diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 9865044717..f02c751a2c 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -18,6 +18,8 @@ limitations under the License. 'use strict'; +import Matrix from 'matrix-js-sdk'; + import utils from 'matrix-js-sdk/lib/utils'; import EventTimeline from 'matrix-js-sdk/lib/models/event-timeline'; import EventTimelineSet from 'matrix-js-sdk/lib/models/event-timeline-set'; @@ -51,6 +53,9 @@ class MatrixClientPeg { this.opts = { initialSyncLimit: 20, }; + // the credentials used to init the current client object. + // used if we tear it down & recreate it with a different store + this._currentClientCreds = null; } /** @@ -79,10 +84,30 @@ class MatrixClientPeg { * Home Server / Identity Server URLs and active credentials */ replaceUsingCreds(creds: MatrixClientCreds) { + this._currentClientCreds = creds; this._createClient(creds); } async start() { + for (const dbType of ['indexeddb', 'memory']) { + try { + const promise = this.matrixClient.store.startup(); + console.log("MatrixClientPeg: waiting for MatrixClient store to initialise"); + await promise; + break; + } catch (err) { + if (dbType === 'indexeddb') { + console.error('Error starting matrixclient store - falling back to memory store', err); + this.matrixClient.store = new Matrix.MatrixInMemoryStore({ + localStorage: global.localStorage, + }); + } else { + console.error('Failed to start memory store!', err); + throw err; + } + } + } + // try to initialise e2e on the new client try { // check that we have a version of the js-sdk which includes initCrypto @@ -103,18 +128,6 @@ class MatrixClientPeg { opts.lazyLoadMembers = true; } - try { - const promise = this.matrixClient.store.startup(); - console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`); - await promise; - } catch (err) { - // log any errors when starting up the database (if one exists) - console.error('Error starting matrixclient store', err); - } - - // regardless of errors, start the client. If we did error out, we'll - // just end up doing a full initial /sync. - // Connect the matrix client to the dispatcher MatrixActionCreators.start(this.matrixClient); @@ -147,7 +160,7 @@ class MatrixClientPeg { return matches[1]; } - _createClient(creds: MatrixClientCreds) { + _createClient(creds: MatrixClientCreds, useIndexedDb) { const opts = { baseUrl: creds.homeserverUrl, idBaseUrl: creds.identityServerUrl, @@ -158,7 +171,7 @@ class MatrixClientPeg { forceTURN: SettingsStore.getValue('webRtcForceTURN', false), }; - this.matrixClient = createMatrixClient(opts, this.indexedDbWorkerScript); + this.matrixClient = createMatrixClient(opts, useIndexedDb); // we're going to add eventlisteners for each matrix event tile, so the // potential number of event listeners is quite high. diff --git a/src/utils/createMatrixClient.js b/src/utils/createMatrixClient.js index 54312695b6..2acd1fae28 100644 --- a/src/utils/createMatrixClient.js +++ b/src/utils/createMatrixClient.js @@ -32,13 +32,18 @@ try { * @param {Object} opts options to pass to Matrix.createClient. This will be * extended with `sessionStore` and `store` members. * + * @param {bool} useIndexedDb True to attempt to use indexeddb, or false to force + * use of the memory store. Default: true. + * * @property {string} indexedDbWorkerScript Optional URL for a web worker script * for IndexedDB store operations. By default, indexeddb ops are done on * the main thread. * * @returns {MatrixClient} the newly-created MatrixClient */ -export default function createMatrixClient(opts) { +export default function createMatrixClient(opts, useIndexedDb) { + if (useIndexedDb === undefined) useIndexedDb = true; + const storeOpts = { useAuthorizationHeader: true, }; @@ -47,7 +52,7 @@ export default function createMatrixClient(opts) { storeOpts.sessionStore = new Matrix.WebStorageSessionStore(localStorage); } - if (indexedDB && localStorage) { + if (indexedDB && localStorage && useIndexedDb) { storeOpts.store = new Matrix.IndexedDBStore({ indexedDB: indexedDB, dbName: "riot-web-sync",