diff --git a/react/features/base/tracks/middleware.any.ts b/react/features/base/tracks/middleware.any.ts index 5e92f7b17d..4b14b34573 100644 --- a/react/features/base/tracks/middleware.any.ts +++ b/react/features/base/tracks/middleware.any.ts @@ -33,7 +33,6 @@ import { isUserInteractionRequiredForUnmute, setTrackMuted } from './functions'; -import './subscriber'; /** * Middleware that captures LIB_DID_DISPOSE and LIB_DID_INIT actions and, diff --git a/react/features/base/tracks/middleware.web.ts b/react/features/base/tracks/middleware.web.ts index dd332aeb46..c737a574c5 100644 --- a/react/features/base/tracks/middleware.web.ts +++ b/react/features/base/tracks/middleware.web.ts @@ -38,6 +38,7 @@ import { import { ITrack, ITrackOptions } from './types'; import './middleware.any'; +import './subscriber.web'; /** * Middleware that captures LIB_DID_DISPOSE and LIB_DID_INIT actions and, diff --git a/react/features/base/tracks/subscriber.ts b/react/features/base/tracks/subscriber.ts deleted file mode 100644 index e646697c31..0000000000 --- a/react/features/base/tracks/subscriber.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { isEqual, sortBy } from 'lodash-es'; - -import { MEDIA_TYPE } from '../media/constants'; -import { getScreenshareParticipantIds } from '../participants/functions'; -import StateListenerRegistry from '../redux/StateListenerRegistry'; - -import { isLocalTrackMuted } from './functions'; - -/** - * Notifies when the list of currently sharing participants changes. - */ -StateListenerRegistry.register( - /* selector */ state => getScreenshareParticipantIds(state), - /* listener */ (participantIDs, store, previousParticipantIDs) => { - if (typeof APP !== 'object') { - return; - } - - if (!isEqual(sortBy(participantIDs), sortBy(previousParticipantIDs))) { - APP.API.notifySharingParticipantsChanged(participantIDs); - } - } -); - - -/** - * Notifies when the local video mute state changes. - */ -StateListenerRegistry.register( - /* selector */ state => isLocalTrackMuted(state['features/base/tracks'], MEDIA_TYPE.VIDEO), - /* listener */ (muted, store, previousMuted) => { - if (typeof APP !== 'object') { - return; - } - - if (muted !== previousMuted) { - APP.API.notifyVideoMutedStatusChanged(muted); - } - } -); diff --git a/react/features/base/tracks/subscriber.web.ts b/react/features/base/tracks/subscriber.web.ts new file mode 100644 index 0000000000..1fba331c3e --- /dev/null +++ b/react/features/base/tracks/subscriber.web.ts @@ -0,0 +1,52 @@ +import { isEqual, sortBy } from 'lodash-es'; + +// @ts-expect-error +import VideoLayout from '../../../../modules/UI/videolayout/VideoLayout'; +import { getAutoPinSetting } from '../../video-layout/functions.any'; +import { MEDIA_TYPE } from '../media/constants'; +import { getScreenshareParticipantIds } from '../participants/functions'; +import StateListenerRegistry from '../redux/StateListenerRegistry'; + +import { isLocalTrackMuted } from './functions'; + +/** + * Notifies when the list of currently sharing participants changes. + */ +StateListenerRegistry.register( + /* selector */ state => getScreenshareParticipantIds(state), + /* listener */ (participantIDs, store, previousParticipantIDs) => { + if (getAutoPinSetting() && participantIDs !== previousParticipantIDs) { + const { participantId } = store.getState()['features/large-video']; + + // Check if any new screenshare participants were added + const newParticipants = participantIDs.filter((id: string) => !previousParticipantIDs.includes(id)); + + // If the current large video participant is a new screensharer, update the display. This is needed when + // the track is created much later after the action for auto-pinning is dispatched. This usually happens in + // very large meetings if the screenshare was already ongoing when the participant joined. The track is + // signaled only after the receiver constraints with SS source id is processed by the bridge but the + // auto-pinning action is dispatched when the participant tile is created as soon as the presence is + // received. + if (participantId && newParticipants.includes(participantId)) { + VideoLayout.updateLargeVideo(participantId, true); + } + } + + if (!isEqual(sortBy(participantIDs), sortBy(previousParticipantIDs))) { + APP.API.notifySharingParticipantsChanged(participantIDs); + } + } +); + + +/** + * Notifies when the local video mute state changes. + */ +StateListenerRegistry.register( + /* selector */ state => isLocalTrackMuted(state['features/base/tracks'], MEDIA_TYPE.VIDEO), + /* listener */ (muted, store, previousMuted) => { + if (muted !== previousMuted) { + APP.API.notifyVideoMutedStatusChanged(muted); + } + } +);