Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Have LocalEchoWrapper emit updates so the app can react faster #7358

Merged
merged 1 commit into from
Dec 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions src/settings/SettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { _t } from '../languageHandler';
import dis from '../dispatcher/dispatcher';
import { IFeature, ISetting, LabGroup, SETTINGS } from "./Settings";
import LocalEchoWrapper from "./handlers/LocalEchoWrapper";
import { WatchManager, CallbackFn as WatchCallbackFn } from "./WatchManager";
import { CallbackFn as WatchCallbackFn, WatchManager } from "./WatchManager";
import { SettingLevel } from "./SettingLevel";
import SettingsHandler from "./handlers/SettingsHandler";
import { SettingUpdatedPayload } from "../dispatcher/payloads/SettingUpdatedPayload";
Expand All @@ -50,21 +50,20 @@ for (const key of Object.keys(SETTINGS)) {
}
}

// Only wrap the handlers with async setters in a local echo wrapper
const LEVEL_HANDLERS = {
[SettingLevel.DEVICE]: new DeviceSettingsHandler(featureNames, defaultWatchManager),
[SettingLevel.ROOM_DEVICE]: new RoomDeviceSettingsHandler(defaultWatchManager),
[SettingLevel.ROOM_ACCOUNT]: new RoomAccountSettingsHandler(defaultWatchManager),
[SettingLevel.ACCOUNT]: new AccountSettingsHandler(defaultWatchManager),
[SettingLevel.ROOM]: new RoomSettingsHandler(defaultWatchManager),
[SettingLevel.ROOM_ACCOUNT]: new LocalEchoWrapper(
new RoomAccountSettingsHandler(defaultWatchManager),
SettingLevel.ROOM_ACCOUNT,
),
[SettingLevel.ACCOUNT]: new LocalEchoWrapper(new AccountSettingsHandler(defaultWatchManager), SettingLevel.ACCOUNT),
[SettingLevel.ROOM]: new LocalEchoWrapper(new RoomSettingsHandler(defaultWatchManager), SettingLevel.ROOM),
[SettingLevel.CONFIG]: new ConfigSettingsHandler(featureNames),
[SettingLevel.DEFAULT]: new DefaultSettingsHandler(defaultSettings, invertedDefaultSettings),
};

// Wrap all the handlers with local echo
for (const key of Object.keys(LEVEL_HANDLERS)) {
LEVEL_HANDLERS[key] = new LocalEchoWrapper(LEVEL_HANDLERS[key]);
}

export const LEVEL_ORDER = [
SettingLevel.DEVICE,
SettingLevel.ROOM_DEVICE,
Expand Down
6 changes: 5 additions & 1 deletion src/settings/handlers/AccountSettingsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ const ANALYTICS_EVENT_TYPE = "im.vector.analytics";
* This handler does not make use of the roomId parameter.
*/
export default class AccountSettingsHandler extends MatrixClientBackedSettingsHandler {
constructor(private watchers: WatchManager) {
constructor(public readonly watchers: WatchManager) {
super();
}

public get level(): SettingLevel {
return SettingLevel.ACCOUNT;
}

public initMatrixClient(oldClient: MatrixClient, newClient: MatrixClient) {
if (oldClient) {
oldClient.removeListener("accountData", this.onAccountData);
Expand Down
2 changes: 1 addition & 1 deletion src/settings/handlers/DeviceSettingsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class DeviceSettingsHandler extends SettingsHandler {
* @param {string[]} featureNames The names of known features.
* @param {WatchManager} watchers The watch manager to notify updates to
*/
constructor(private featureNames: string[], private watchers: WatchManager) {
constructor(private featureNames: string[], public readonly watchers: WatchManager) {
super();
}

Expand Down
11 changes: 9 additions & 2 deletions src/settings/handlers/LocalEchoWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.
*/

import SettingsHandler from "./SettingsHandler";
import { SettingLevel } from "../SettingLevel";

/**
* A wrapper for a SettingsHandler that performs local echo on
Expand All @@ -32,8 +33,9 @@ export default class LocalEchoWrapper extends SettingsHandler {
/**
* Creates a new local echo wrapper
* @param {SettingsHandler} handler The handler to wrap
* @param {SettingLevel} level The level to notify updates at
*/
constructor(private handler: SettingsHandler) {
constructor(private readonly handler: SettingsHandler, private readonly level: SettingLevel) {
super();
}

Expand All @@ -54,8 +56,13 @@ export default class LocalEchoWrapper extends SettingsHandler {
const cacheRoomId = roomId ? roomId : "UNDEFINED"; // avoid weird keys
bySetting[cacheRoomId] = newValue;

const currentValue = this.handler.getValue(settingName, roomId);
const handlerPromise = this.handler.setValue(settingName, roomId, newValue);
return Promise.resolve(handlerPromise).finally(() => {
this.handler.watchers?.notifyUpdate(settingName, roomId, this.level, newValue);
return Promise.resolve(handlerPromise).catch(() => {
// notify of a rollback
this.handler.watchers?.notifyUpdate(settingName, roomId, this.level, currentValue);
}).finally(() => {
delete bySetting[cacheRoomId];
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/settings/handlers/RoomAccountSettingsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const ALLOWED_WIDGETS_EVENT_TYPE = "im.vector.setting.allowed_widgets";
* Gets and sets settings at the "room-account" level for the current user.
*/
export default class RoomAccountSettingsHandler extends MatrixClientBackedSettingsHandler {
constructor(private watchers: WatchManager) {
constructor(public readonly watchers: WatchManager) {
super();
}

Expand Down
2 changes: 1 addition & 1 deletion src/settings/handlers/RoomDeviceSettingsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { WatchManager } from "../WatchManager";
* room.
*/
export default class RoomDeviceSettingsHandler extends SettingsHandler {
constructor(private watchers: WatchManager) {
constructor(public readonly watchers: WatchManager) {
super();
}

Expand Down
2 changes: 1 addition & 1 deletion src/settings/handlers/RoomSettingsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { WatchManager } from "../WatchManager";
* Gets and sets settings at the "room" level.
*/
export default class RoomSettingsHandler extends MatrixClientBackedSettingsHandler {
constructor(private watchers: WatchManager) {
constructor(public readonly watchers: WatchManager) {
super();
}

Expand Down
4 changes: 4 additions & 0 deletions src/settings/handlers/SettingsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { WatchManager } from "../WatchManager";

/**
* Represents the base class for all level handlers. This class performs no logic
* and should be overridden.
*/
export default abstract class SettingsHandler {
public readonly watchers?: WatchManager;

/**
* Gets the value for a particular setting at this level for a particular room.
* If no room is applicable, the roomId may be null. The roomId may not be
Expand Down