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