您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

reducer.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* @flow */
  2. import _ from 'lodash';
  3. import { equals, ReducerRegistry, set } from '../redux';
  4. import { SET_CONFIG } from './actionTypes';
  5. /**
  6. * The initial state of the feature base/config when executing in a
  7. * non-React Native environment. The mandatory configuration to be passed to
  8. * JitsiMeetJS#init(). The app will download config.js from the Jitsi Meet
  9. * deployment and take its values into account but the values bellow will be
  10. * enforced (because they are essential to the correct execution of the
  11. * application).
  12. *
  13. * @type {Object}
  14. */
  15. const INITIAL_NON_RN_STATE = {
  16. };
  17. /**
  18. * The initial state of the feature base/config when executing in a React Native
  19. * environment. The mandatory configuration to be passed to JitsiMeetJS#init().
  20. * The app will download config.js from the Jitsi Meet deployment and take its
  21. * values into account but the values bellow will be enforced (because they are
  22. * essential to the correct execution of the application).
  23. *
  24. * @type {Object}
  25. */
  26. const INITIAL_RN_STATE = {
  27. // FIXME The support for audio levels in lib-jitsi-meet polls the statistics
  28. // of WebRTC at a short interval multiple times a second. Unfortunately,
  29. // React Native is slow to fetch these statistics from the native WebRTC
  30. // API, through the React Native bridge and eventually to JavaScript.
  31. // Because the audio levels are of no interest to the mobile app, it is
  32. // fastest to merely disable them.
  33. disableAudioLevels: true,
  34. // FIXME Lib-jitsi-meet uses HTML script elements to asynchronously load
  35. // certain pieces of JavaScript. Unfortunately, the technique doesn't work
  36. // on React Native (because there are no HTML elements in the first place).
  37. // Fortunately, these pieces of JavaScript currently involve third parties
  38. // and we can temporarily disable them (until we implement an alternative to
  39. // async script elements on React Native).
  40. disableThirdPartyRequests: true,
  41. p2p: {
  42. preferH264: true
  43. }
  44. };
  45. ReducerRegistry.register(
  46. 'features/base/config',
  47. (state = _getInitialState(), action) => {
  48. switch (action.type) {
  49. case SET_CONFIG:
  50. return _setConfig(state, action);
  51. default:
  52. return state;
  53. }
  54. });
  55. /**
  56. * Gets the initial state of the feature base/config. The mandatory
  57. * configuration to be passed to JitsiMeetJS#init(). The app will download
  58. * config.js from the Jitsi Meet deployment and take its values into account but
  59. * the values bellow will be enforced (because they are essential to the correct
  60. * execution of the application).
  61. *
  62. * @returns {Object}
  63. */
  64. function _getInitialState() {
  65. return (
  66. navigator.product === 'ReactNative'
  67. ? INITIAL_RN_STATE
  68. : INITIAL_NON_RN_STATE);
  69. }
  70. /**
  71. * Reduces a specific Redux action SET_CONFIG of the feature
  72. * base/lib-jitsi-meet.
  73. *
  74. * @param {Object} state - The Redux state of the feature base/lib-jitsi-meet.
  75. * @param {Action} action - The Redux action SET_CONFIG to reduce.
  76. * @private
  77. * @returns {Object} The new state of the feature base/lib-jitsi-meet after the
  78. * reduction of the specified action.
  79. */
  80. function _setConfig(state, action) {
  81. let { config } = action;
  82. // The mobile app bundles jitsi-meet and lib-jitsi-meet at build time and
  83. // does not download them at runtime from the deployment on which it will
  84. // join a conference. The downloading is planned for implementation in the
  85. // future (later rather than sooner) but is not implemented yet at the time
  86. // of this writing and, consequently, we must provide legacy support in the
  87. // meantime.
  88. config = _translateLegacyConfig(config);
  89. const newState = _.merge(
  90. {},
  91. config,
  92. // The config of _getInitialState() is meant to override the config
  93. // downloaded from the Jitsi Meet deployment because the former contains
  94. // values that are mandatory.
  95. _getInitialState()
  96. );
  97. return equals(state, newState) ? state : newState;
  98. }
  99. /**
  100. * Constructs a new config {@code Object}, if necessary, out of a specific
  101. * config {@code Object} which is in the latest format supported by jitsi-meet.
  102. * Such a translation from an old config format to a new/the latest config
  103. * format is necessary because the mobile app bundles jitsi-meet and
  104. * lib-jitsi-meet at build time and does not download them at runtime from the
  105. * deployment on which it will join a conference.
  106. *
  107. * @param {Object} oldValue - The config {@code Object} which may or may not be
  108. * in the latest form supported by jitsi-meet and from which a new config
  109. * {@code Object} is to be constructed if necessary.
  110. * @returns {Object} A config {@code Object} which is in the latest format
  111. * supported by jitsi-meet.
  112. */
  113. function _translateLegacyConfig(oldValue: Object) {
  114. // jitsi/jitsi-meet#3ea2f005787c9f49c48febaeed9dc0340fe0a01b
  115. let newValue = oldValue;
  116. // At the time of this writing lib-jitsi-meet will rely on config having a
  117. // property with the name p2p and with a value of type Object.
  118. if (typeof oldValue.p2p !== 'object') {
  119. newValue = set(newValue, 'p2p', {});
  120. }
  121. // Translate the old config properties into the new config.p2p properties.
  122. for (const [ oldKey, newKey ]
  123. of [
  124. [ 'backToP2PDelay', 'backToP2PDelay' ],
  125. [ 'enableP2P', 'enabled' ],
  126. [ 'p2pStunServers', 'stunServers' ]
  127. ]) {
  128. if (oldKey in newValue) {
  129. const v = newValue[oldKey];
  130. // Do not modify oldValue.
  131. if (newValue === oldValue) {
  132. newValue = {
  133. ...newValue
  134. };
  135. }
  136. delete newValue[oldKey];
  137. // Do not modify p2p because it may be from oldValue i.e. do not
  138. // modify oldValue.
  139. newValue.p2p = {
  140. ...newValue.p2p,
  141. [newKey]: v
  142. };
  143. }
  144. }
  145. return newValue;
  146. }