瀏覽代碼

Merge pull request #6529 from jitsi/local-storage

fix(localStorage): exception when disabled.
j8
Emil Ivov 5 年之前
父節點
當前提交
0fd0897531
No account linked to committer's email address

+ 2
- 1
connection.js 查看文件

@@ -1,7 +1,8 @@
1 1
 /* global APP, JitsiMeetJS, config */
2 2
 
3
+import { jitsiLocalStorage } from 'js-utils';
4
+
3 5
 import AuthHandler from './modules/UI/authentication/AuthHandler';
4
-import jitsiLocalStorage from './modules/util/JitsiLocalStorage';
5 6
 
6 7
 import {
7 8
     connectionEstablished,

+ 1
- 1
modules/UI/util/MessageHandler.js 查看文件

@@ -1,7 +1,7 @@
1 1
 /* global $, APP */
2 2
 const logger = require('jitsi-meet-logger').getLogger(__filename);
3 3
 
4
-import jitsiLocalStorage from '../../util/JitsiLocalStorage';
4
+import { jitsiLocalStorage } from 'js-utils';
5 5
 
6 6
 import {
7 7
     NOTIFICATION_TIMEOUT,

+ 0
- 77
modules/util/JitsiLocalStorage.js 查看文件

@@ -1,77 +0,0 @@
1
-import Logger from 'jitsi-meet-logger';
2
-
3
-const logger = Logger.getLogger(__filename);
4
-
5
-/**
6
- * Dummy implementation of Storage interface with empty methods.
7
- */
8
-class DummyLocalStorage {
9
-    /* eslint-disable no-empty-function */
10
-    /**
11
-     * Empty function
12
-     */
13
-    getItem() { }
14
-
15
-    /**
16
-     * Empty function
17
-     */
18
-    setItem() { }
19
-
20
-    /**
21
-     * Empty function
22
-     */
23
-    removeItem() { }
24
-    /* eslint-enable no-empty-function */
25
-}
26
-
27
-/**
28
- * Wrapper class for browser's local storage object.
29
- */
30
-class JitsiLocalStorage extends DummyLocalStorage {
31
-    /**
32
-     * @constructor
33
-     * @param {Storage} storage browser's local storage object.
34
-     */
35
-    constructor() {
36
-        super();
37
-        let storage;
38
-
39
-        try {
40
-            storage = window.localStorage;
41
-        } catch (error) {
42
-            logger.error(error);
43
-        }
44
-        this.storage = storage || new DummyLocalStorage();
45
-    }
46
-
47
-    /**
48
-     * Returns that passed key's value.
49
-     * @param {string} keyName the name of the key you want to retrieve
50
-     * the value of.
51
-     * @returns {String|null} the value of the key. If the key does not exist,
52
-     * null is returned.
53
-     */
54
-    getItem(keyName) {
55
-        return this.storage.getItem(keyName);
56
-    }
57
-
58
-    /**
59
-     * Adds a key to the storage, or update key's value if it already exists.
60
-     * @param {string} keyName the name of the key you want to create/update.
61
-     * @param {string} keyValue the value you want to give the key you are
62
-     * creating/updating.
63
-     */
64
-    setItem(keyName, keyValue) {
65
-        return this.storage.setItem(keyName, keyValue);
66
-    }
67
-
68
-    /**
69
-     * Remove a key from the storage.
70
-     * @param {string} keyName the name of the key you want to remove.
71
-     */
72
-    removeItem(keyName) {
73
-        return this.storage.removeItem(keyName);
74
-    }
75
-}
76
-
77
-export default new JitsiLocalStorage();

+ 5
- 5
package-lock.json 查看文件

@@ -10594,8 +10594,8 @@
10594 10594
       "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
10595 10595
     },
10596 10596
     "js-utils": {
10597
-      "version": "github:jitsi/js-utils#df68966e3c65b5c57fcd2670da1326a2c77518d1",
10598
-      "from": "github:jitsi/js-utils#df68966e3c65b5c57fcd2670da1326a2c77518d1",
10597
+      "version": "github:jitsi/js-utils#0c0c4142bd559fffffaebaded80bdaba8414d6b8",
10598
+      "from": "github:jitsi/js-utils#0c0c4142bd559fffffaebaded80bdaba8414d6b8",
10599 10599
       "requires": {
10600 10600
         "bowser": "2.7.0",
10601 10601
         "js-md5": "0.7.3",
@@ -10794,15 +10794,15 @@
10794 10794
       }
10795 10795
     },
10796 10796
     "lib-jitsi-meet": {
10797
-      "version": "github:jitsi/lib-jitsi-meet#dffe94f270f692c7421412bbbc597279e4a2d805",
10798
-      "from": "github:jitsi/lib-jitsi-meet#dffe94f270f692c7421412bbbc597279e4a2d805",
10797
+      "version": "github:jitsi/lib-jitsi-meet#c6e8d596b0817a6584915457b2cb9ef726e94181",
10798
+      "from": "github:jitsi/lib-jitsi-meet#c6e8d596b0817a6584915457b2cb9ef726e94181",
10799 10799
       "requires": {
10800 10800
         "@jitsi/sdp-interop": "1.0.2",
10801 10801
         "@jitsi/sdp-simulcast": "0.3.0",
10802 10802
         "async": "0.9.0",
10803 10803
         "current-executing-script": "0.1.3",
10804 10804
         "jitsi-meet-logger": "github:jitsi/jitsi-meet-logger#5ec92357570dc8f0b7ffc1528820721c84c6af8b",
10805
-        "js-utils": "github:jitsi/js-utils#df68966e3c65b5c57fcd2670da1326a2c77518d1",
10805
+        "js-utils": "github:jitsi/js-utils#0c0c4142bd559fffffaebaded80bdaba8414d6b8",
10806 10806
         "lodash.isequal": "4.5.0",
10807 10807
         "sdp-transform": "2.3.0",
10808 10808
         "strophe.js": "1.3.4",

+ 2
- 2
package.json 查看文件

@@ -53,10 +53,10 @@
53 53
     "jquery-contextmenu": "2.4.5",
54 54
     "jquery-i18next": "1.2.1",
55 55
     "js-md5": "0.6.1",
56
-    "js-utils": "github:jitsi/js-utils#df68966e3c65b5c57fcd2670da1326a2c77518d1",
56
+    "js-utils": "github:jitsi/js-utils#0c0c4142bd559fffffaebaded80bdaba8414d6b8",
57 57
     "jsrsasign": "8.0.12",
58 58
     "jwt-decode": "2.2.0",
59
-    "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#dffe94f270f692c7421412bbbc597279e4a2d805",
59
+    "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#c6e8d596b0817a6584915457b2cb9ef726e94181",
60 60
     "libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
61 61
     "lodash": "4.17.13",
62 62
     "moment": "2.19.4",

+ 2
- 2
react/features/base/app/components/BaseApp.js 查看文件

@@ -1,5 +1,6 @@
1 1
 // @flow
2 2
 
3
+import { jitsiLocalStorage } from 'js-utils';
3 4
 import _ from 'lodash';
4 5
 import React, { Component, Fragment } from 'react';
5 6
 import { I18nextProvider } from 'react-i18next';
@@ -15,7 +16,6 @@ import {
15 16
 } from '../../redux';
16 17
 import { SoundCollection } from '../../sounds';
17 18
 import { PersistenceRegistry } from '../../storage';
18
-
19 19
 import { appWillMount, appWillUnmount } from '../actions';
20 20
 import logger from '../logger';
21 21
 
@@ -110,7 +110,7 @@ export default class BaseApp extends Component<*, State> {
110 110
      * @returns {Promise}
111 111
      */
112 112
     _initStorage(): Promise<*> {
113
-        const { _initializing } = window.localStorage;
113
+        const _initializing = jitsiLocalStorage.getItem('_initializing');
114 114
 
115 115
         return _initializing || Promise.resolve();
116 116
     }

+ 3
- 5
react/features/base/config/actions.js 查看文件

@@ -1,5 +1,6 @@
1 1
 // @flow
2 2
 
3
+import { jitsiLocalStorage } from 'js-utils';
3 4
 import type { Dispatch } from 'redux';
4 5
 
5 6
 import { addKnownDomains } from '../known-domains';
@@ -109,11 +110,8 @@ export function storeConfig(baseURL: string, config: Object) {
109 110
         let b = false;
110 111
 
111 112
         try {
112
-            if (typeof window.config === 'undefined'
113
-                    || window.config !== config) {
114
-                window.localStorage.setItem(
115
-                    `${_CONFIG_STORE_PREFIX}/${baseURL}`,
116
-                    JSON.stringify(config));
113
+            if (typeof window.config === 'undefined' || window.config !== config) {
114
+                jitsiLocalStorage.setItem(`${_CONFIG_STORE_PREFIX}/${baseURL}`, JSON.stringify(config));
117 115
                 b = true;
118 116
             }
119 117
         } catch (e) {

+ 7
- 12
react/features/base/config/functions.any.js 查看文件

@@ -1,5 +1,6 @@
1 1
 // @flow
2 2
 
3
+import { jitsiLocalStorage } from 'js-utils';
3 4
 import _ from 'lodash';
4 5
 
5 6
 import CONFIG_WHITELIST from './configWhitelist';
@@ -136,22 +137,16 @@ function _getWhitelistedJSON(configName, configJSON) {
136 137
  * otherwise, {@code undefined}.
137 138
  */
138 139
 export function restoreConfig(baseURL: string): ?Object {
139
-    let storage;
140 140
     const key = `${_CONFIG_STORE_PREFIX}/${baseURL}`;
141
+    const config = jitsiLocalStorage.getItem(key);
141 142
 
142
-    try {
143
-        // XXX Even reading the property localStorage of window may throw an
144
-        // error (which is user agent-specific behavior).
145
-        storage = window.localStorage;
146
-
147
-        const config = storage.getItem(key);
148
-
149
-        if (config) {
143
+    if (config) {
144
+        try {
150 145
             return JSON.parse(config) || undefined;
146
+        } catch (e) {
147
+            // Somehow incorrect data ended up in the storage. Clean it up.
148
+            jitsiLocalStorage.removeItem(key);
151 149
         }
152
-    } catch (e) {
153
-        // Somehow incorrect data ended up in the storage. Clean it up.
154
-        storage && storage.removeItem(key);
155 150
     }
156 151
 
157 152
     return undefined;

+ 16
- 17
react/features/base/config/middleware.js 查看文件

@@ -1,5 +1,7 @@
1 1
 // @flow
2 2
 
3
+import { jitsiLocalStorage } from 'js-utils';
4
+
3 5
 import { APP_WILL_MOUNT } from '../app';
4 6
 import { addKnownDomains } from '../known-domains';
5 7
 import { MiddlewareRegistry } from '../redux';
@@ -51,31 +53,28 @@ function _appWillMount(store, next, action) {
51 53
     // consequently, the feature known-domains, it's possible for the feature
52 54
     // base/config to know of domains which the feature known-domains is yet to
53 55
     // discover.
54
-    const { localStorage } = window;
55 56
 
56
-    if (localStorage) {
57
-        const prefix = `${_CONFIG_STORE_PREFIX}/`;
58
-        const knownDomains = [];
57
+    const prefix = `${_CONFIG_STORE_PREFIX}/`;
58
+    const knownDomains = [];
59 59
 
60
-        for (let i = 0; /* localStorage.key(i) */; ++i) {
61
-            const key = localStorage.key(i);
60
+    for (let i = 0; /* localStorage.key(i) */; ++i) {
61
+        const key = jitsiLocalStorage.key(i);
62 62
 
63
-            if (key) {
64
-                let baseURL;
63
+        if (key) {
64
+            let baseURL;
65 65
 
66
-                if (key.startsWith(prefix)
67
-                        && (baseURL = key.substring(prefix.length))) {
68
-                    const uri = parseURIString(baseURL);
69
-                    let host;
66
+            if (key.startsWith(prefix)
67
+                    && (baseURL = key.substring(prefix.length))) {
68
+                const uri = parseURIString(baseURL);
69
+                let host;
70 70
 
71
-                    uri && (host = uri.host) && knownDomains.push(host);
72
-                }
73
-            } else {
74
-                break;
71
+                uri && (host = uri.host) && knownDomains.push(host);
75 72
             }
73
+        } else {
74
+            break;
76 75
         }
77
-        knownDomains.length && store.dispatch(addKnownDomains(knownDomains));
78 76
     }
77
+    knownDomains.length && store.dispatch(addKnownDomains(knownDomains));
79 78
 
80 79
     return result;
81 80
 }

+ 9
- 12
react/features/base/settings/reducer.js 查看文件

@@ -1,5 +1,6 @@
1 1
 // @flow
2 2
 
3
+import { jitsiLocalStorage } from 'js-utils';
3 4
 import { randomHexString } from 'js-utils/random';
4 5
 import _ from 'lodash';
5 6
 
@@ -86,8 +87,7 @@ ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
86 87
  * @returns {Object}
87 88
  */
88 89
 function _getLegacyProfile() {
89
-    let persistedProfile
90
-        = window.localStorage.getItem('features/base/profile');
90
+    let persistedProfile = jitsiLocalStorage.getItem('features/base/profile');
91 91
 
92 92
     if (persistedProfile) {
93 93
         try {
@@ -123,9 +123,9 @@ function _initSettings(featureState) {
123 123
     // FIXME: jibri uses old settings.js local storage values to set its display
124 124
     // name and email. Provide another way for jibri to set these values, update
125 125
     // jibri, and remove the old settings.js values.
126
-    const savedDisplayName = window.localStorage.getItem('displayname');
127
-    const savedEmail = window.localStorage.getItem('email');
128
-    let avatarID = _.escape(window.localStorage.getItem('avatarId'));
126
+    const savedDisplayName = jitsiLocalStorage.getItem('displayname');
127
+    const savedEmail = jitsiLocalStorage.getItem('email');
128
+    let avatarID = _.escape(jitsiLocalStorage.getItem('avatarId'));
129 129
 
130 130
     // The helper _.escape will convert null to an empty strings. The empty
131 131
     // string will be saved in settings. On app re-load, because an empty string
@@ -149,16 +149,13 @@ function _initSettings(featureState) {
149 149
 
150 150
     if (!browser.isReactNative()) {
151 151
         // Browser only
152
-        const localFlipX
153
-            = JSON.parse(window.localStorage.getItem('localFlipX') || 'true');
154
-        const cameraDeviceId
155
-            = window.localStorage.getItem('cameraDeviceId') || '';
156
-        const micDeviceId = window.localStorage.getItem('micDeviceId') || '';
152
+        const localFlipX = JSON.parse(jitsiLocalStorage.getItem('localFlipX') || 'true');
153
+        const cameraDeviceId = jitsiLocalStorage.getItem('cameraDeviceId') || '';
154
+        const micDeviceId = jitsiLocalStorage.getItem('micDeviceId') || '';
157 155
 
158 156
         // Currently audio output device change is supported only in Chrome and
159 157
         // default output always has 'default' device ID
160
-        const audioOutputDeviceId
161
-            = window.localStorage.getItem('audioOutputDeviceId') || 'default';
158
+        const audioOutputDeviceId = jitsiLocalStorage.getItem('audioOutputDeviceId') || 'default';
162 159
 
163 160
         settings = assignIfDefined({
164 161
             audioOutputDeviceId,

+ 7
- 13
react/features/base/storage/PersistenceRegistry.js 查看文件

@@ -1,6 +1,7 @@
1 1
 // @flow
2 2
 
3 3
 import md5 from 'js-md5';
4
+import { jitsiLocalStorage } from 'js-utils';
4 5
 
5 6
 import logger from './logger';
6 7
 
@@ -63,8 +64,7 @@ class PersistenceRegistry {
63 64
 
64 65
         // legacy
65 66
         if (Object.keys(filteredPersistedState).length === 0) {
66
-            const { localStorage } = window;
67
-            let persistedState = localStorage.getItem(PERSISTED_STATE_NAME);
67
+            let persistedState = jitsiLocalStorage.getItem(PERSISTED_STATE_NAME);
68 68
 
69 69
             if (persistedState) {
70 70
                 try {
@@ -82,7 +82,7 @@ class PersistenceRegistry {
82 82
                 // Store into the new format and delete the old format so that
83 83
                 // it's not used again.
84 84
                 this.persistState(filteredPersistedState);
85
-                localStorage.removeItem(PERSISTED_STATE_NAME);
85
+                jitsiLocalStorage.removeItem(PERSISTED_STATE_NAME);
86 86
             }
87 87
         }
88 88
 
@@ -110,18 +110,12 @@ class PersistenceRegistry {
110 110
         if (checksum !== this._checksum) {
111 111
             for (const subtreeName of Object.keys(filteredState)) {
112 112
                 try {
113
-                    window.localStorage.setItem(
114
-                        subtreeName,
115
-                        JSON.stringify(filteredState[subtreeName]));
113
+                    jitsiLocalStorage.setItem(subtreeName, JSON.stringify(filteredState[subtreeName]));
116 114
                 } catch (error) {
117
-                    logger.error(
118
-                        'Error persisting redux subtree',
119
-                        subtreeName,
120
-                        error);
115
+                    logger.error('Error persisting redux subtree', subtreeName, error);
121 116
                 }
122 117
             }
123
-            logger.info(
124
-                `redux state persisted. ${this._checksum} -> ${checksum}`);
118
+            logger.info(`redux state persisted. ${this._checksum} -> ${checksum}`);
125 119
             this._checksum = checksum;
126 120
         }
127 121
     }
@@ -225,7 +219,7 @@ class PersistenceRegistry {
225 219
      * @returns {Object}
226 220
      */
227 221
     _getPersistedSubtree(subtreeName, subtreeConfig, subtreeDefaults) {
228
-        let persistedSubtree = window.localStorage.getItem(subtreeName);
222
+        let persistedSubtree = jitsiLocalStorage.getItem(subtreeName);
229 223
 
230 224
         if (persistedSubtree) {
231 225
             try {

+ 13
- 8
react/features/chrome-extension-banner/components/ChromeExtensionBanner.web.js 查看文件

@@ -1,19 +1,24 @@
1 1
 // @flow
2
+
3
+import { jitsiLocalStorage } from 'js-utils';
2 4
 import React, { PureComponent } from 'react';
3
-import { connect } from '../../base/redux';
5
+
6
+import {
7
+    createChromeExtensionBannerEvent,
8
+    sendAnalytics
9
+} from '../../analytics';
10
+import { getCurrentConference } from '../../base/conference/functions';
4 11
 import { Icon, IconClose } from '../../base/icons';
5 12
 import { translate } from '../../base/i18n';
6
-import { getCurrentConference } from '../../base/conference/functions';
7 13
 import { browser } from '../../base/lib-jitsi-meet';
14
+import { connect } from '../../base/redux';
8 15
 import {
9 16
     checkChromeExtensionsInstalled,
10 17
     isMobileBrowser
11 18
 } from '../../base/environment/utils';
19
+
12 20
 import logger from '../logger';
13
-import {
14
-    createChromeExtensionBannerEvent,
15
-    sendAnalytics
16
-} from '../../analytics';
21
+
17 22
 
18 23
 declare var interfaceConfig: Object;
19 24
 
@@ -182,7 +187,7 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
182 187
             return true;
183 188
         }
184 189
 
185
-        const dontShowAgain = localStorage.getItem(DONT_SHOW_AGAIN_CHECKED) === 'true';
190
+        const dontShowAgain = jitsiLocalStorage.getItem(DONT_SHOW_AGAIN_CHECKED) === 'true';
186 191
 
187 192
         return !this.props.bannerCfg.url
188 193
             || dontShowAgain
@@ -212,7 +217,7 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
212 217
     render() {
213 218
         if (this._shouldNotRender()) {
214 219
             if (this.state.dontShowAgainChecked) {
215
-                localStorage.setItem(DONT_SHOW_AGAIN_CHECKED, 'true');
220
+                jitsiLocalStorage.setItem(DONT_SHOW_AGAIN_CHECKED, 'true');
216 221
             }
217 222
 
218 223
             return null;

+ 1
- 1
react/features/local-recording/session/SessionManager.js 查看文件

@@ -1,6 +1,6 @@
1 1
 /* @flow */
2 2
 
3
-import jitsiLocalStorage from '../../../../modules/util/JitsiLocalStorage';
3
+import { jitsiLocalStorage } from 'js-utils';
4 4
 
5 5
 import logger from '../logger';
6 6
 

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

@@ -1,4 +1,7 @@
1 1
 // @flow
2
+
3
+import { jitsiLocalStorage } from 'js-utils';
4
+
2 5
 import { APP_WILL_MOUNT } from '../base/app';
3 6
 import { getURLWithoutParamsNormalized } from '../base/connection';
4 7
 import { ReducerRegistry } from '../base/redux';
@@ -119,16 +122,17 @@ function _appWillMount(state) {
119 122
  * @returns {Array<Object>}
120 123
  */
121 124
 function _getLegacyRecentRoomList(): Array<Object> {
122
-    try {
123
-        const str = window.localStorage.getItem(LEGACY_STORAGE_KEY);
125
+    const str = jitsiLocalStorage.getItem(LEGACY_STORAGE_KEY);
124 126
 
125
-        if (str) {
127
+    if (str) {
128
+        try {
126 129
             return JSON.parse(str);
130
+        } catch (error) {
131
+            logger.warn('Failed to parse legacy recent-room list!');
127 132
         }
128
-    } catch (error) {
129
-        logger.warn('Failed to parse legacy recent-room list!');
130 133
     }
131 134
 
135
+
132 136
     return [];
133 137
 }
134 138
 

Loading…
取消
儲存