瀏覽代碼

Introduce base/storage to represent the Web Storage API and persistence-related customizations

master
Lyubo Marinov 7 年之前
父節點
當前提交
d7dddb2509

+ 3
- 6
react/features/app/components/AbstractApp.js 查看文件

14
 } from '../../base/participants';
14
 } from '../../base/participants';
15
 import { getProfile } from '../../base/profile';
15
 import { getProfile } from '../../base/profile';
16
 import { Fragment, RouteRegistry } from '../../base/react';
16
 import { Fragment, RouteRegistry } from '../../base/react';
17
-import {
18
-    MiddlewareRegistry,
19
-    PersistencyRegistry,
20
-    ReducerRegistry
21
-} from '../../base/redux';
17
+import { MiddlewareRegistry, ReducerRegistry } from '../../base/redux';
18
+import { PersistenceRegistry } from '../../base/storage';
22
 import { toURLString } from '../../base/util';
19
 import { toURLString } from '../../base/util';
23
 import { OverlayContainer } from '../../overlay';
20
 import { OverlayContainer } from '../../overlay';
24
 import { BlankPage } from '../../welcome';
21
 import { BlankPage } from '../../welcome';
349
         return (
346
         return (
350
             createStore(
347
             createStore(
351
                 reducer,
348
                 reducer,
352
-                PersistencyRegistry.getPersistedState(),
349
+                PersistenceRegistry.getPersistedState(),
353
                 middleware));
350
                 middleware));
354
     }
351
     }
355
 
352
 

+ 7
- 15
react/features/base/lib-jitsi-meet/native/polyfills-browser.js 查看文件

4
 
4
 
5
 import { Platform } from '../../react';
5
 import { Platform } from '../../react';
6
 
6
 
7
-import Storage from './Storage';
7
+// XXX The library lib-jitsi-meet utilizes window.localStorage at the time of
8
+// this writing and, consequently, the browser-related polyfills implemented
9
+// here by the feature base/lib-jitsi-meet for the purposes of the library
10
+// lib-jitsi-meet are incomplete without the Web Storage API! Should the library
11
+// lib-jitsi-meet (and its dependencies) stop utilizing window.localStorage,
12
+// the following import may be removed:
13
+import '../../storage';
8
 
14
 
9
 /**
15
 /**
10
  * Gets the first common prototype of two specified Objects (treating the
16
  * Gets the first common prototype of two specified Objects (treating the
271
         global.document = document;
277
         global.document = document;
272
     }
278
     }
273
 
279
 
274
-    // localStorage
275
-    if (typeof global.localStorage === 'undefined') {
276
-        global.localStorage = new Storage('@jitsi-meet/');
277
-    }
278
-
279
     // location
280
     // location
280
     if (typeof global.location === 'undefined') {
281
     if (typeof global.location === 'undefined') {
281
         global.location = {
282
         global.location = {
332
         navigator.userAgent = userAgent;
333
         navigator.userAgent = userAgent;
333
     }
334
     }
334
 
335
 
335
-    // sessionStorage
336
-    //
337
-    // Required by:
338
-    // - herment
339
-    // - Strophe
340
-    if (typeof global.sessionStorage === 'undefined') {
341
-        global.sessionStorage = new Storage();
342
-    }
343
-
344
     // WebRTC
336
     // WebRTC
345
     require('./polyfills-webrtc');
337
     require('./polyfills-webrtc');
346
     require('react-native-callstats/csio-polyfill');
338
     require('react-native-callstats/csio-polyfill');

+ 6
- 2
react/features/base/profile/reducer.js 查看文件

1
 // @flow
1
 // @flow
2
 
2
 
3
-import { PersistencyRegistry, ReducerRegistry } from '../redux';
3
+import { ReducerRegistry } from '../redux';
4
+import { PersistenceRegistry } from '../storage';
4
 
5
 
5
 import { PROFILE_UPDATED } from './actionTypes';
6
 import { PROFILE_UPDATED } from './actionTypes';
6
 
7
 
10
 
11
 
11
 const STORE_NAME = 'features/base/profile';
12
 const STORE_NAME = 'features/base/profile';
12
 
13
 
13
-PersistencyRegistry.register(STORE_NAME, {
14
+/**
15
+ * Sets up the persistence of the feature base/profile.
16
+ */
17
+PersistenceRegistry.register(STORE_NAME, {
14
     profile: true
18
     profile: true
15
 });
19
 });
16
 
20
 

+ 0
- 3
react/features/base/redux/index.js 查看文件

1
 export * from './functions';
1
 export * from './functions';
2
 export { default as MiddlewareRegistry } from './MiddlewareRegistry';
2
 export { default as MiddlewareRegistry } from './MiddlewareRegistry';
