* make tiles based on rtc member * display missing lk participant + fix tile multiplier * add show_non_member_participants config option * per member tiles * merge fixes * linter * linter and tests * tests * adapt tests (wip) * Remove unused keys * Fix optionality of nonMemberItemCount * video is optional * Mock RTC members * Lint * Merge fixes * Fix user id * Add explicit types for public fields * isRTCParticipantAvailable => isLiveKitParticipantAvailable * isLiveKitParticipantAvailable * Readonly * More keys removal * Make local field based on view model class not observable * Wording * Fix RTC members in tes * Tests again * Lint * Disable showing non-member tiles by default * Duplicate screen sharing tiles like we used to * Lint * Revert function reordering * Remove throttleTime from bad merge * Cleanup * Tidy config of show non-member settings * tidy up handling of local rtc member in tests * tidy up test init * Fix mocks * Cleanup * Apply local override where participant not yet known * Handle no visible media id * Assertions for one-on-one view * Remove isLiveKitParticipantAvailable and show via encryption status * Handle no local media (yet) * Remove unused effect for setting * Tidy settings * Avoid case of one-to-one layout with missing local or remote * Iterate * Remove option to show non-member tiles to simplify code review * Remove unused code * Remove more remnants of show-non-member-tiles * iterate * back * Fix unit test * Refactor * Expose TestScheduler as global * Fix incorrect type assertion * Simplify speaking observer * Fix * Whitespace * Make it clear that we are mocking MatrixRTC memberships * Test case for only showing tiles for MatrixRTC session members * Simplify diff * Simplify diff These changes are in https://github.com/element-hq/element-call/pull/2809 * . * Whitespaces * Use asObservable when exposing subject * Show "waiting for media..." when no participant * Additional test case * Don't show "waiting for media..." in case of local participant * Make the loading state more subtle - instead of a label we show a animated gradient * Use correct key for matrix rtc foci in code comment. (#2838) * Update src/tile/SpotlightTile.tsx Co-authored-by: Timo <16718859+toger5@users.noreply.github.com> * Update src/state/CallViewModel.ts Co-authored-by: Timo <16718859+toger5@users.noreply.github.com> * Make the purpose of BaseMediaViewModel.local explicit * Use named object instead of unnamed array for spotlightAndPip * Refactor spotlightAndPip into spotlight and pip * Use if statement instead of ternary for readability in spotlight and pip logic * Review feedback * Fix tests for CallEventAudioRenderer * Lint * Developer setting to show non-member tiles This is based on top of https://github.com/element-hq/element-call/pull/2701 * Lint * Remove unused code * Remove changes that should be in https://github.com/element-hq/element-call/pull/2858 * Update src/state/CallViewModel.test.ts Co-authored-by: Robin <robin@robin.town> * Merge branch 'livekit' into toger5/show-non-member-tiles * Remove unused nonMemberItemCount * Restore default showNonMemberTiles value after test * Update comments --------- Co-authored-by: Timo <toger5@hotmail.de> Co-authored-by: Timo <16718859+toger5@users.noreply.github.com> Co-authored-by: Robin <robin@robin.town>
112 lines
2.9 KiB
TypeScript
112 lines
2.9 KiB
TypeScript
/*
|
|
Copyright 2024 New Vector Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import { logger } from "matrix-js-sdk/src/logger";
|
|
import { BehaviorSubject, type Observable } from "rxjs";
|
|
import { useObservableEagerState } from "observable-hooks";
|
|
|
|
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
|
|
|
export class Setting<T> {
|
|
public constructor(
|
|
key: string,
|
|
public readonly defaultValue: T,
|
|
) {
|
|
this.key = `matrix-setting-${key}`;
|
|
|
|
const storedValue = localStorage.getItem(this.key);
|
|
let initialValue = defaultValue;
|
|
if (storedValue !== null) {
|
|
try {
|
|
initialValue = JSON.parse(storedValue);
|
|
} catch (e) {
|
|
logger.warn(
|
|
`Invalid value stored for setting ${key}: ${storedValue}.`,
|
|
e,
|
|
);
|
|
}
|
|
}
|
|
|
|
this._value = new BehaviorSubject(initialValue);
|
|
this.value = this._value;
|
|
}
|
|
|
|
private readonly key: string;
|
|
|
|
private readonly _value: BehaviorSubject<T>;
|
|
public readonly value: Observable<T>;
|
|
|
|
public readonly setValue = (value: T): void => {
|
|
this._value.next(value);
|
|
localStorage.setItem(this.key, JSON.stringify(value));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* React hook that returns a settings's current value and a setter.
|
|
*/
|
|
export function useSetting<T>(setting: Setting<T>): [T, (value: T) => void] {
|
|
return [useObservableEagerState(setting.value), setting.setValue];
|
|
}
|
|
|
|
// 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);
|
|
return PosthogAnalytics.instance.isEnabled() ? setting : [false, null];
|
|
};
|
|
|
|
export const developerMode = new Setting("developer-settings-tab", false);
|
|
|
|
export const duplicateTiles = new Setting("duplicate-tiles", 0);
|
|
|
|
export const showNonMemberTiles = new Setting<boolean>(
|
|
"show-non-member-tiles",
|
|
false,
|
|
);
|
|
export const debugTileLayout = new Setting("debug-tile-layout", false);
|
|
|
|
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,
|
|
);
|
|
|
|
export const showHandRaisedTimer = new Setting<boolean>(
|
|
"hand-raised-show-timer",
|
|
false,
|
|
);
|
|
|
|
export const showReactions = new Setting<boolean>("reactions-show", true);
|
|
|
|
export const playReactionsSound = new Setting<boolean>(
|
|
"reactions-play-sound",
|
|
true,
|
|
);
|
|
|
|
export const soundEffectVolumeSetting = new Setting<number>(
|
|
"sound-effect-volume",
|
|
0.5,
|
|
);
|
|
|
|
export const alwaysShowSelf = new Setting<boolean>("always-show-self", true);
|