diff options
Merge branch 'UseStorageLocal' into i3076-UseStorageLocalInstead
Diffstat (limited to 'app/scripts')
-rw-r--r-- | app/scripts/background.js | 18 | ||||
-rw-r--r-- | app/scripts/lib/extension-store.js | 39 | ||||
-rw-r--r-- | app/scripts/lib/local-store.js | 25 |
3 files changed, 82 insertions, 0 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js index 0471cee3b..280c28d70 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -4,6 +4,7 @@ const pump = require('pump') const log = require('loglevel') const extension = require('extensionizer') const LocalStorageStore = require('obs-store/lib/localStorage') +const LocalStore = require('./lib/local-store') const storeTransform = require('obs-store/lib/transform') const asStream = require('obs-store/lib/asStream') const ExtensionPlatform = require('./platforms/extension') @@ -33,6 +34,7 @@ let popupIsOpen = false // state persistence const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY }) +const localStore = new LocalStore() // initialization flow initialize().catch(log.error) @@ -52,6 +54,14 @@ async function loadStateFromPersistence () { const migrator = new Migrator({ migrations }) // read from disk let versionedData = diskStore.getState() || migrator.generateInitialState(firstTimeState) + // fetch from extension store and merge in data + + if (localStore.isSupported) { + const localData = await localStore.get() + // TODO: handle possible exceptions (https://developer.chrome.com/apps/runtime#property-lastError) + versionedData = Object.keys(localData).length > 0 ? localData : versionedData + } + // migrate data versionedData = await migrator.migrateData(versionedData) // write to disk @@ -91,6 +101,7 @@ function setupController (initState) { pump( asStream(controller.store), storeTransform(versionifyData), + storeTransform(syncDataWithExtension), asStream(diskStore) ) @@ -100,6 +111,13 @@ function setupController (initState) { return versionedData } + function syncDataWithExtension(state) { + if (localStore.isSupported) { + localStore.set(state) // TODO: handle possible exceptions (https://developer.chrome.com/apps/runtime#property-lastError) + } + return state + } + // // connect to other contexts // diff --git a/app/scripts/lib/extension-store.js b/app/scripts/lib/extension-store.js new file mode 100644 index 000000000..67ee71f16 --- /dev/null +++ b/app/scripts/lib/extension-store.js @@ -0,0 +1,39 @@ +const extension = require('extensionizer') + +const KEYS_TO_SYNC = ['KeyringController', 'PreferencesController'] +const FIREFOX_SYNC_DISABLED_MESSAGE = 'Please set webextensions.storage.sync.enabled to true in about:config' + +const handleDisabledSyncAndResolve = (resolve, toResolve) => { + // Firefox 52 has sync available on extension.storage, but it is disabled by default + const lastError = extension.runtime.lastError + if (lastError && lastError.message.includes(FIREFOX_SYNC_DISABLED_MESSAGE)) { + resolve({}) + } else { + resolve(toResolve) + } +} + +module.exports = class ExtensionStore { + constructor() { + this.isSupported = !!(extension.storage.sync) + this.isEnabled = true // TODO: get value from user settings + } + async fetch() { + return new Promise((resolve) => { + extension.storage.sync.get(KEYS_TO_SYNC, (data) => { + handleDisabledSyncAndResolve(resolve, data) + }) + }) + } + async sync(state) { + const dataToSync = KEYS_TO_SYNC.reduce((result, key) => { + result[key] = state.data[key] + return result + }, {}) + return new Promise((resolve) => { + extension.storage.sync.set(dataToSync, () => { + handleDisabledSyncAndResolve(resolve) + }) + }) + } +} diff --git a/app/scripts/lib/local-store.js b/app/scripts/lib/local-store.js new file mode 100644 index 000000000..32faac96b --- /dev/null +++ b/app/scripts/lib/local-store.js @@ -0,0 +1,25 @@ +// We should not rely on local storage in an extension! +// We should use this instead! +// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/local + +const extension = require('extensionizer') +const STORAGE_KEY = 'metamask-config' + +module.exports = class ExtensionStore { + constructor() { + this.isSupported = !!(extension.storage.local) + if (!this.isSupported) { + log.error('Storage local API not available.') + } + } + async get() { + return new Promise((resolve) => { + extension.storage.local.get(STORAGE_KEY, resolve) + }) + } + async set(state) { + return new Promise((resolve) => { + extension.storage.local.set(state, resolve) + }) + } +} |