2024-05-08 15:29:39 -04:00
|
|
|
/*
|
2024-09-06 10:22:13 +02:00
|
|
|
Copyright 2024 New Vector Ltd.
|
2024-05-08 15:29:39 -04:00
|
|
|
|
2025-02-18 17:59:58 +00:00
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
2024-09-06 10:22:13 +02:00
|
|
|
Please see LICENSE in the repository root for full details.
|
2024-05-08 15:29:39 -04:00
|
|
|
*/
|
|
|
|
|
|
2025-03-13 13:58:43 +01:00
|
|
|
import { logger } from "matrix-js-sdk/lib/logger";
|
2024-12-11 09:27:55 +00:00
|
|
|
import { BehaviorSubject, type Observable } from "rxjs";
|
2024-05-08 15:29:39 -04:00
|
|
|
import { useObservableEagerState } from "observable-hooks";
|
|
|
|
|
|
|
|
|
|
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
|
|
|
|
|
|
|
|
|
export class Setting<T> {
|
2024-11-08 17:36:40 +00:00
|
|
|
public constructor(
|
|
|
|
|
key: string,
|
|
|
|
|
public readonly defaultValue: T,
|
|
|
|
|
) {
|
2024-05-08 15:29:39 -04:00
|
|
|
this.key = `matrix-setting-${key}`;
|
|
|
|
|
|
|
|
|
|
const storedValue = localStorage.getItem(this.key);
|
|
|
|
|
let initialValue = defaultValue;
|
|
|
|
|
if (storedValue !== null) {
|
|
|
|
|
try {
|
|
|
|
|
initialValue = JSON.parse(storedValue);
|
|
|
|
|
} catch (e) {
|
2024-09-03 17:14:27 +02:00
|
|
|
logger.warn(
|
|
|
|
|
`Invalid value stored for setting ${key}: ${storedValue}.`,
|
|
|
|
|
e,
|
|
|
|
|
);
|
2024-05-08 15:29:39 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-17 04:01:56 +00:00
|
|
|
this._value$ = new BehaviorSubject(initialValue);
|
|
|
|
|
this.value$ = this._value$;
|
2024-05-08 15:29:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private readonly key: string;
|
|
|
|
|
|
2024-12-17 04:01:56 +00:00
|
|
|
private readonly _value$: BehaviorSubject<T>;
|
|
|
|
|
public readonly value$: Observable<T>;
|
2024-05-08 15:29:39 -04:00
|
|
|
|
|
|
|
|
public readonly setValue = (value: T): void => {
|
2024-12-17 04:01:56 +00:00
|
|
|
this._value$.next(value);
|
2024-05-08 15:29:39 -04:00
|
|
|
localStorage.setItem(this.key, JSON.stringify(value));
|
|
|
|
|
};
|
2025-05-14 10:41:03 +02:00
|
|
|
public readonly getValue = (): T => {
|
|
|
|
|
return this._value$.getValue();
|
|
|
|
|
};
|
2024-05-08 15:29:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* React hook that returns a settings's current value and a setter.
|
|
|
|
|
*/
|
|
|
|
|
export function useSetting<T>(setting: Setting<T>): [T, (value: T) => void] {
|
2024-12-17 04:01:56 +00:00
|
|
|
return [useObservableEagerState(setting.value$), setting.setValue];
|
2024-05-08 15:29:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// null = undecided
|
|
|
|
|
export const optInAnalytics = new Setting<boolean | null>(
|
|
|
|
|
"opt-in-analytics",
|
|
|
|
|
null,
|
|
|
|
|
);
|
|
|
|
|
// TODO: This setting can be disabled. Work out an approach to disableable
|
|
|
|
|
// settings thats works for Observables in addition to React.
|
|
|
|
|
export const useOptInAnalytics = (): [
|
|
|
|
|
boolean | null,
|
|
|
|
|
((value: boolean | null) => void) | null,
|
|
|
|
|
] => {
|
|
|
|
|
const setting = useSetting(optInAnalytics);
|
2024-07-12 14:15:27 -04:00
|
|
|
return PosthogAnalytics.instance.isEnabled() ? setting : [false, null];
|
2024-05-08 15:29:39 -04:00
|
|
|
};
|
|
|
|
|
|
2024-12-11 14:30:16 +00:00
|
|
|
export const developerMode = new Setting("developer-settings-tab", false);
|
2024-05-08 15:29:39 -04:00
|
|
|
|
2024-05-08 16:00:42 -04:00
|
|
|
export const duplicateTiles = new Setting("duplicate-tiles", 0);
|
|
|
|
|
|
2024-12-13 14:53:08 +00:00
|
|
|
export const showNonMemberTiles = new Setting<boolean>(
|
|
|
|
|
"show-non-member-tiles",
|
|
|
|
|
false,
|
|
|
|
|
);
|
2024-12-11 05:23:42 -05:00
|
|
|
export const debugTileLayout = new Setting("debug-tile-layout", false);
|
|
|
|
|
|
2025-01-06 09:47:39 +00:00
|
|
|
export const showConnectionStats = new Setting<boolean>(
|
|
|
|
|
"show-connection-stats",
|
|
|
|
|
false,
|
|
|
|
|
);
|
|
|
|
|
|
2024-05-08 15:29:39 -04:00
|
|
|
export const audioInput = new Setting<string | undefined>(
|
|
|
|
|
"audio-input",
|
|
|
|
|
undefined,
|
|
|
|
|
);
|
|
|
|
|
export const audioOutput = new Setting<string | undefined>(
|
|
|
|
|
"audio-output",
|
|
|
|
|
undefined,
|
|
|
|
|
);
|
|
|
|
|
export const videoInput = new Setting<string | undefined>(
|
|
|
|
|
"video-input",
|
|
|
|
|
undefined,
|
|
|
|
|
);
|
2024-05-16 13:33:02 -04:00
|
|
|
|
2024-11-29 18:18:40 +01:00
|
|
|
export const backgroundBlur = new Setting<boolean>("background-blur", false);
|
2024-11-20 17:22:24 +01:00
|
|
|
|
2024-11-04 08:54:13 -01:00
|
|
|
export const showHandRaisedTimer = new Setting<boolean>(
|
|
|
|
|
"hand-raised-show-timer",
|
|
|
|
|
false,
|
|
|
|
|
);
|
|
|
|
|
|
2024-11-08 17:36:40 +00:00
|
|
|
export const showReactions = new Setting<boolean>("reactions-show", true);
|
|
|
|
|
|
|
|
|
|
export const playReactionsSound = new Setting<boolean>(
|
|
|
|
|
"reactions-play-sound",
|
|
|
|
|
true,
|
|
|
|
|
);
|
|
|
|
|
|
2025-05-13 22:05:55 +02:00
|
|
|
export const soundEffectVolume = new Setting<number>(
|
2024-11-07 16:42:43 +00:00
|
|
|
"sound-effect-volume",
|
2024-11-12 10:18:45 +00:00
|
|
|
0.5,
|
2024-11-07 16:42:43 +00:00
|
|
|
);
|
2024-11-07 16:35:37 +00:00
|
|
|
|
2025-05-13 21:11:12 +02:00
|
|
|
export const useNewMembershipManager = new Setting<boolean>(
|
2025-03-07 17:27:04 +01:00
|
|
|
"new-membership-manager",
|
|
|
|
|
true,
|
|
|
|
|
);
|
2025-04-11 10:07:50 +02:00
|
|
|
|
2025-05-13 21:11:12 +02:00
|
|
|
export const useExperimentalToDeviceTransport = new Setting<boolean>(
|
2025-04-11 10:07:50 +02:00
|
|
|
"experimental-to-device-transport",
|
2025-04-11 17:05:57 +02:00
|
|
|
true,
|
2025-04-11 10:07:50 +02:00
|
|
|
);
|
|
|
|
|
|
2025-05-13 21:11:12 +02:00
|
|
|
export const muteAllAudio = new Setting<boolean>("mute-all-audio", false);
|
|
|
|
|
|
2024-05-16 13:33:02 -04:00
|
|
|
export const alwaysShowSelf = new Setting<boolean>("always-show-self", true);
|
2025-05-14 10:41:03 +02:00
|
|
|
|
|
|
|
|
export const alwaysShowIphoneEarpiece = new Setting<boolean>(
|
|
|
|
|
"always-show-iphone-earpice",
|
|
|
|
|
false,
|
|
|
|
|
);
|