3
-export { default as PersistencyRegistry } from './PersistencyRegistry';
4
 export { default as ReducerRegistry } from './ReducerRegistry';
3
 export { default as ReducerRegistry } from './ReducerRegistry';
5
-
6
-import './middleware';

+ 0
- 30
react/features/base/redux/readme.md 查看文件

1
-Jitsi Meet - redux state persistency
2
-====================================
3
-Jitsi Meet has a persistency layer that persists a subtree (or specific subtrees) into window.localStorage (on web) or
4
-AsyncStorage (on mobile).
5
-
6
-Usage
7
-=====
8
-If a subtree of the redux store should be persisted (e.g. ``'features/base/profile'``), then persistency for that
9
-subtree should be requested by registering the subtree (and related config) into PersistencyRegistry.
10
-
11
-E.g. to register the field ``profile`` of the Redux subtree ``'features/base/profile'`` to be persisted, use:
12
-
13
-```JavaScript
14
-PersistencyRegistry.register('features/base/profile', {
15
-    profile: true
16
-});
17
-```
18
-
19
-in the ``reducer.js`` of the ``profile`` feature.
20
-
21
-When it's done, Jitsi Meet will automatically persist these subtrees/fields and rehidrate them on startup.
22
-
23
-Throttling
24
-==========
25
-To avoid too frequent write operations in the storage, we utilise throttling in the persistency layer, meaning that the storage
26
-gets persisted only once in every 2 seconds, even if multiple redux state changes occur during this period. This throttling timeout
27
-can be configured in
28
-```
29
-react/features/base/redux/middleware.js#PERSIST_DELAY
30
-```

react/features/base/redux/PersistencyRegistry.js → react/features/base/storage/PersistenceRegistry.js 查看文件

19
  * A registry to allow features to register their redux store subtree to be
19
  * A registry to allow features to register their redux store subtree to be
20
  * persisted and also handles the persistency calls too.
20
  * persisted and also handles the persistency calls too.
21
  */
21
  */
22
-class PersistencyRegistry {
22
+class PersistenceRegistry {
23
     _checksum: string;
23
     _checksum: string;
24
 
24
 
25
     _elements: PersistencyConfigMap;
25
     _elements: PersistencyConfigMap;
26
 
26
 
27
     /**
27
     /**
28
-     * Initializes a new {@ code PersistencyRegistry} instance.
28
+     * Initializes a new {@ code PersistenceRegistry} instance.
29
      */
29
      */
30
     constructor() {
30
     constructor() {
31
         this._elements = {};
31
         this._elements = {};
166
     }
166
     }
167
 }
167
 }
168
 
168
 
169
-export default new PersistencyRegistry();
169
+export default new PersistenceRegistry();

+ 33
- 0
react/features/base/storage/README.md 查看文件

1
+Jitsi Meet - redux state persistence
2
+====================================
3
+Jitsi Meet has a persistence layer that persists specific subtrees of the redux
4
+store/state into window.localStorage (on Web) or AsyncStorage (on mobile).
5
+
6
+Usage
7
+=====
8
+If a subtree of the redux store should be persisted (e.g.
9
+`'features/base/profile'`), then persistence for that subtree should be
10
+requested by registering the subtree with `PersistenceRegistry`.
11
+
12
+For example, to register the field `profile` of the redux subtree
13
+`'features/base/profile'` to be persisted, use:
14
+```javascript
15
+PersistenceRegistry.register('features/base/profile', {
16
+    profile: true
17
+});
18
+```
19
+
20
+in the `reducer.js` of the `base/profile` feature.
21
+
22
+When it's done, Jitsi Meet will automatically persist these subtrees and
23
+rehydrate them on startup.
24
+
25
+Throttling
26
+==========
27
+To avoid too frequent write operations in the storage, we utilize throttling in
28
+the persistence layer, meaning that the storage gets persisted only once every 2
29
+seconds, even if multiple redux state changes occur during this period. The
30
+throttling timeout can be configured in
31
+```
32
+react/features/base/storage/middleware.js#PERSIST_STATE_DELAY
33
+```

+ 1
- 0
react/features/base/storage/_.native.js 查看文件

1
+export * from './native';

+ 0
- 0
react/features/base/storage/_.web.js 查看文件


+ 4
- 0
react/features/base/storage/index.js 查看文件

1
+export * from './_';
2
+export { default as PersistenceRegistry } from './PersistenceRegistry';
3
+
4
+import './middleware';

react/features/base/redux/middleware.js → react/features/base/storage/middleware.js 查看文件

2
 
2
 
3
 import _ from 'lodash';
3
 import _ from 'lodash';
4
 
4
 
