Files
healthchat-web/apps/web/src/settings/controllers/ServerSupportUnstableFeatureController.ts
T
Will Hunt 4bee845010 Show user status in timeline (#32991)
* Use other branch

* All the changes that got lost

* Fix merge

* Ensure emoji can only be one character long

* Fixup labs feature

* Remove redundant check

* Update snapshot

* update snapshot

* add snapshot

* unpin

* fix pnpm lock

* undo pn[m lockfile changes altogether

as we shouldn't actually need any afaik

* update snpahot for changed IDs

* Snapshot update

* Snapshot update

* There is now another section

* more snapshots

* more snapshot

* More snapshots

* oh come on snapshots

* actual snapshot update

* Fix sonar issues

* just update the thing manually

* [screams internally]

* Update snapshot

* test for useUserStatus

* Make useUserStatus actually truncate

* Split out slash command to its own file

& add test

* Remove irrelevant comment

* doc

* Comment on non-obvious error message

---------

Co-authored-by: David Baker <dbkr@users.noreply.github.com>
2026-04-29 08:14:22 +00:00

121 lines
4.5 KiB
TypeScript

/*
Copyright 2026 Element Creations Ltd.
Copyright 2024 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { type SettingLevel } from "../SettingLevel";
import MatrixClientBackedController from "./MatrixClientBackedController";
import { type WatchManager } from "../WatchManager";
import SettingsStore from "../SettingsStore";
import { type SettingKey } from "../Settings.tsx";
import { _t } from "../../languageHandler.tsx";
import PlatformPeg from "../../PlatformPeg.ts";
/**
* Disables a given setting if the server unstable feature it requires is not supported
* When a setting gets disabled or enabled from this controller it notifies the given WatchManager
*/
export default class ServerSupportUnstableFeatureController extends MatrixClientBackedController {
// Starts off as `undefined` so when we first compare the `newDisabledValue`, it sees
// it as a change and updates the watchers.
private enabled: boolean | undefined;
/**
* Construct a new ServerSupportUnstableFeatureController.
*
* @param unstableFeatureGroups - If any one of the feature groups is satisfied,
* then the setting is considered enabled. A feature group is satisfied if all of
* the features in the group are supported (all features in a group are required).
* @param defaultEnabled - If we haven't been able to check for support yet, should
* this feature be enabled or disabled (default).
* @param forceReload - Should the client force reload.
*/
public constructor(
private readonly settingName: SettingKey,
private readonly watchers: WatchManager,
private readonly unstableFeatureGroups: string[][],
private readonly stableVersion?: string,
private readonly disabledMessage?: TranslationKey,
private readonly forcedValue: any = false,
private readonly defaultEnabled = false,
private readonly forceReload = false,
) {
super();
}
public onChange(): void {
if (this.forceReload) {
PlatformPeg.get()?.reload();
}
}
public get disabled(): boolean {
if (this.enabled !== undefined) {
return !this.enabled;
}
return !this.defaultEnabled;
}
public set disabled(newDisabledValue: boolean) {
if (!newDisabledValue === this.enabled) return;
this.enabled = !newDisabledValue;
const level = SettingsStore.firstSupportedLevel(this.settingName);
if (!level) return;
const settingValue = SettingsStore.getValue(this.settingName, null);
this.watchers.notifyUpdate(this.settingName, null, level, settingValue);
}
protected async initMatrixClient(): Promise<void> {
// Check for stable version support first
if (this.stableVersion && (await this.client!.isVersionSupported(this.stableVersion))) {
this.disabled = false;
return;
}
// Otherwise, only one of the unstable feature groups needs to be satisfied in
// order for this setting overall to be enabled
let isEnabled = false;
for (const featureGroup of this.unstableFeatureGroups) {
const featureSupportList = await Promise.all(
featureGroup.map(async (feature) => {
const isFeatureSupported = await this.client!.doesServerSupportUnstableFeature(feature);
return isFeatureSupported;
}),
);
// Every feature in a feature group is required in order
// for this setting overall to be enabled.
const isFeatureGroupSatisfied = featureSupportList.every((isFeatureSupported) => isFeatureSupported);
if (isFeatureGroupSatisfied) {
isEnabled = true;
break;
}
}
this.disabled = !isEnabled;
}
public getValueOverride(
level: SettingLevel,
roomId: string | null,
calculatedValue: any,
calculatedAtLevel: SettingLevel | null,
): any {
if (this.settingDisabled) {
return this.forcedValue;
}
return null; // no override
}
public get settingDisabled(): boolean | string {
if (this.disabled) {
return this.disabledMessage ? _t(this.disabledMessage) : true;
}
return false;
}
}