diff --git a/react/features/filmstrip/functions.any.ts b/react/features/filmstrip/functions.any.ts index 976a2f2783..b567df876f 100644 --- a/react/features/filmstrip/functions.any.ts +++ b/react/features/filmstrip/functions.any.ts @@ -73,32 +73,33 @@ export function updateRemoteParticipants(store: IStore, force?: boolean, partici for (const screenshare of screenShareParticipants) { const ownerId = getVirtualScreenshareParticipantOwnerId(screenshare); + remoteParticipants.delete(ownerId); + remoteParticipants.delete(screenshare); speakers.delete(ownerId); } - // Calculate the number of slots available for active speakers and then sort them alphabetically to ensure - // consistent order. - const numberOfActiveSpeakerSlots - = visibleRemoteParticipants.size - screenShareParticipants.length - sharedVideos.length; - const activeSpeakersDisplayed = _takeFirstN(speakers, numberOfActiveSpeakerSlots) - .sort((a: string, b: string) => { - return (getParticipantById(state, a)?.name ?? defaultRemoteDisplayName) - .localeCompare(getParticipantById(state, b)?.name ?? defaultRemoteDisplayName); - }); - for (const sharedVideo of sharedVideos) { remoteParticipants.delete(sharedVideo); } for (const speaker of speakers.keys()) { remoteParticipants.delete(speaker); } + + // Calculate the number of slots available for active speakers and then sort them alphabetically to ensure + // consistent order. + const numberOfActiveSpeakerSlots + = visibleRemoteParticipants.size - (screenShareParticipants.length * 2) - sharedVideos.length; + const activeSpeakersDisplayed = _takeFirstN(speakers, numberOfActiveSpeakerSlots) + .sort((a: string, b: string) => { + return (getParticipantById(state, a)?.name ?? defaultRemoteDisplayName) + .localeCompare(getParticipantById(state, b)?.name ?? defaultRemoteDisplayName); + }); + const participantsWithScreenShare = screenShareParticipants.reduce((acc, screenshare) => { const ownerId = getVirtualScreenshareParticipantOwnerId(screenshare); acc.push(ownerId); acc.push(screenshare); - remoteParticipants.delete(ownerId); - remoteParticipants.delete(screenshare); return acc; }, []); diff --git a/react/features/filmstrip/subscriber.any.ts b/react/features/filmstrip/subscriber.any.ts index b93d18aaa2..fb5f3e8d3d 100644 --- a/react/features/filmstrip/subscriber.any.ts +++ b/react/features/filmstrip/subscriber.any.ts @@ -1,4 +1,3 @@ -import { getParticipantById } from '../base/participants/functions'; import StateListenerRegistry from '../base/redux/StateListenerRegistry'; import { isFilmstripScrollVisible, updateRemoteParticipants } from './functions'; @@ -26,15 +25,7 @@ StateListenerRegistry.register( */ StateListenerRegistry.register( /* selector */ state => state['features/base/participants'].dominantSpeaker, - /* listener */ (dominantSpeaker, store) => { - const { visibleRemoteParticipants } = store.getState()['features/filmstrip']; - const dominant = getParticipantById(store.getState(), dominantSpeaker); - - // Only update the remote participants if the dominant speaker is not currently visible. - if (!dominant?.local && !visibleRemoteParticipants.has(dominantSpeaker)) { - updateRemoteParticipants(store); - } - }); + /* listener */ (dominantSpeaker, store) => updateRemoteParticipants(store)); /** * Listens for changes in the filmstrip scroll visibility. diff --git a/tests/specs/media/activeSpeaker.spec.ts b/tests/specs/media/activeSpeaker.spec.ts index 43686a5ffb..92153e42af 100644 --- a/tests/specs/media/activeSpeaker.spec.ts +++ b/tests/specs/media/activeSpeaker.spec.ts @@ -1,6 +1,6 @@ import type { Participant } from '../../helpers/Participant'; import { setTestProperties } from '../../helpers/TestProperties'; -import { checkForScreensharingTile, ensureThreeParticipants, hangupAllParticipants } from '../../helpers/participants'; +import { ensureThreeParticipants } from '../../helpers/participants'; import { muteAudioAndCheck } from '../helpers/mute'; setTestProperties(__filename, { @@ -159,115 +159,6 @@ describe('Active speaker', () => { await p1.getToolbar().clickAudioMuteButton(); }); - - it('testRemoteTilesVisibleWhenRemoteStartsScreenshare', async () => { - await hangupAllParticipants(); - await ensureThreeParticipants(); - - const { p1, p2, p3 } = ctx; - const p2EndpointId = await p2.getEndpointId(); - const p3EndpointId = await p3.getEndpointId(); - - // Exit tile view on p1 - await p1.getToolbar().clickExitTileViewButton(); - await p1.waitForTileViewDisplayed(true); - - // Mute all participants - await muteAudioAndCheck(p1, p2); - await muteAudioAndCheck(p2, p1); - await muteAudioAndCheck(p3, p1); - - // Verify both p2 and p3 are visible before screenshare - await p1.driver.$(`//span[@id='participant_${p2EndpointId}']`).waitForDisplayed({ - timeout: 3_000, - timeoutMsg: 'P2 tile should be visible before screenshare' - }); - await p1.driver.$(`//span[@id='participant_${p3EndpointId}']`).waitForDisplayed({ - timeout: 3_000, - timeoutMsg: 'P3 tile should be visible before screenshare' - }); - - // Unmute p3 to make them dominant speaker. - await p3.getToolbar().clickAudioUnmuteButton(); - await p1.waitForParticipantOnLargeVideo( - p3EndpointId, - 'P3 should be dominant speaker on P1 before screenshare' - ); - await p3.getToolbar().clickAudioMuteButton(); - - // p2 starts screensharing and becomes dominant speaker - await p2.getToolbar().clickDesktopSharingButton(); - await p2.getToolbar().clickAudioUnmuteButton(); - - // Check screenshare tiles are created - await checkForScreensharingTile(p2, p1); - await checkForScreensharingTile(p2, p2); - - // Wait for p2 to be on large video on p1 - await p1.waitForParticipantOnLargeVideo( - `${p2EndpointId}-v1`, - 'P2 screenshare should be on large video on P1', - 10_000 - ); - - // Verify that both p2 and p3 camera tiles remain visible in filmstrip - // Even though p2 is screensharing, their camera tile should still be visible - await p1.driver.$(`//span[@id='participant_${p2EndpointId}']`).waitForDisplayed({ - timeout: 3_000, - timeoutMsg: 'P2 camera tile should remain visible in filmstrip during their screenshare' - }); - await p1.driver.$(`//span[@id='participant_${p3EndpointId}']`).waitForDisplayed({ - timeout: 3_000, - timeoutMsg: 'P3 tile should remain visible in filmstrip during P2 screenshare' - }); - - // Check that there are no gaps in the filmstrip when remote starts screensharing - await p1.getFilmstrip().assertNoGapsInFilmstrip(); - await p3.getFilmstrip().assertNoGapsInFilmstrip(); - }); - - it('testFilmstripTilesWithMultipleScreenshares', async () => { - await hangupAllParticipants(); - await ensureThreeParticipants(); - - const { p1, p2, p3 } = ctx; - const p1EndpointId = await p1.getEndpointId(); - const p2EndpointId = await p2.getEndpointId(); - - // Exit tile view on all participants - await p1.getToolbar().clickExitTileViewButton(); - await p1.waitForTileViewDisplayed(true); - - // Mute all participants - await muteAudioAndCheck(p1, p2); - await muteAudioAndCheck(p2, p1); - await muteAudioAndCheck(p3, p1); - - // p1 starts screensharing - await p1.getToolbar().clickDesktopSharingButton(); - await checkForScreensharingTile(p1, p2); - - // p2 also starts screensharing - await p2.getToolbar().clickDesktopSharingButton(); - await checkForScreensharingTile(p2, p1); - - // Verify all camera tiles are still visible on p3's view - await p3.driver.$(`//span[@id='participant_${p1EndpointId}']`).waitForDisplayed({ - timeout: 3_000, - timeoutMsg: 'P1 camera tile should be visible on P3 during multiple screenshares' - }); - await p3.driver.$(`//span[@id='participant_${p2EndpointId}']`).waitForDisplayed({ - timeout: 3_000, - timeoutMsg: 'P2 camera tile should be visible on P3 during multiple screenshares' - }); - - // Verify screenshare tiles are present - await checkForScreensharingTile(p1, p3); - await checkForScreensharingTile(p2, p3); - - // Check that there are no gaps in the filmstrip with multiple screenshares - await p3.getFilmstrip().assertNoGapsInFilmstrip(); - }); }); /** diff --git a/tests/specs/media/desktopSharing.spec.ts b/tests/specs/media/desktopSharing.spec.ts index be6da1b11c..1691df3791 100644 --- a/tests/specs/media/desktopSharing.spec.ts +++ b/tests/specs/media/desktopSharing.spec.ts @@ -67,21 +67,7 @@ describe('Desktop sharing', () => { // Check if a remote screen share tile is created on all participants. await checkForScreensharingTile(p2, p1); await checkForScreensharingTile(p2, p2); - await checkForScreensharingTile(p2, p3); - - // Verify that all participant camera tiles remain visible in filmstrip - const p2EndpointId = await p2.getEndpointId(); - const p3EndpointId = await p3.getEndpointId(); - - // Check from p1's perspective that camera tiles are visible - await p1.driver.$(`//span[@id='participant_${p2EndpointId}']`).waitForDisplayed({ - timeout: 3_000, - timeoutMsg: 'P2 camera tile should be visible on P1 during screenshare' - }); - await p1.driver.$(`//span[@id='participant_${p3EndpointId}']`).waitForDisplayed({ - timeout: 3_000, - timeoutMsg: 'P3 camera tile should be visible on P1 during P2 screenshare' - }); + await checkForScreensharingTile(p2, p2); await p1.getFilmstrip().assertNoGapsInFilmstrip(); await p3.getFilmstrip().assertNoGapsInFilmstrip();