From fdc6d4a1b6245f12c59118167f025f2f63b526d1 Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 8 May 2024 16:00:42 -0400 Subject: [PATCH 1/2] Add a developer option to duplicate tiles This is useful for testing how the UI behaves with different numbers of participants. --- public/locales/en-GB/app.json | 1 + src/settings/SettingsModal.tsx | 18 ++++++++++++++- src/settings/settings.ts | 2 ++ src/state/CallViewModel.ts | 41 +++++++++++++++++++++++----------- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index 4279bbb5..97f2be93 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -132,6 +132,7 @@ "developer_settings_label": "Developer Settings", "developer_settings_label_description": "Expose developer settings in the settings window.", "developer_tab_title": "Developer", + "duplicate_tiles_label": "Number of duplicate tiles", "feedback_tab_body": "If you are experiencing issues or simply would like to provide some feedback, please send us a short description below.", "feedback_tab_description_label": "Your feedback", "feedback_tab_h4": "Submit feedback", diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx index fd0b6295..d8430022 100644 --- a/src/settings/SettingsModal.tsx +++ b/src/settings/SettingsModal.tsx @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { ChangeEvent, FC, Key, ReactNode } from "react"; +import { ChangeEvent, FC, Key, ReactNode, useCallback } from "react"; import { Item } from "@react-stately/collections"; import { Trans, useTranslation } from "react-i18next"; import { MatrixClient } from "matrix-js-sdk"; @@ -44,6 +44,7 @@ import { useSetting, optInAnalytics as optInAnalyticsSetting, developerSettingsTab as developerSettingsTabSetting, + duplicateTiles as duplicateTilesSetting, } from "./settings"; import { isFirefox } from "../Platform"; @@ -80,6 +81,7 @@ export const SettingsModal: FC = ({ const [developerSettingsTab, setDeveloperSettingsTab] = useSetting( developerSettingsTabSetting, ); + const [duplicateTiles, setDuplicateTiles] = useSetting(duplicateTilesSetting); // Generate a `SelectInput` with a list of devices for a given device kind. const generateDeviceSelection = ( @@ -244,6 +246,20 @@ export const SettingsModal: FC = ({ })} + + ): void => { + setDuplicateTiles(event.target.valueAsNumber); + }, + [setDuplicateTiles], + )} + /> + ); diff --git a/src/settings/settings.ts b/src/settings/settings.ts index 307a557e..5f2cc529 100644 --- a/src/settings/settings.ts +++ b/src/settings/settings.ts @@ -76,6 +76,8 @@ export const developerSettingsTab = new Setting( false, ); +export const duplicateTiles = new Setting("duplicate-tiles", 0); + export const audioInput = new Setting( "audio-input", undefined, diff --git a/src/state/CallViewModel.ts b/src/state/CallViewModel.ts index e6d55b72..59f0f5dc 100644 --- a/src/state/CallViewModel.ts +++ b/src/state/CallViewModel.ts @@ -67,6 +67,7 @@ import { } from "./MediaViewModel"; import { finalizeValue } from "../observable-utils"; import { ObservableScope } from "./ObservableScope"; +import { duplicateTiles } from "../settings/settings"; // How long we wait after a focus switch before showing the real participant // list again @@ -308,11 +309,16 @@ export class CallViewModel extends ViewModel { combineLatest([ this.remoteParticipants, observeParticipantMedia(this.livekitRoom.localParticipant), + duplicateTiles.value, ]).pipe( scan( ( prevItems, - [remoteParticipants, { participant: localParticipant }], + [ + remoteParticipants, + { participant: localParticipant }, + duplicateTiles, + ], ) => { let allGhosts = true; @@ -330,20 +336,29 @@ export class CallViewModel extends ViewModel { ); } - const userMediaId = p.identity; - yield [ - userMediaId, - prevItems.get(userMediaId) ?? - new UserMedia(userMediaId, member, p, this.encrypted), - ]; - - if (p.isScreenShareEnabled) { - const screenShareId = `${userMediaId}:screen-share`; + // Create as many tiles for this participant as called for by + // the duplicateTiles option + for (let i = 0; i < 1 + duplicateTiles; i++) { + const userMediaId = `${p.identity}:${i}`; yield [ - screenShareId, - prevItems.get(screenShareId) ?? - new ScreenShare(screenShareId, member, p, this.encrypted), + userMediaId, + prevItems.get(userMediaId) ?? + new UserMedia(userMediaId, member, p, this.encrypted), ]; + + if (p.isScreenShareEnabled) { + const screenShareId = `${userMediaId}:screen-share`; + yield [ + screenShareId, + prevItems.get(screenShareId) ?? + new ScreenShare( + screenShareId, + member, + p, + this.encrypted, + ), + ]; + } } } }.bind(this)(), From 8c21e8f277915c3c38d38fdafbb9ae43b3db343e Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 17 Jul 2024 14:55:45 -0400 Subject: [PATCH 2/2] Use a more descriptive string --- public/locales/en-GB/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index 97f2be93..95bf334f 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -132,7 +132,7 @@ "developer_settings_label": "Developer Settings", "developer_settings_label_description": "Expose developer settings in the settings window.", "developer_tab_title": "Developer", - "duplicate_tiles_label": "Number of duplicate tiles", + "duplicate_tiles_label": "Number of additional tile copies per participant", "feedback_tab_body": "If you are experiencing issues or simply would like to provide some feedback, please send us a short description below.", "feedback_tab_description_label": "Your feedback", "feedback_tab_h4": "Submit feedback",