From 7c51fff92c6ef55addf7fc5148ca8e35a900482f Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 7 Sep 2023 13:03:51 +0200 Subject: [PATCH] Revert "fix handling of multiple tracks of the same source from the same participant (#618)" This reverts commit 233eb346f0b86fccf117d9f8c9675ea346595147. --- .changeset/eight-nails-rush.md | 6 -- .changeset/quiet-yaks-argue.md | 6 -- packages/core/etc/components-core.api.md | 13 +--- .../src/sorting/tile-array-update.test.ts | 1 - .../core/src/sorting/tile-array-update.ts | 34 +++------ .../src/track-reference/test-utils.test.ts | 38 +--------- .../core/src/track-reference/test-utils.ts | 2 +- .../track-reference.utils.test.ts | 58 --------------- .../track-reference/track-reference.utils.ts | 46 ++---------- packages/core/src/utils.ts | 17 ----- packages/react/etc/components-react.api.md | 16 ++-- packages/react/src/components/TrackLoop.tsx | 10 ++- .../src/components/controls/FocusToggle.tsx | 19 +---- .../participant/ParticipantTile.tsx | 21 +++--- packages/react/src/hooks/useFocusToggle.ts | 74 ++++++------------- 15 files changed, 72 insertions(+), 289 deletions(-) delete mode 100644 .changeset/eight-nails-rush.md delete mode 100644 .changeset/quiet-yaks-argue.md delete mode 100644 packages/core/src/track-reference/track-reference.utils.test.ts diff --git a/.changeset/eight-nails-rush.md b/.changeset/eight-nails-rush.md deleted file mode 100644 index 1101c6a2f..000000000 --- a/.changeset/eight-nails-rush.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@livekit/components-react': minor -'@livekit/components-core': patch ---- - -fix handling of multiple tracks of the same source from the same participant diff --git a/.changeset/quiet-yaks-argue.md b/.changeset/quiet-yaks-argue.md deleted file mode 100644 index ad04c0d95..000000000 --- a/.changeset/quiet-yaks-argue.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@livekit/components-core": patch -"@livekit/components-react": patch ---- - -fix handling of multiple tracks of the same source from the same participant diff --git a/packages/core/etc/components-core.api.md b/packages/core/etc/components-core.api.md index b8f567cd7..68e71c023 100644 --- a/packages/core/etc/components-core.api.md +++ b/packages/core/etc/components-core.api.md @@ -184,16 +184,8 @@ export function isLocal(p: Participant): boolean; // @public export function isMobileBrowser(): boolean; -// @public @deprecated -export function isParticipantSourcePinned(participant: Participant, source: Track.Source, pinState: PinState | undefined): boolean; - // @public -export function isParticipantTrackReferencePinned(trackRef: TrackReference, pinState: PinState | undefined): boolean; - -// Warning: (ae-internal-missing-underscore) The name "isPlaceholderReplacement" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export function isPlaceholderReplacement(currentTrackRef: TrackReferenceOrPlaceholder, nextTrackRef: TrackReferenceOrPlaceholder): boolean; +export function isParticipantSourcePinned(participant: Participant, source: Track.Source, pinState: PinState | undefined): boolean; // @public (undocumented) export function isRemote(p: Participant): boolean; @@ -509,9 +501,6 @@ export type TrackReference = { // @public (undocumented) export type TrackReferenceFilter = Parameters['0']; -// @public (undocumented) -export type TrackReferenceId = ReturnType; - // @public (undocumented) export type TrackReferenceOrPlaceholder = TrackReference | TrackReferencePlaceholder; diff --git a/packages/core/src/sorting/tile-array-update.test.ts b/packages/core/src/sorting/tile-array-update.test.ts index db40c0602..8f92d2774 100644 --- a/packages/core/src/sorting/tile-array-update.test.ts +++ b/packages/core/src/sorting/tile-array-update.test.ts @@ -338,7 +338,6 @@ describe('Test updating the list based while considering pages.', () => { expect(flatTrackReferenceArray(result)).toStrictEqual(flatTrackReferenceArray(expected)); }); - // FIXME: mute for implementation unmute before production. test.each([ { state: [mockTrackReferencePlaceholder('A', Track.Source.Camera)], diff --git a/packages/core/src/sorting/tile-array-update.ts b/packages/core/src/sorting/tile-array-update.ts index adf0acdb3..66cb63d91 100644 --- a/packages/core/src/sorting/tile-array-update.ts +++ b/packages/core/src/sorting/tile-array-update.ts @@ -1,12 +1,7 @@ import { differenceBy, chunk, zip } from '../helper/array-helper'; import { log } from '../logger'; import type { TrackReferenceOrPlaceholder } from '../track-reference'; -import { - getTrackReferenceId, - isPlaceholderReplacement, - isTrackReference, - isTrackReferencePlaceholder, -} from '../track-reference'; +import { getTrackReferenceId } from '../track-reference'; import { flatTrackReferenceArray } from '../track-reference/test-utils'; type VisualChanges = { @@ -85,12 +80,12 @@ export function updatePages( ): T[] { let updatedList: T[] = refreshList(currentList, nextList); - if (updatedList.length < nextList.length) { + if (currentList.length < nextList.length) { // Items got added: Find newly added items and add them to the end of the list. - const addedItems = differenceBy(nextList, updatedList, getTrackReferenceId); + const addedItems = differenceBy(nextList, currentList, getTrackReferenceId); updatedList = [...updatedList, ...addedItems]; } - const currentPages = divideIntoPages(updatedList, maxItemsOnPage); + const currentPages = divideIntoPages(currentList, maxItemsOnPage); const nextPages = divideIntoPages(nextList, maxItemsOnPage); zip(currentPages, nextPages).forEach(([currentPage, nextPage], pageIndex) => { @@ -136,7 +131,7 @@ export function updatePages( if (updatedList.length > nextList.length) { // Items got removed: Find items that got completely removed from the list. - const missingItems = differenceBy(updatedList, nextList, getTrackReferenceId); + const missingItems = differenceBy(currentList, nextList, getTrackReferenceId); updatedList = updatedList.filter( (item) => !missingItems.map(getTrackReferenceId).includes(getTrackReferenceId(item)), ); @@ -146,24 +141,19 @@ export function updatePages( } /** - * Update the current list with the items from the next list whenever the item ids are the same - * or the current item is a placeholder and we find a track reference in the next list - * to replace the placeholder with. + * Update the first list with the items from the second list whenever the ids are the same. * @remarks * This is needed because `TrackReference`s can change their internal state while keeping the same id. */ function refreshList(currentList: T[], nextList: T[]): T[] { return currentList.map((currentItem) => { const updateForCurrentItem = nextList.find( - (newItem_) => - // If the IDs match or .. - getTrackReferenceId(currentItem) === getTrackReferenceId(newItem_) || - // ... if the current item is a placeholder and the new item is the track reference can replace it. - (typeof currentItem !== 'number' && - isTrackReferencePlaceholder(currentItem) && - isTrackReference(newItem_) && - isPlaceholderReplacement(currentItem, newItem_)), + (newItem_) => getTrackReferenceId(currentItem) === getTrackReferenceId(newItem_), ); - return updateForCurrentItem ?? currentItem; + if (updateForCurrentItem) { + return updateForCurrentItem; + } else { + return currentItem; + } }); } diff --git a/packages/core/src/track-reference/test-utils.test.ts b/packages/core/src/track-reference/test-utils.test.ts index 1c966f5ce..ec140ebf1 100644 --- a/packages/core/src/track-reference/test-utils.test.ts +++ b/packages/core/src/track-reference/test-utils.test.ts @@ -1,8 +1,7 @@ import { describe, test, expect, expectTypeOf } from 'vitest'; -import { mockTrackReferencePlaceholder, mockTrackReferenceSubscribed } from './test-utils'; -import { Participant, TrackPublication } from 'livekit-client'; +import { mockTrackReferenceSubscribed } from './test-utils'; +import type { Participant, TrackPublication } from 'livekit-client'; import { Track } from 'livekit-client'; -import { getTrackReferenceId } from './track-reference.utils'; describe('Test mocking functions ', () => { test('mockTrackReferenceSubscribed without options.', () => { @@ -24,36 +23,3 @@ describe('Test mocking functions ', () => { expectTypeOf(mock.source).toMatchTypeOf(); }); }); - -describe('Test mockTrackReferencePlaceholder() produces valid id with getTrackReferenceId()', () => { - test.each([ - { - participantId: 'participantA', - trackSource: Track.Source.Camera, - expected: 'participantA_camera_placeholder', - }, - ])('mockTrackReferencePlaceholder id', ({ participantId, trackSource, expected }) => { - const mock = mockTrackReferencePlaceholder(participantId, trackSource); - const trackRefId = getTrackReferenceId(mock); - expect(trackRefId.startsWith(participantId)); - expect(trackRefId.endsWith('_placeholder')); - expect(trackRefId).toBe(expected); - }); -}); - -describe('Test mockTrackReferenceSubscribed() produces valid id with getTrackReferenceId()', () => { - test.each([ - { - participantId: 'participantA', - trackSource: Track.Source.Camera, - expected: 'participantA_camera_publicationId(participantA)', - }, - ])('mockTrackReferencePlaceholder id', ({ participantId, trackSource, expected }) => { - const mock = mockTrackReferenceSubscribed(participantId, trackSource, { - mockPublication: true, - }); - const trackRefId = getTrackReferenceId(mock); - expect(trackRefId.startsWith(participantId)); - expect(trackRefId).toBe(expected); - }); -}); diff --git a/packages/core/src/track-reference/test-utils.ts b/packages/core/src/track-reference/test-utils.ts index 1cd681ef0..524578893 100644 --- a/packages/core/src/track-reference/test-utils.ts +++ b/packages/core/src/track-reference/test-utils.ts @@ -51,7 +51,7 @@ export const mockTrackReferenceSubscribed = ( ? (mockParticipant(id, options.mockIsLocal ?? false) as Participant) : new Participant(`${id}`, `${id}`), publication: options.mockPublication - ? (mockTrackPublication(`publicationId(${id})`, kind, source) as TrackPublication) + ? (mockTrackPublication(id, kind, source) as TrackPublication) : publication, source, }; diff --git a/packages/core/src/track-reference/track-reference.utils.test.ts b/packages/core/src/track-reference/track-reference.utils.test.ts deleted file mode 100644 index effba1b03..000000000 --- a/packages/core/src/track-reference/track-reference.utils.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { describe, test, expect, expectTypeOf } from 'vitest'; -import { mockTrackReferencePlaceholder, mockTrackReferenceSubscribed } from './test-utils'; -import type { Participant, TrackPublication } from 'livekit-client'; -import { Track } from 'livekit-client'; -import { isPlaceholderReplacement } from './track-reference.utils'; - -describe('Test mocking functions ', () => { - test('mockTrackReferenceSubscribed without options.', () => { - const mock = mockTrackReferenceSubscribed('MOCK_ID', Track.Source.Camera); - expect(mock).toBeDefined(); - // Check if the participant is mocked correctly: - expect(mock.participant).toBeDefined(); - expect(mock.participant.identity).toBe('MOCK_ID'); - expectTypeOf(mock.participant).toMatchTypeOf(); - - // Check if the publication is mocked correctly: - expect(mock.publication).toBeDefined(); - expect(mock.publication.kind).toBe(Track.Kind.Video); - expectTypeOf(mock.publication).toMatchTypeOf(); - - // Check if the source is mocked correctly: - expect(mock.source).toBeDefined(); - expect(mock.source).toBe(Track.Source.Camera); - expectTypeOf(mock.source).toMatchTypeOf(); - }); -}); - -describe('Test if the current TrackReferencePlaceholder can be replaced with the next TrackReference.', () => { - test.each([ - { - currentTrackRef: mockTrackReferencePlaceholder('Participant_A', Track.Source.Camera), - nextTrackRef: mockTrackReferenceSubscribed('Participant_A', Track.Source.Camera, { - mockPublication: true, - }), - isReplacement: true, - }, - { - currentTrackRef: mockTrackReferencePlaceholder('Participant_B', Track.Source.Camera), - nextTrackRef: mockTrackReferenceSubscribed('Participant_A', Track.Source.Camera, { - mockPublication: true, - }), - isReplacement: false, - }, - { - currentTrackRef: mockTrackReferencePlaceholder('Participant_A', Track.Source.ScreenShare), - nextTrackRef: mockTrackReferenceSubscribed('Participant_A', Track.Source.Camera, { - mockPublication: true, - }), - isReplacement: false, - }, - ])( - 'Test if the current TrackReference was the placeholder for the next TrackReference.', - ({ nextTrackRef: trackRef, currentTrackRef: maybePlaceholder, isReplacement }) => { - const result = isPlaceholderReplacement(maybePlaceholder, trackRef); - expect(result).toBe(isReplacement); - }, - ); -}); diff --git a/packages/core/src/track-reference/track-reference.utils.ts b/packages/core/src/track-reference/track-reference.utils.ts index 22f28fa05..016c4a327 100644 --- a/packages/core/src/track-reference/track-reference.utils.ts +++ b/packages/core/src/track-reference/track-reference.utils.ts @@ -3,27 +3,17 @@ import type { PinState } from '../types'; import type { TrackReferenceOrPlaceholder } from './track-reference.types'; import { isTrackReference, isTrackReferencePlaceholder } from './track-reference.types'; -/** - * Returns a id to identify the `TrackReference` or `TrackReferencePlaceholder` based on - * participant, track source and trackSid. - * @remarks - * The id pattern is: `${participantIdentity}_${trackSource}_${trackSid}` for `TrackReference` - * and `${participantIdentity}_${trackSource}_placeholder` for `TrackReferencePlaceholder`. - */ -export function getTrackReferenceId(trackReference: TrackReferenceOrPlaceholder | number) { +/** Returns a id to identify the `TrackReference` based on participant and source. */ +export function getTrackReferenceId(trackReference: TrackReferenceOrPlaceholder | number): string { if (typeof trackReference === 'string' || typeof trackReference === 'number') { return `${trackReference}`; - } else if (isTrackReferencePlaceholder(trackReference)) { - return `${trackReference.participant.identity}_${trackReference.source}_placeholder`; } else if (isTrackReference(trackReference)) { - return `${trackReference.participant.identity}_${trackReference.publication.source}_${trackReference.publication.trackSid}`; + return `${trackReference.participant.identity}_${trackReference.publication.source}`; } else { - throw new Error(`Can't generate a id for the given track reference: ${trackReference}`); + return `${trackReference.participant.identity}_${trackReference.source}`; } } -export type TrackReferenceId = ReturnType; - /** Returns the Source of the TrackReference. */ export function getTrackReferenceSource(trackReference: TrackReferenceOrPlaceholder): Track.Source { if (isTrackReference(trackReference)) { @@ -37,14 +27,12 @@ export function isEqualTrackRef( a?: TrackReferenceOrPlaceholder, b?: TrackReferenceOrPlaceholder, ): boolean { - if (a === undefined || b === undefined) { - return false; - } if (isTrackReference(a) && isTrackReference(b)) { return a.publication.trackSid === b.publication.trackSid; - } else { - return getTrackReferenceId(a) === getTrackReferenceId(b); + } else if (isTrackReferencePlaceholder(a) && isTrackReferencePlaceholder(b)) { + return a.participant.identity === b.participant.identity && a.source === b.source; } + return false; } /** @@ -75,23 +63,3 @@ export function isTrackReferencePinned( return false; } } - -/** - * Check if the current `currentTrackRef` is the placeholder for next `nextTrackRef`. - * Based on the participant identity and the source. - * @internal - */ -export function isPlaceholderReplacement( - currentTrackRef: TrackReferenceOrPlaceholder, - nextTrackRef: TrackReferenceOrPlaceholder, -) { - // if (typeof nextTrackRef === 'number' || typeof currentTrackRef === 'number') { - // return false; - // } - return ( - isTrackReferencePlaceholder(currentTrackRef) && - isTrackReference(nextTrackRef) && - nextTrackRef.participant.identity === currentTrackRef.participant.identity && - nextTrackRef.source === currentTrackRef.source - ); -} diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 0c516c5c4..6584b96c2 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -2,8 +2,6 @@ import type { Participant, Track, TrackPublication } from 'livekit-client'; import { LocalParticipant, RemoteParticipant } from 'livekit-client'; import type { PinState } from './types'; -import type { TrackReference } from './track-reference'; -import { isEqualTrackRef } from './track-reference'; export function isLocal(p: Participant) { return p instanceof LocalParticipant; @@ -30,7 +28,6 @@ export const attachIfSubscribed = ( /** * Check if the participant track source is pinned. - * @deprecated Use {@link isParticipantTrackReferencePinned} instead. */ export function isParticipantSourcePinned( participant: Participant, @@ -47,20 +44,6 @@ export function isParticipantSourcePinned( ); } -/** - * Check if the participant track reference is pinned. - */ -export function isParticipantTrackReferencePinned( - trackRef: TrackReference, - pinState: PinState | undefined, -): boolean { - if (pinState === undefined) { - return false; - } - - return pinState.some((pinnedTrackRef) => isEqualTrackRef(pinnedTrackRef, trackRef)); -} - /** * Calculates the scrollbar width by creating two HTML elements * and messaging the difference. diff --git a/packages/react/etc/components-react.api.md b/packages/react/etc/components-react.api.md index aa591ea06..ce546bed2 100644 --- a/packages/react/etc/components-react.api.md +++ b/packages/react/etc/components-react.api.md @@ -222,16 +222,14 @@ export interface FocusLayoutProps extends React_2.HTMLAttributes { } // @public -export function FocusToggle({ trackRef, trackSource, participant, ...props }: FocusToggleProps): React_2.JSX.Element; +export function FocusToggle({ trackSource, participant, ...props }: FocusToggleProps): React_2.JSX.Element; // @public (undocumented) export interface FocusToggleProps extends React_2.ButtonHTMLAttributes { - // @deprecated (undocumented) + // (undocumented) participant?: Participant; // (undocumented) - trackRef?: TrackReferenceOrPlaceholder; - // @deprecated (undocumented) - trackSource?: Track.Source; + trackSource: Track.Source; } // @public (undocumented) @@ -574,7 +572,7 @@ export function useEnsureTrackReference(track?: TrackReferenceOrPlaceholder): Tr export function useFacingMode(trackReference: TrackReferenceOrPlaceholder): 'user' | 'environment' | 'left' | 'right' | 'undefined'; // @public (undocumented) -export function useFocusToggle({ trackRef, trackSource, participant, props }: UseFocusToggleProps): { +export function useFocusToggle({ trackSource, participant, props }: UseFocusToggleProps): { mergedProps: React_2.ButtonHTMLAttributes & { className: string; onClick: (event: React_2.MouseEvent) => void; @@ -584,14 +582,12 @@ export function useFocusToggle({ trackRef, trackSource, participant, props }: Us // @public (undocumented) export interface UseFocusToggleProps { - // @deprecated (undocumented) + // (undocumented) participant?: Participant; // (undocumented) props: React_2.ButtonHTMLAttributes; // (undocumented) - trackRef?: TrackReferenceOrPlaceholder; - // @deprecated (undocumented) - trackSource?: Track.Source; + trackSource: Track.Source; } // @public diff --git a/packages/react/src/components/TrackLoop.tsx b/packages/react/src/components/TrackLoop.tsx index edea7ac4b..691b6470c 100644 --- a/packages/react/src/components/TrackLoop.tsx +++ b/packages/react/src/components/TrackLoop.tsx @@ -1,8 +1,8 @@ import type { TrackReference, TrackReferenceOrPlaceholder } from '@livekit/components-core'; +import { isTrackReference } from '@livekit/components-core'; import * as React from 'react'; import { TrackContext } from '../context/track-context'; import { cloneSingleChild } from '../utils'; -import { getTrackReferenceId } from '@livekit/components-core'; /** @public */ export interface TrackLoopProps { @@ -31,8 +31,14 @@ export function TrackLoop({ tracks, ...props }: TrackLoopProps) { return ( <> {tracks.map((trackReference) => { + const trackSource = isTrackReference(trackReference) + ? trackReference.publication.source + : trackReference.source; return ( - + {cloneSingleChild(props.children)} ); diff --git a/packages/react/src/components/controls/FocusToggle.tsx b/packages/react/src/components/controls/FocusToggle.tsx index df734d80d..848ba6418 100644 --- a/packages/react/src/components/controls/FocusToggle.tsx +++ b/packages/react/src/components/controls/FocusToggle.tsx @@ -1,16 +1,12 @@ import type { Participant, Track } from 'livekit-client'; import * as React from 'react'; -import { LayoutContext, useMaybeTrackContext } from '../../context'; +import { LayoutContext } from '../../context'; import { FocusToggleIcon, UnfocusToggleIcon } from '../../assets/icons'; import { useFocusToggle } from '../../hooks'; -import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'; /** @public */ export interface FocusToggleProps extends React.ButtonHTMLAttributes { - trackRef?: TrackReferenceOrPlaceholder; - /** @deprecated This parameter will be removed in a future version use `trackRef` instead. */ - trackSource?: Track.Source; - /** @deprecated This parameter will be removed in a future version use `trackRef` instead. */ + trackSource: Track.Source; participant?: Participant; } @@ -25,15 +21,8 @@ export interface FocusToggleProps extends React.ButtonHTMLAttributes diff --git a/packages/react/src/components/participant/ParticipantTile.tsx b/packages/react/src/components/participant/ParticipantTile.tsx index 41ae09ba7..390ef6768 100644 --- a/packages/react/src/components/participant/ParticipantTile.tsx +++ b/packages/react/src/components/participant/ParticipantTile.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import type { Participant, TrackPublication } from 'livekit-client'; import { Track } from 'livekit-client'; import type { ParticipantClickEvent, TrackReferenceOrPlaceholder } from '@livekit/components-core'; -import { isTrackReferencePinned } from '@livekit/components-core'; +import { isParticipantSourcePinned } from '@livekit/components-core'; import { ConnectionQualityIndicator } from './ConnectionQualityIndicator'; import { ParticipantName } from './ParticipantName'; import { TrackMutedIndicator } from './TrackMutedIndicator'; @@ -68,14 +68,11 @@ export function ParticipantTile({ ...htmlProps }: ParticipantTileProps) { const p = useEnsureParticipant(participant); - const initialTrackRef: TrackReferenceOrPlaceholder = React.useMemo(() => { - return { - participant: p, - source, - publication, - }; - }, [p, publication, source]); - const trackRef: TrackReferenceOrPlaceholder = useMaybeTrackContext() ?? initialTrackRef; + const trackRef: TrackReferenceOrPlaceholder = useMaybeTrackContext() ?? { + participant: p, + source, + publication, + }; const { elementProps } = useParticipantTile({ participant: trackRef.participant, @@ -95,12 +92,12 @@ export function ParticipantTile({ !subscribed && layoutContext && layoutContext.pin.dispatch && - isTrackReferencePinned(trackRef, layoutContext.pin.state) + isParticipantSourcePinned(trackRef.participant, trackRef.source, layoutContext.pin.state) ) { layoutContext.pin.dispatch({ msg: 'clear_pin' }); } }, - [trackRef, layoutContext], + [trackRef.participant, layoutContext, trackRef.source], ); return ( @@ -151,7 +148,7 @@ export function ParticipantTile({ )} - + ); diff --git a/packages/react/src/hooks/useFocusToggle.ts b/packages/react/src/hooks/useFocusToggle.ts index 8c9e849b6..9770e4e6b 100644 --- a/packages/react/src/hooks/useFocusToggle.ts +++ b/packages/react/src/hooks/useFocusToggle.ts @@ -1,9 +1,4 @@ -import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'; -import { - setupFocusToggle, - isTrackReferencePinned, - isTrackReference, -} from '@livekit/components-core'; +import { setupFocusToggle, isTrackReferencePinned } from '@livekit/components-core'; import type { Track, Participant } from 'livekit-client'; import { useEnsureParticipant, useMaybeLayoutContext } from '../context'; import { mergeProps } from '../mergeProps'; @@ -11,40 +6,28 @@ import * as React from 'react'; /** @public */ export interface UseFocusToggleProps { - trackRef?: TrackReferenceOrPlaceholder; - /** @deprecated This parameter will be removed in a future version use `trackRef` instead. */ - trackSource?: Track.Source; - /** @deprecated This parameter will be removed in a future version use `trackRef` instead. */ - participant?: Participant; props: React.ButtonHTMLAttributes; + trackSource: Track.Source; + participant?: Participant; } /** @public */ -export function useFocusToggle({ trackRef, trackSource, participant, props }: UseFocusToggleProps) { +export function useFocusToggle({ trackSource, participant, props }: UseFocusToggleProps) { const p = useEnsureParticipant(participant); - if (!trackRef && !trackSource) { - throw new Error('trackRef or trackSource must be defined.'); - } const layoutContext = useMaybeLayoutContext(); const { className } = React.useMemo(() => setupFocusToggle(), []); const inFocus: boolean = React.useMemo(() => { - if (trackRef) { - return isTrackReferencePinned(trackRef, layoutContext?.pin.state); - } else if (trackSource) { - const track = p.getTrack(trackSource); - if (layoutContext?.pin.state && track) { - return isTrackReferencePinned( - { participant: p, source: trackSource, publication: track }, - layoutContext.pin.state, - ); - } else { - return false; - } + const track = p.getTrack(trackSource); + if (layoutContext?.pin.state && track) { + return isTrackReferencePinned( + { participant: p, source: trackSource, publication: track }, + layoutContext.pin.state, + ); } else { - throw new Error('trackRef or trackSource and participant must be defined.'); + return false; } - }, [trackRef, layoutContext?.pin.state, p, trackSource]); + }, [p, trackSource, layoutContext]); const mergedProps = React.useMemo( () => @@ -55,39 +38,26 @@ export function useFocusToggle({ trackRef, trackSource, participant, props }: Us props.onClick?.(event); // Set or clear focus based on current focus state. - if (trackRef && isTrackReference(trackRef)) { + const track = p.getTrack(trackSource); + if (layoutContext?.pin.dispatch && track) { if (inFocus) { - layoutContext?.pin.dispatch?.({ + layoutContext.pin.dispatch({ msg: 'clear_pin', }); } else { - layoutContext?.pin.dispatch?.({ + layoutContext.pin.dispatch({ msg: 'set_pin', - trackReference: trackRef, + trackReference: { + participant: p, + publication: track, + source: track.source, + }, }); } - } else if (trackSource) { - const track = p.getTrack(trackSource); - if (layoutContext?.pin.dispatch && track) { - if (inFocus) { - layoutContext.pin.dispatch({ - msg: 'clear_pin', - }); - } else { - layoutContext.pin.dispatch({ - msg: 'set_pin', - trackReference: { - participant: p, - publication: track, - source: track.source, - }, - }); - } - } } }, }), - [props, className, trackRef, trackSource, inFocus, layoutContext?.pin, p], + [props, className, p, trackSource, inFocus, layoutContext], ); return { mergedProps, inFocus };