5
-import { toState } from './functions';
6
-import MiddlewareRegistry from './MiddlewareRegistry';
7
-import PersistencyRegistry from './PersistencyRegistry';
5
+import { MiddlewareRegistry, toState } from '../redux';
6
+
7
+import PersistenceRegistry from './PersistenceRegistry';
8
 
8
 
9
 /**
9
 /**
10
- * The delay that passes between the last state change and the persisting of
11
- * that state in the storage.
10
+ * The delay in milliseconds that passes between the last state change and the
11
+ * persisting of that state in the storage.
12
  */
12
  */
13
 const PERSIST_STATE_DELAY = 2000;
13
 const PERSIST_STATE_DELAY = 2000;
14
 
14
 
17
  */
17
  */
18
 const throttledPersistState
18
 const throttledPersistState
19
     = _.throttle(
19
     = _.throttle(
20
-        state => PersistencyRegistry.persistState(state),
20
+        state => PersistenceRegistry.persistState(state),
21
         PERSIST_STATE_DELAY);
21
         PERSIST_STATE_DELAY);
22
 
22
 
23
 /**
23
 /**
24
  * A master MiddleWare to selectively persist state. Please use the
24
  * A master MiddleWare to selectively persist state. Please use the
25
- * {@link persisterconfig.json} to set which subtrees of the Redux state should
25
+ * {@link persisterconfig.json} to set which subtrees of the redux state should
26
  * be persisted.
26
  * be persisted.
27
  *
27
  *
28
  * @param {Store} store - The redux store.
28
  * @param {Store} store - The redux store.
29
  * @returns {Function}
29
  * @returns {Function}
30
  */
30
  */
31
 MiddlewareRegistry.register(store => next => action => {
31
 MiddlewareRegistry.register(store => next => action => {
32
+    const oldState = toState(store);
32
     const result = next(action);
33
     const result = next(action);
34
+    const newState = toState(store);
33
 
35
 
34
-    throttledPersistState(toState(store));
36
+    oldState === newState || throttledPersistState(newState);
35
 
37
 
36
     return result;
38
     return result;
37
 });
39
 });

react/features/base/lib-jitsi-meet/native/Storage.js → react/features/base/storage/native/Storage.js 查看文件


+ 1
- 0
react/features/base/storage/native/index.js 查看文件

1
+import './polyfills-browser';

+ 19
- 0
react/features/base/storage/native/polyfills-browser.js 查看文件

1
+import Storage from './Storage';
2
+
3
+(global => {
4
+
5
+    // localStorage
6
+    if (typeof global.localStorage === 'undefined') {
7
+        global.localStorage = new Storage('@jitsi-meet/');
8
+    }
9
+
10
+    // sessionStorage
11
+    //
12
+    // Required by:
13
+    // - herment
14
+    // - Strophe
15
+    if (typeof global.sessionStorage === 'undefined') {
16
+        global.sessionStorage = new Storage();
17
+    }
18
+
19
+})(global || window || this); // eslint-disable-line no-invalid-this

+ 1
- 1
react/features/recent-list/components/AbstractRecentList.js 查看文件

46
 }
46
 }
47
 
47
 
48
 /**
48
 /**
49
- * Maps Redux state to component props.
49
+ * Maps redux state to component props.
50
  *
50
  *
51
  * @param {Object} state - The redux state.
51
  * @param {Object} state - The redux state.
52
  * @returns {{
52
  * @returns {{

+ 5
- 4
react/features/recent-list/reducer.js 查看文件

1
 // @flow
1
 // @flow
2
 
2
 
3
-import { PersistencyRegistry, ReducerRegistry } from '../base/redux';
3
+import { ReducerRegistry } from '../base/redux';
4
+import { PersistenceRegistry } from '../base/storage';
4
 
5
 
5
 import {
6
 import {
6
     STORE_CURRENT_CONFERENCE,
7
     STORE_CURRENT_CONFERENCE,
30
 const STORE_NAME = 'features/recent-list';
31
 const STORE_NAME = 'features/recent-list';
31
 
32
 
32
 /**
33
 /**
33
- * Registers the redux store subtree of this feature for persistency.
34
+ * Sets up the persistence of the feature recent-list.
34
  */
35
  */
35
-PersistencyRegistry.register(STORE_NAME, {
36
+PersistenceRegistry.register(STORE_NAME, {
36
     list: true
37
     list: true
37
 });
38
 });
38
 
39
 
39
 /**
40
 /**
40
- * Reduces the redux actions of the feature features/recent-list.
41
+ * Reduces the redux actions of the feature recent-list.
41
  */
42
  */
42
 ReducerRegistry.register(
43
 ReducerRegistry.register(
43
     STORE_NAME,
44
     STORE_NAME,

Loading…
取消
儲存