From c24f721de06ad5679f32b51d81dfa441d3f929b9 Mon Sep 17 00:00:00 2001 From: trevor-signal <131492920+trevor-signal@users.noreply.github.com> Date: Fri, 30 Jan 2026 14:10:12 -0500 Subject: [PATCH] Update sidebar layout visibility in group calls --- ts/components/CallScreen.dom.tsx | 31 +-------- ts/components/CallingHeader.dom.stories.tsx | 2 - ts/components/CallingHeader.dom.tsx | 18 ++--- .../GroupCallRemoteParticipants.dom.tsx | 67 ++----------------- 4 files changed, 14 insertions(+), 104 deletions(-) diff --git a/ts/components/CallScreen.dom.tsx b/ts/components/CallScreen.dom.tsx index 55d35a1c87..5c6d6bdcca 100644 --- a/ts/components/CallScreen.dom.tsx +++ b/ts/components/CallScreen.dom.tsx @@ -327,20 +327,6 @@ export function CallScreen({ setShowRaisedHandsList(prevValue => !prevValue); }, []); - const [sidebarViewDiffersFromGridView, setSidebarViewDiffersFromGridView] = - useState(false); - - // If the user is in Sidebar view but it's no longer different from Grid view, - // automatically switch to Grid view. - useEffect(() => { - if ( - !sidebarViewDiffersFromGridView && - activeCall.viewMode === CallViewMode.Sidebar - ) { - changeCallView(CallViewMode.Paginated); - } - }, [sidebarViewDiffersFromGridView, activeCall.viewMode, changeCallView]); - const [controlsHover, setControlsHover] = useState(false); const onControlsMouseEnter = useCallback(() => { setControlsHover(true); @@ -459,7 +445,7 @@ export function CallScreen({ }, [showReactionPicker]); useScreenSharingStoppedToast({ activeCall, i18n }); - useViewModeChangedToast({ activeCall, i18n, sidebarViewDiffersFromGridView }); + useViewModeChangedToast({ activeCall, i18n }); const currentPresenter = remoteParticipants.find( participant => participant.presenting @@ -1004,9 +990,6 @@ export function CallScreen({ imageDataCache={imageDataCache} i18n={i18n} joinedAt={activeCall.joinedAt} - onSidebarViewDiffersFromGridViewChange={ - setSidebarViewDiffersFromGridView - } remoteParticipants={activeCall.remoteParticipants} setGroupCallVideoRequest={setGroupCallVideoRequest} remoteAudioLevels={activeCall.remoteAudioLevels} @@ -1087,7 +1070,6 @@ export function CallScreen({ i18n={i18n} isGroupCall={isGroupCall} participantCount={participantCount} - showSidebarViewOption={sidebarViewDiffersFromGridView} togglePip={togglePip} toggleSettings={toggleSettings} /> @@ -1335,11 +1317,9 @@ function renderDuration(ms: number): string { function useViewModeChangedToast({ activeCall, i18n, - sidebarViewDiffersFromGridView, }: { activeCall: ActiveCallType; i18n: LocalizerType; - sidebarViewDiffersFromGridView: boolean; }): void { const { viewMode } = activeCall; const previousViewMode = usePrevious(viewMode, viewMode); @@ -1359,14 +1339,6 @@ function useViewModeChangedToast({ return; } - if ( - !sidebarViewDiffersFromGridView && - previousViewMode === CallViewMode.Sidebar && - viewMode === CallViewMode.Paginated - ) { - return; - } - hideToast(VIEW_MODE_CHANGED_TOAST_KEY); showToast({ key: VIEW_MODE_CHANGED_TOAST_KEY, @@ -1389,7 +1361,6 @@ function useViewModeChangedToast({ hideToast, i18n, activeCall, - sidebarViewDiffersFromGridView, viewMode, previousViewMode, presenterAci, diff --git a/ts/components/CallingHeader.dom.stories.tsx b/ts/components/CallingHeader.dom.stories.tsx index 2dbe6d49f4..763a05346f 100644 --- a/ts/components/CallingHeader.dom.stories.tsx +++ b/ts/components/CallingHeader.dom.stories.tsx @@ -16,13 +16,11 @@ export default { argTypes: { isGroupCall: { control: { type: 'boolean' } }, participantCount: { control: { type: 'number' } }, - showSidebarViewOption: { control: { type: 'boolean' } }, }, args: { i18n, isGroupCall: false, participantCount: 0, - showSidebarViewOption: false, togglePip: action('toggle-pip'), callViewMode: CallViewMode.Paginated, changeCallView: action('change-call-view'), diff --git a/ts/components/CallingHeader.dom.tsx b/ts/components/CallingHeader.dom.tsx index 1b13992f90..89d7b9efff 100644 --- a/ts/components/CallingHeader.dom.tsx +++ b/ts/components/CallingHeader.dom.tsx @@ -15,7 +15,6 @@ export type PropsType = { isGroupCall?: boolean; onCancel?: () => void; participantCount: number; - showSidebarViewOption?: boolean; togglePip?: () => void; toggleSettings: () => void; changeCallView?: (mode: CallViewMode) => void; @@ -28,7 +27,6 @@ export function CallingHeader({ isGroupCall = false, onCancel, participantCount, - showSidebarViewOption = false, togglePip, toggleSettings, }: PropsType): React.JSX.Element { @@ -49,16 +47,12 @@ export function CallingHeader({ onClick: () => changeCallView(CallViewMode.Paginated), value: CallViewMode.Paginated, }, - ...(showSidebarViewOption - ? [ - { - icon: 'CallSettingsButton__Icon--SidebarView', - label: i18n('icu:calling__view_mode--overflow'), - onClick: () => changeCallView(CallViewMode.Sidebar), - value: CallViewMode.Sidebar, - }, - ] - : []), + { + icon: 'CallSettingsButton__Icon--SidebarView', + label: i18n('icu:calling__view_mode--overflow'), + onClick: () => changeCallView(CallViewMode.Sidebar), + value: CallViewMode.Sidebar, + }, { icon: 'CallSettingsButton__Icon--SpeakerView', label: i18n('icu:calling__view_mode--speaker'), diff --git a/ts/components/GroupCallRemoteParticipants.dom.tsx b/ts/components/GroupCallRemoteParticipants.dom.tsx index 7edacf5f50..1a1fa83c8c 100644 --- a/ts/components/GroupCallRemoteParticipants.dom.tsx +++ b/ts/components/GroupCallRemoteParticipants.dom.tsx @@ -68,7 +68,6 @@ type PropsType = { imageDataCache: React.RefObject; isCallReconnecting: boolean; joinedAt: number | null; - onSidebarViewDiffersFromGridViewChange: (differs: boolean) => void; remoteParticipants: ReadonlyArray; setGroupCallVideoRequest: ( _: Array, @@ -122,7 +121,6 @@ export function GroupCallRemoteParticipants({ i18n, isCallReconnecting, joinedAt, - onSidebarViewDiffersFromGridViewChange, remoteParticipants, setGroupCallVideoRequest, remoteAudioLevels, @@ -142,7 +140,10 @@ export function GroupCallRemoteParticipants({ const { invisibleDemuxIds, onParticipantVisibilityChanged } = useInvisibleParticipants(remoteParticipants); - const minRenderedHeight = getMinRenderedHeight(callViewMode); + const minRenderedHeight = + callViewMode === CallViewMode.Paginated + ? SMALL_TILES_MIN_HEIGHT + : LARGE_TILES_MIN_HEIGHT; const isInSpeakerView = callViewMode === CallViewMode.Speaker || @@ -156,7 +157,9 @@ export function GroupCallRemoteParticipants({ // 1. Figure out the maximum number of possible rows that could fit on the page. // Could be 0 if (a) there are no participants (b) the container's height is small. - const maxRowsPerPage = getMaxRowsPerPage(maxGridHeight, minRenderedHeight); + const maxRowsPerPage = Math.floor( + maxGridHeight / (minRenderedHeight + PARTICIPANT_MARGIN) + ); // 2. Sort the participants in priority order: by `presenting` first, since presenters // should be on the main grid, then by `speakerTime` so that the most recent speakers @@ -225,49 +228,6 @@ export function GroupCallRemoteParticipants({ setPageIndex(gridParticipantsByPage.length - 1); } - // Calculate whether Sidebar view would look different from Grid (Paginated) view. - // They differ when Grid view would have multiple pages. - const minRenderedHeightForGridView = getMinRenderedHeight( - CallViewMode.Paginated - ); - const maxRowsPerPageForGridView = getMaxRowsPerPage( - maxGridHeight, - minRenderedHeightForGridView - ); - const sidebarViewDiffersFromGridView = useMemo(() => { - if (!prioritySortedParticipants.length || !maxRowsPerPageForGridView) { - return false; - } - - // When in Grid view, we've already calculated with the right params - if (isInPaginationView) { - return gridParticipantsByPage.length > 1; - } - - // For other views, calculate how many would fit on the first page of Grid view - const gridViewPages = getGridParticipantsByPage({ - participants: prioritySortedParticipants, - maxRowWidth, - maxPages: 1, - maxRowsPerPage: maxRowsPerPageForGridView, - minRenderedHeight: minRenderedHeightForGridView, - maxParticipantsPerPage: MAX_PARTICIPANTS_PER_PAGE, - }); - - return gridViewPages[0].numParticipants < prioritySortedParticipants.length; - }, [ - isInPaginationView, - gridParticipantsByPage.length, - maxRowWidth, - maxRowsPerPageForGridView, - minRenderedHeightForGridView, - prioritySortedParticipants, - ]); - - useEffect(() => { - onSidebarViewDiffersFromGridViewChange(sidebarViewDiffersFromGridView); - }, [onSidebarViewDiffersFromGridViewChange, sidebarViewDiffersFromGridView]); - const totalParticipantsInGrid = gridParticipantsByPage.reduce( (pageCount, { numParticipants }) => pageCount + numParticipants, 0 @@ -675,19 +635,6 @@ function participantWidthAtHeight( return participant.videoAspectRatio * height; } -function getMinRenderedHeight(callViewMode: CallViewMode): number { - return callViewMode === CallViewMode.Paginated - ? SMALL_TILES_MIN_HEIGHT - : LARGE_TILES_MIN_HEIGHT; -} - -function getMaxRowsPerPage( - maxGridHeight: number, - minRenderedHeight: number -): number { - return Math.floor(maxGridHeight / (minRenderedHeight + PARTICIPANT_MARGIN)); -} - function stableParticipantComparator( a: Readonly<{ demuxId: number }>, b: Readonly<{ demuxId: number }>