diff --git a/src/settings/LocalEchoWrapper.js b/src/settings/LocalEchoWrapper.js new file mode 100644 index 0000000000..8cc8e0294d --- /dev/null +++ b/src/settings/LocalEchoWrapper.js @@ -0,0 +1,67 @@ +/* +Copyright 2017 Travis Ralston + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import SettingsHandler from "./SettingsHandler"; + +/** + * A wrapper for a SettingsHandler that performs local echo on + * changes to settings. This wrapper will use the underlying + * handler as much as possible to ensure values are not stale. + */ +export default class LocalEchoWrapper extends SettingsHandler { + /** + * Creates a new local echo wrapper + * @param {SettingsHandler} handler The handler to wrap + */ + constructor(handler) { + super(); + this._handler = handler; + this._cache = { + // settingName: { roomId: value } + }; + } + + getValue(settingName, roomId) { + const cacheRoomId = roomId ? roomId : "UNDEFINED"; // avoid weird keys + const bySetting = this._cache[settingName]; + if (bySetting && bySetting.hasOwnProperty(cacheRoomId)) { + return bySetting[roomId]; + } + + return this._handler.getValue(settingName, roomId); + } + + setValue(settingName, roomId, newValue) { + if (!this._cache[settingName]) this._cache[settingName] = {}; + const bySetting = this._cache[settingName]; + + const cacheRoomId = roomId ? roomId : "UNDEFINED"; // avoid weird keys + bySetting[cacheRoomId] = newValue; + + return this._handler.setValue(settingName, roomId, newValue).finally(() => { + delete bySetting[cacheRoomId]; + }); + } + + + canSetValue(settingName, roomId) { + return this._handler.canSetValue(settingName, roomId); + } + + isSupported() { + return this._handler.isSupported(); + } +} \ No newline at end of file diff --git a/src/settings/SettingsStore.js b/src/settings/SettingsStore.js index e74280b844..f31c9980db 100644 --- a/src/settings/SettingsStore.js +++ b/src/settings/SettingsStore.js @@ -25,6 +25,7 @@ import ConfigSettingsHandler from "./ConfigSettingsHandler"; import {_t} from '../languageHandler'; import SdkConfig from "../SdkConfig"; import {SETTINGS} from "./Settings"; +import LocalEchoWrapper from "./LocalEchoWrapper"; /** * Represents the various setting levels supported by the SettingsStore. @@ -59,6 +60,11 @@ const LEVEL_HANDLERS = { "default": new DefaultSettingsHandler(defaultSettings), }; +// Wrap all the handlers with local echo +for (const key of Object.keys(LEVEL_HANDLERS)) { + LEVEL_HANDLERS[key] = new LocalEchoWrapper(LEVEL_HANDLERS[key]); +} + const LEVEL_ORDER = [ 'device', 'room-device', 'room-account', 'account', 'room', 'config', 'default', ];