From d5b280aadeaa4c718d0158561197c7045620ae0f Mon Sep 17 00:00:00 2001 From: Anton Arnautov <43254280+arnautov-anton@users.noreply.github.com> Date: Mon, 9 Oct 2023 11:22:44 +0200 Subject: [PATCH] fix: sorting in paginated grid (#1129) Sort dominant speakers only when their visibility state is unknown or invisible (UNKNOWN in this case). --- .../src/sorting/__tests__/presets.test.ts | 57 +++++++++++-------- packages/client/src/sorting/presets.ts | 3 +- .../CallLayout/PaginatedGridLayout.tsx | 17 +++++- .../components/CallLayout/SpeakerLayout.tsx | 1 + 4 files changed, 51 insertions(+), 27 deletions(-) diff --git a/packages/client/src/sorting/__tests__/presets.test.ts b/packages/client/src/sorting/__tests__/presets.test.ts index 207acb1d5c..d7d47a8df8 100644 --- a/packages/client/src/sorting/__tests__/presets.test.ts +++ b/packages/client/src/sorting/__tests__/presets.test.ts @@ -14,14 +14,17 @@ describe('presets', () => { }, })); - expect(ps.sort(paginatedLayoutSortPreset).map((p) => p.name)).toEqual([ - 'F', - 'B', - 'E', - 'D', - 'A', - 'C', - ]); + expect(ps.sort(paginatedLayoutSortPreset).map((p) => p.name)) + .toMatchInlineSnapshot(` + [ + "F", + "D", + "A", + "B", + "C", + "E", + ] + `); // server-pin C ps.at(-1)!.pin = { @@ -29,26 +32,32 @@ describe('presets', () => { pinnedAt: Date.now(), }; - expect(ps.sort(paginatedLayoutSortPreset).map((p) => p.name)).toEqual([ - 'C', - 'F', - 'B', - 'E', - 'D', - 'A', - ]); + expect(ps.sort(paginatedLayoutSortPreset).map((p) => p.name)) + .toMatchInlineSnapshot(` + [ + "E", + "F", + "D", + "A", + "B", + "C", + ] + `); ps.at(-3)!.publishedTracks = [TrackType.AUDIO]; // E ps.at(-2)!.isDominantSpeaker = false; // D ps.at(-1)!.isDominantSpeaker = true; // A - expect(ps.sort(paginatedLayoutSortPreset).map((p) => p.name)).toEqual([ - 'C', - 'F', - 'B', - 'A', - 'E', - 'D', - ]); + expect(ps.sort(paginatedLayoutSortPreset).map((p) => p.name)) + .toMatchInlineSnapshot(` + [ + "E", + "F", + "D", + "C", + "B", + "A", + ] + `); }); }); diff --git a/packages/client/src/sorting/presets.ts b/packages/client/src/sorting/presets.ts index 23071a9dd5..a4a81824aa 100644 --- a/packages/client/src/sorting/presets.ts +++ b/packages/client/src/sorting/presets.ts @@ -67,8 +67,7 @@ export const speakerLayoutSortPreset = combineComparators( */ export const paginatedLayoutSortPreset = combineComparators( pinned, - screenSharing, - dominantSpeaker, + ifInvisibleOrUnknownBy(dominantSpeaker), ifInvisibleOrUnknownBy(speaking), ifInvisibleOrUnknownBy(reactionType('raised-hand')), ifInvisibleOrUnknownBy(publishingVideo), diff --git a/packages/react-sdk/src/core/components/CallLayout/PaginatedGridLayout.tsx b/packages/react-sdk/src/core/components/CallLayout/PaginatedGridLayout.tsx index 1b220095f6..f0def63367 100644 --- a/packages/react-sdk/src/core/components/CallLayout/PaginatedGridLayout.tsx +++ b/packages/react-sdk/src/core/components/CallLayout/PaginatedGridLayout.tsx @@ -79,6 +79,10 @@ export const PaginatedGridLayout = ({ ParticipantViewUI = DefaultParticipantViewUI, }: PaginatedGridLayoutProps) => { const [page, setPage] = useState(0); + const [ + paginatedGridLayoutWrapperElement, + setPaginatedGridLayoutWrapperElement, + ] = useState(null); const call = useCall(); const { useParticipants, useRemoteParticipants } = useCallStateHooks(); @@ -88,6 +92,14 @@ export const PaginatedGridLayout = ({ usePaginatedLayoutSortPreset(call); + useEffect(() => { + if (!paginatedGridLayoutWrapperElement || !call) return; + + const cleanup = call.setViewport(paginatedGridLayoutWrapperElement); + + return () => cleanup(); + }, [paginatedGridLayoutWrapperElement, call]); + // only used to render video elements const participantGroups = useMemo( () => @@ -112,7 +124,10 @@ export const PaginatedGridLayout = ({ if (!call) return null; return ( -
+
{pageArrowsVisible && pageCount > 1 && ( diff --git a/packages/react-sdk/src/core/components/CallLayout/SpeakerLayout.tsx b/packages/react-sdk/src/core/components/CallLayout/SpeakerLayout.tsx index 4f959d08be..f3b7245bfb 100644 --- a/packages/react-sdk/src/core/components/CallLayout/SpeakerLayout.tsx +++ b/packages/react-sdk/src/core/components/CallLayout/SpeakerLayout.tsx @@ -72,6 +72,7 @@ export const SpeakerLayout = ({ if (!participantsBarWrapperElement || !call) return; const cleanup = call.setViewport(participantsBarWrapperElement); + return () => cleanup(); }, [participantsBarWrapperElement, call]);