Merge pull request #6529 from jitsi/local-storage
fix(localStorage): exception when disabled.
This commit is contained in:
commit
0fd0897531
|
@ -1,7 +1,8 @@
|
|||
/* global APP, JitsiMeetJS, config */
|
||||
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
|
||||
import AuthHandler from './modules/UI/authentication/AuthHandler';
|
||||
import jitsiLocalStorage from './modules/util/JitsiLocalStorage';
|
||||
|
||||
import {
|
||||
connectionEstablished,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* global $, APP */
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||
|
||||
import jitsiLocalStorage from '../../util/JitsiLocalStorage';
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
|
||||
import {
|
||||
NOTIFICATION_TIMEOUT,
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
import Logger from 'jitsi-meet-logger';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
|
||||
/**
|
||||
* Dummy implementation of Storage interface with empty methods.
|
||||
*/
|
||||
class DummyLocalStorage {
|
||||
/* eslint-disable no-empty-function */
|
||||
/**
|
||||
* Empty function
|
||||
*/
|
||||
getItem() { }
|
||||
|
||||
/**
|
||||
* Empty function
|
||||
*/
|
||||
setItem() { }
|
||||
|
||||
/**
|
||||
* Empty function
|
||||
*/
|
||||
removeItem() { }
|
||||
/* eslint-enable no-empty-function */
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for browser's local storage object.
|
||||
*/
|
||||
class JitsiLocalStorage extends DummyLocalStorage {
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Storage} storage browser's local storage object.
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
let storage;
|
||||
|
||||
try {
|
||||
storage = window.localStorage;
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
this.storage = storage || new DummyLocalStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns that passed key's value.
|
||||
* @param {string} keyName the name of the key you want to retrieve
|
||||
* the value of.
|
||||
* @returns {String|null} the value of the key. If the key does not exist,
|
||||
* null is returned.
|
||||
*/
|
||||
getItem(keyName) {
|
||||
return this.storage.getItem(keyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a key to the storage, or update key's value if it already exists.
|
||||
* @param {string} keyName the name of the key you want to create/update.
|
||||
* @param {string} keyValue the value you want to give the key you are
|
||||
* creating/updating.
|
||||
*/
|
||||
setItem(keyName, keyValue) {
|
||||
return this.storage.setItem(keyName, keyValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a key from the storage.
|
||||
* @param {string} keyName the name of the key you want to remove.
|
||||
*/
|
||||
removeItem(keyName) {
|
||||
return this.storage.removeItem(keyName);
|
||||
}
|
||||
}
|
||||
|
||||
export default new JitsiLocalStorage();
|
|
@ -10594,8 +10594,8 @@
|
|||
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
|
||||
},
|
||||
"js-utils": {
|
||||
"version": "github:jitsi/js-utils#df68966e3c65b5c57fcd2670da1326a2c77518d1",
|
||||
"from": "github:jitsi/js-utils#df68966e3c65b5c57fcd2670da1326a2c77518d1",
|
||||
"version": "github:jitsi/js-utils#0c0c4142bd559fffffaebaded80bdaba8414d6b8",
|
||||
"from": "github:jitsi/js-utils#0c0c4142bd559fffffaebaded80bdaba8414d6b8",
|
||||
"requires": {
|
||||
"bowser": "2.7.0",
|
||||
"js-md5": "0.7.3",
|
||||
|
@ -10794,15 +10794,15 @@
|
|||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "github:jitsi/lib-jitsi-meet#dffe94f270f692c7421412bbbc597279e4a2d805",
|
||||
"from": "github:jitsi/lib-jitsi-meet#dffe94f270f692c7421412bbbc597279e4a2d805",
|
||||
"version": "github:jitsi/lib-jitsi-meet#c6e8d596b0817a6584915457b2cb9ef726e94181",
|
||||
"from": "github:jitsi/lib-jitsi-meet#c6e8d596b0817a6584915457b2cb9ef726e94181",
|
||||
"requires": {
|
||||
"@jitsi/sdp-interop": "1.0.2",
|
||||
"@jitsi/sdp-simulcast": "0.3.0",
|
||||
"async": "0.9.0",
|
||||
"current-executing-script": "0.1.3",
|
||||
"jitsi-meet-logger": "github:jitsi/jitsi-meet-logger#5ec92357570dc8f0b7ffc1528820721c84c6af8b",
|
||||
"js-utils": "github:jitsi/js-utils#df68966e3c65b5c57fcd2670da1326a2c77518d1",
|
||||
"js-utils": "github:jitsi/js-utils#0c0c4142bd559fffffaebaded80bdaba8414d6b8",
|
||||
"lodash.isequal": "4.5.0",
|
||||
"sdp-transform": "2.3.0",
|
||||
"strophe.js": "1.3.4",
|
||||
|
|
|
@ -53,10 +53,10 @@
|
|||
"jquery-contextmenu": "2.4.5",
|
||||
"jquery-i18next": "1.2.1",
|
||||
"js-md5": "0.6.1",
|
||||
"js-utils": "github:jitsi/js-utils#df68966e3c65b5c57fcd2670da1326a2c77518d1",
|
||||
"js-utils": "github:jitsi/js-utils#0c0c4142bd559fffffaebaded80bdaba8414d6b8",
|
||||
"jsrsasign": "8.0.12",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#dffe94f270f692c7421412bbbc597279e4a2d805",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#c6e8d596b0817a6584915457b2cb9ef726e94181",
|
||||
"libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
|
||||
"lodash": "4.17.13",
|
||||
"moment": "2.19.4",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
import _ from 'lodash';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
|
@ -15,7 +16,6 @@ import {
|
|||
} from '../../redux';
|
||||
import { SoundCollection } from '../../sounds';
|
||||
import { PersistenceRegistry } from '../../storage';
|
||||
|
||||
import { appWillMount, appWillUnmount } from '../actions';
|
||||
import logger from '../logger';
|
||||
|
||||
|
@ -110,7 +110,7 @@ export default class BaseApp extends Component<*, State> {
|
|||
* @returns {Promise}
|
||||
*/
|
||||
_initStorage(): Promise<*> {
|
||||
const { _initializing } = window.localStorage;
|
||||
const _initializing = jitsiLocalStorage.getItem('_initializing');
|
||||
|
||||
return _initializing || Promise.resolve();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { addKnownDomains } from '../known-domains';
|
||||
|
@ -109,11 +110,8 @@ export function storeConfig(baseURL: string, config: Object) {
|
|||
let b = false;
|
||||
|
||||
try {
|
||||
if (typeof window.config === 'undefined'
|
||||
|| window.config !== config) {
|
||||
window.localStorage.setItem(
|
||||
`${_CONFIG_STORE_PREFIX}/${baseURL}`,
|
||||
JSON.stringify(config));
|
||||
if (typeof window.config === 'undefined' || window.config !== config) {
|
||||
jitsiLocalStorage.setItem(`${_CONFIG_STORE_PREFIX}/${baseURL}`, JSON.stringify(config));
|
||||
b = true;
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
import _ from 'lodash';
|
||||
|
||||
import CONFIG_WHITELIST from './configWhitelist';
|
||||
|
@ -136,22 +137,16 @@ function _getWhitelistedJSON(configName, configJSON) {
|
|||
* otherwise, {@code undefined}.
|
||||
*/
|
||||
export function restoreConfig(baseURL: string): ?Object {
|
||||
let storage;
|
||||
const key = `${_CONFIG_STORE_PREFIX}/${baseURL}`;
|
||||
|
||||
try {
|
||||
// XXX Even reading the property localStorage of window may throw an
|
||||
// error (which is user agent-specific behavior).
|
||||
storage = window.localStorage;
|
||||
|
||||
const config = storage.getItem(key);
|
||||
const config = jitsiLocalStorage.getItem(key);
|
||||
|
||||
if (config) {
|
||||
try {
|
||||
return JSON.parse(config) || undefined;
|
||||
}
|
||||
} catch (e) {
|
||||
// Somehow incorrect data ended up in the storage. Clean it up.
|
||||
storage && storage.removeItem(key);
|
||||
jitsiLocalStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
|
||||
import { APP_WILL_MOUNT } from '../app';
|
||||
import { addKnownDomains } from '../known-domains';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
|
@ -51,14 +53,12 @@ function _appWillMount(store, next, action) {
|
|||
// consequently, the feature known-domains, it's possible for the feature
|
||||
// base/config to know of domains which the feature known-domains is yet to
|
||||
// discover.
|
||||
const { localStorage } = window;
|
||||
|
||||
if (localStorage) {
|
||||
const prefix = `${_CONFIG_STORE_PREFIX}/`;
|
||||
const knownDomains = [];
|
||||
|
||||
for (let i = 0; /* localStorage.key(i) */; ++i) {
|
||||
const key = localStorage.key(i);
|
||||
const key = jitsiLocalStorage.key(i);
|
||||
|
||||
if (key) {
|
||||
let baseURL;
|
||||
|
@ -75,7 +75,6 @@ function _appWillMount(store, next, action) {
|
|||
}
|
||||
}
|
||||
knownDomains.length && store.dispatch(addKnownDomains(knownDomains));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
import { randomHexString } from 'js-utils/random';
|
||||
import _ from 'lodash';
|
||||
|
||||
|
@ -86,8 +87,7 @@ ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
|
|||
* @returns {Object}
|
||||
*/
|
||||
function _getLegacyProfile() {
|
||||
let persistedProfile
|
||||
= window.localStorage.getItem('features/base/profile');
|
||||
let persistedProfile = jitsiLocalStorage.getItem('features/base/profile');
|
||||
|
||||
if (persistedProfile) {
|
||||
try {
|
||||
|
@ -123,9 +123,9 @@ function _initSettings(featureState) {
|
|||
// FIXME: jibri uses old settings.js local storage values to set its display
|
||||
// name and email. Provide another way for jibri to set these values, update
|
||||
// jibri, and remove the old settings.js values.
|
||||
const savedDisplayName = window.localStorage.getItem('displayname');
|
||||
const savedEmail = window.localStorage.getItem('email');
|
||||
let avatarID = _.escape(window.localStorage.getItem('avatarId'));
|
||||
const savedDisplayName = jitsiLocalStorage.getItem('displayname');
|
||||
const savedEmail = jitsiLocalStorage.getItem('email');
|
||||
let avatarID = _.escape(jitsiLocalStorage.getItem('avatarId'));
|
||||
|
||||
// The helper _.escape will convert null to an empty strings. The empty
|
||||
// string will be saved in settings. On app re-load, because an empty string
|
||||
|
@ -149,16 +149,13 @@ function _initSettings(featureState) {
|
|||
|
||||
if (!browser.isReactNative()) {
|
||||
// Browser only
|
||||
const localFlipX
|
||||
= JSON.parse(window.localStorage.getItem('localFlipX') || 'true');
|
||||
const cameraDeviceId
|
||||
= window.localStorage.getItem('cameraDeviceId') || '';
|
||||
const micDeviceId = window.localStorage.getItem('micDeviceId') || '';
|
||||
const localFlipX = JSON.parse(jitsiLocalStorage.getItem('localFlipX') || 'true');
|
||||
const cameraDeviceId = jitsiLocalStorage.getItem('cameraDeviceId') || '';
|
||||
const micDeviceId = jitsiLocalStorage.getItem('micDeviceId') || '';
|
||||
|
||||
// Currently audio output device change is supported only in Chrome and
|
||||
// default output always has 'default' device ID
|
||||
const audioOutputDeviceId
|
||||
= window.localStorage.getItem('audioOutputDeviceId') || 'default';
|
||||
const audioOutputDeviceId = jitsiLocalStorage.getItem('audioOutputDeviceId') || 'default';
|
||||
|
||||
settings = assignIfDefined({
|
||||
audioOutputDeviceId,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import md5 from 'js-md5';
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
|
||||
import logger from './logger';
|
||||
|
||||
|
@ -63,8 +64,7 @@ class PersistenceRegistry {
|
|||
|
||||
// legacy
|
||||
if (Object.keys(filteredPersistedState).length === 0) {
|
||||
const { localStorage } = window;
|
||||
let persistedState = localStorage.getItem(PERSISTED_STATE_NAME);
|
||||
let persistedState = jitsiLocalStorage.getItem(PERSISTED_STATE_NAME);
|
||||
|
||||
if (persistedState) {
|
||||
try {
|
||||
|
@ -82,7 +82,7 @@ class PersistenceRegistry {
|
|||
// Store into the new format and delete the old format so that
|
||||
// it's not used again.
|
||||
this.persistState(filteredPersistedState);
|
||||
localStorage.removeItem(PERSISTED_STATE_NAME);
|
||||
jitsiLocalStorage.removeItem(PERSISTED_STATE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,18 +110,12 @@ class PersistenceRegistry {
|
|||
if (checksum !== this._checksum) {
|
||||
for (const subtreeName of Object.keys(filteredState)) {
|
||||
try {
|
||||
window.localStorage.setItem(
|
||||
subtreeName,
|
||||
JSON.stringify(filteredState[subtreeName]));
|
||||
jitsiLocalStorage.setItem(subtreeName, JSON.stringify(filteredState[subtreeName]));
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
'Error persisting redux subtree',
|
||||
subtreeName,
|
||||
error);
|
||||
logger.error('Error persisting redux subtree', subtreeName, error);
|
||||
}
|
||||
}
|
||||
logger.info(
|
||||
`redux state persisted. ${this._checksum} -> ${checksum}`);
|
||||
logger.info(`redux state persisted. ${this._checksum} -> ${checksum}`);
|
||||
this._checksum = checksum;
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +219,7 @@ class PersistenceRegistry {
|
|||
* @returns {Object}
|
||||
*/
|
||||
_getPersistedSubtree(subtreeName, subtreeConfig, subtreeDefaults) {
|
||||
let persistedSubtree = window.localStorage.getItem(subtreeName);
|
||||
let persistedSubtree = jitsiLocalStorage.getItem(subtreeName);
|
||||
|
||||
if (persistedSubtree) {
|
||||
try {
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
// @flow
|
||||
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from '../../base/redux';
|
||||
import { Icon, IconClose } from '../../base/icons';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { getCurrentConference } from '../../base/conference/functions';
|
||||
import { browser } from '../../base/lib-jitsi-meet';
|
||||
import {
|
||||
checkChromeExtensionsInstalled,
|
||||
isMobileBrowser
|
||||
} from '../../base/environment/utils';
|
||||
import logger from '../logger';
|
||||
|
||||
import {
|
||||
createChromeExtensionBannerEvent,
|
||||
sendAnalytics
|
||||
} from '../../analytics';
|
||||
import { getCurrentConference } from '../../base/conference/functions';
|
||||
import { Icon, IconClose } from '../../base/icons';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { browser } from '../../base/lib-jitsi-meet';
|
||||
import { connect } from '../../base/redux';
|
||||
import {
|
||||
checkChromeExtensionsInstalled,
|
||||
isMobileBrowser
|
||||
} from '../../base/environment/utils';
|
||||
|
||||
import logger from '../logger';
|
||||
|
||||
|
||||
declare var interfaceConfig: Object;
|
||||
|
||||
|
@ -182,7 +187,7 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
|
|||
return true;
|
||||
}
|
||||
|
||||
const dontShowAgain = localStorage.getItem(DONT_SHOW_AGAIN_CHECKED) === 'true';
|
||||
const dontShowAgain = jitsiLocalStorage.getItem(DONT_SHOW_AGAIN_CHECKED) === 'true';
|
||||
|
||||
return !this.props.bannerCfg.url
|
||||
|| dontShowAgain
|
||||
|
@ -212,7 +217,7 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
|
|||
render() {
|
||||
if (this._shouldNotRender()) {
|
||||
if (this.state.dontShowAgainChecked) {
|
||||
localStorage.setItem(DONT_SHOW_AGAIN_CHECKED, 'true');
|
||||
jitsiLocalStorage.setItem(DONT_SHOW_AGAIN_CHECKED, 'true');
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* @flow */
|
||||
|
||||
import jitsiLocalStorage from '../../../../modules/util/JitsiLocalStorage';
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
|
||||
import logger from '../logger';
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
|
||||
import { APP_WILL_MOUNT } from '../base/app';
|
||||
import { getURLWithoutParamsNormalized } from '../base/connection';
|
||||
import { ReducerRegistry } from '../base/redux';
|
||||
|
@ -119,15 +122,16 @@ function _appWillMount(state) {
|
|||
* @returns {Array<Object>}
|
||||
*/
|
||||
function _getLegacyRecentRoomList(): Array<Object> {
|
||||
try {
|
||||
const str = window.localStorage.getItem(LEGACY_STORAGE_KEY);
|
||||
const str = jitsiLocalStorage.getItem(LEGACY_STORAGE_KEY);
|
||||
|
||||
if (str) {
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn('Failed to parse legacy recent-room list!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return [];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue