ref(participants) use enum type to store fake participants (#12316)
This commit is contained in:
parent
be7f2643df
commit
d0c22806ec
|
@ -19,7 +19,9 @@ import { JitsiTrackEvents } from '../../../react/features/base/lib-jitsi-meet';
|
|||
import { VIDEO_TYPE } from '../../../react/features/base/media';
|
||||
import {
|
||||
getParticipantById,
|
||||
getParticipantDisplayName
|
||||
getParticipantDisplayName,
|
||||
isLocalScreenshareParticipant,
|
||||
isScreenShareParticipant
|
||||
} from '../../../react/features/base/participants';
|
||||
import {
|
||||
getVideoTrackByParticipant,
|
||||
|
@ -265,8 +267,7 @@ export default class LargeVideoManager {
|
|||
let isVideoRenderable;
|
||||
|
||||
if (getSourceNameSignalingFeatureFlag(state)) {
|
||||
const tracks = state['features/base/tracks'];
|
||||
const videoTrack = getVideoTrackByParticipant(tracks, participant);
|
||||
const videoTrack = getVideoTrackByParticipant(state, participant);
|
||||
|
||||
// Remove track streaming status listener from the old track and add it to the new track,
|
||||
// in order to stop updating track streaming status for the old track and start it for the new track.
|
||||
|
@ -292,7 +293,10 @@ export default class LargeVideoManager {
|
|||
const streamingStatusActive = isTrackStreamingStatusActive(videoTrack);
|
||||
|
||||
isVideoRenderable = !isVideoMuted
|
||||
&& (APP.conference.isLocalId(id) || participant?.isLocalScreenShare || streamingStatusActive);
|
||||
&& (APP.conference.isLocalId(id)
|
||||
|| isLocalScreenshareParticipant(participant)
|
||||
|| streamingStatusActive
|
||||
);
|
||||
this.videoTrack?.jitsiTrack?.getVideoType() === VIDEO_TYPE.DESKTOP
|
||||
&& logger.debug(`Remote track ${videoTrack?.jitsiTrack}, isVideoMuted=${isVideoMuted},`
|
||||
+ ` streamingStatusActive=${streamingStatusActive}, isVideoRenderable=${isVideoRenderable}`);
|
||||
|
@ -309,7 +313,7 @@ export default class LargeVideoManager {
|
|||
// progress.
|
||||
const legacyScreenshare = getMultipleVideoSupportFeatureFlag(state)
|
||||
&& videoType === VIDEO_TYPE.DESKTOP
|
||||
&& !participant.isVirtualScreenshareParticipant;
|
||||
&& !isScreenShareParticipant(participant);
|
||||
|
||||
const showAvatar
|
||||
= isVideoContainer
|
||||
|
@ -329,11 +333,10 @@ export default class LargeVideoManager {
|
|||
if ((!shouldDisplayTileView(state) || participant?.pinned) // In theory the tile view may not be
|
||||
// enabled yet when we auto pin the participant.
|
||||
|
||||
&& participant && !participant.local && !participant.isFakeParticipant) {
|
||||
&& participant && !participant.local && !participant.fakeParticipant) {
|
||||
// remote participant only
|
||||
|
||||
const tracks = state['features/base/tracks'];
|
||||
const track = getVideoTrackByParticipant(tracks, participant);
|
||||
const track = getVideoTrackByParticipant(state, participant);
|
||||
|
||||
const isScreenSharing = track?.videoType === 'desktop';
|
||||
|
||||
|
@ -365,8 +368,7 @@ export default class LargeVideoManager {
|
|||
let messageKey;
|
||||
|
||||
if (getSourceNameSignalingFeatureFlag(state)) {
|
||||
const tracks = state['features/base/tracks'];
|
||||
const videoTrack = getVideoTrackByParticipant(tracks, participant);
|
||||
const videoTrack = getVideoTrackByParticipant(state, participant);
|
||||
|
||||
messageKey = isTrackStreamingStatusInactive(videoTrack) ? 'connection.LOW_BANDWIDTH' : null;
|
||||
} else {
|
||||
|
@ -619,8 +621,7 @@ export default class LargeVideoManager {
|
|||
const state = APP.store.getState();
|
||||
|
||||
if (getSourceNameSignalingFeatureFlag(state)) {
|
||||
const tracks = state['features/base/tracks'];
|
||||
const videoTrack = getVideoTrackByParticipant(tracks, participant);
|
||||
const videoTrack = getVideoTrackByParticipant(state, participant);
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
show = !APP.conference.isLocalId(this.id)
|
||||
|
|
|
@ -6,7 +6,9 @@ import { getMultipleVideoSupportFeatureFlag } from '../../../react/features/base
|
|||
import { MEDIA_TYPE, VIDEO_TYPE } from '../../../react/features/base/media';
|
||||
import {
|
||||
getParticipantById,
|
||||
getPinnedParticipant
|
||||
getPinnedParticipant,
|
||||
isScreenShareParticipant,
|
||||
isScreenShareParticipantById
|
||||
} from '../../../react/features/base/participants';
|
||||
import {
|
||||
getTrackByMediaTypeAndParticipant,
|
||||
|
@ -90,12 +92,13 @@ const VideoLayout = {
|
|||
getRemoteVideoType(id) {
|
||||
const state = APP.store.getState();
|
||||
const participant = getParticipantById(state, id);
|
||||
const isScreenShare = isScreenShareParticipantById(state, id);
|
||||
|
||||
if (participant?.isFakeParticipant) {
|
||||
if (participant?.fakeParticipant && !isScreenShare) {
|
||||
return VIDEO_TYPE.CAMERA;
|
||||
}
|
||||
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && isScreenShare) {
|
||||
return VIDEO_TYPE.DESKTOP;
|
||||
}
|
||||
|
||||
|
@ -190,7 +193,7 @@ const VideoLayout = {
|
|||
|
||||
let videoTrack;
|
||||
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(participant)) {
|
||||
videoTrack = getVirtualScreenshareParticipantTrack(tracks, id);
|
||||
} else {
|
||||
videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, id);
|
||||
|
|
|
@ -36,7 +36,7 @@ import {
|
|||
getVirtualScreenshareParticipantOwnerId
|
||||
} from './functions';
|
||||
import logger from './logger';
|
||||
import { Participant } from './types';
|
||||
import { FakeParticipant, Participant } from './types';
|
||||
|
||||
/**
|
||||
* Create an action for when dominant speaker changes.
|
||||
|
@ -386,10 +386,8 @@ export function hiddenParticipantLeft(id: string) {
|
|||
* instance.
|
||||
* @param {Object} participantLeftProps - Other participant properties.
|
||||
* @typedef {Object} participantLeftProps
|
||||
* @param {FakeParticipant|undefined} participantLeftProps.fakeParticipant - The type of fake participant.
|
||||
* @param {boolean} participantLeftProps.isReplaced - Whether the participant is to be replaced in the meeting.
|
||||
* @param {boolean} participantLeftProps.isVirtualScreenshareParticipant - Whether the participant is a
|
||||
* virtual screen share participant.
|
||||
* @param {boolean} participantLeftProps.isFakeParticipant - Whether the participant is a fake participant.
|
||||
*
|
||||
* @returns {{
|
||||
* type: PARTICIPANT_LEFT,
|
||||
|
@ -404,11 +402,9 @@ export function participantLeft(id: string, conference: any, participantLeftProp
|
|||
type: PARTICIPANT_LEFT,
|
||||
participant: {
|
||||
conference,
|
||||
fakeParticipant: participantLeftProps.fakeParticipant,
|
||||
id,
|
||||
isReplaced: participantLeftProps.isReplaced,
|
||||
isVirtualScreenshareParticipant: participantLeftProps.isVirtualScreenshareParticipant,
|
||||
isWhiteboard: participantLeftProps.isWhiteboard,
|
||||
isFakeParticipant: participantLeftProps.isFakeParticipant
|
||||
isReplaced: participantLeftProps.isReplaced
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -538,9 +534,8 @@ export function createVirtualScreenshareParticipant(sourceName: string, local: b
|
|||
|
||||
dispatch(participantJoined({
|
||||
conference: state['features/base/conference'].conference,
|
||||
fakeParticipant: local ? FakeParticipant.LocalScreenShare : FakeParticipant.RemoteScreenShare,
|
||||
id: sourceName,
|
||||
isVirtualScreenshareParticipant: true,
|
||||
isLocalScreenShare: local,
|
||||
name: ownerName
|
||||
}));
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ import { connect } from '../../redux';
|
|||
import { TestHint } from '../../testing/components';
|
||||
import { getVideoTrackByParticipant } from '../../tracks';
|
||||
import { getParticipantById, shouldRenderParticipantVideo } from '../functions';
|
||||
import { FakeParticipant } from '../types';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
|
@ -31,11 +32,11 @@ type Props = {
|
|||
_connectionStatus: string,
|
||||
|
||||
/**
|
||||
* True if the participant which this component represents is fake.
|
||||
* The type of participant if the participant which this component represents is fake.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_isFakeParticipant: boolean,
|
||||
_fakeParticipant?: FakeParticipant,
|
||||
|
||||
/**
|
||||
* The name of the participant which this component represents.
|
||||
|
@ -174,7 +175,7 @@ class ParticipantView extends Component<Props> {
|
|||
render() {
|
||||
const {
|
||||
_connectionStatus: connectionStatus,
|
||||
_isFakeParticipant,
|
||||
_fakeParticipant,
|
||||
_renderVideo: renderVideo,
|
||||
_videoTrack: videoTrack,
|
||||
disableVideo,
|
||||
|
@ -190,7 +191,7 @@ class ParticipantView extends Component<Props> {
|
|||
? this.props.testHintId
|
||||
: `org.jitsi.meet.Participant#${this.props.participantId}`;
|
||||
|
||||
const renderSharedVideo = _isFakeParticipant && !disableVideo;
|
||||
const renderSharedVideo = _fakeParticipant && !disableVideo;
|
||||
|
||||
return (
|
||||
<Container
|
||||
|
@ -208,7 +209,7 @@ class ParticipantView extends Component<Props> {
|
|||
|
||||
{ renderSharedVideo && <SharedVideo /> }
|
||||
|
||||
{ !_isFakeParticipant && renderVideo
|
||||
{ !_fakeParticipant && renderVideo
|
||||
&& <VideoTrack
|
||||
onPress = { onPress }
|
||||
videoTrack = { videoTrack }
|
||||
|
@ -248,8 +249,7 @@ class ParticipantView extends Component<Props> {
|
|||
function _mapStateToProps(state, ownProps) {
|
||||
const { disableVideo, participantId } = ownProps;
|
||||
const participant = getParticipantById(state, participantId);
|
||||
const tracks = state['features/base/tracks'];
|
||||
const videoTrack = getVideoTrackByParticipant(tracks, participant);
|
||||
const videoTrack = getVideoTrackByParticipant(state, participant);
|
||||
let connectionStatus;
|
||||
let participantName;
|
||||
|
||||
|
@ -257,7 +257,7 @@ function _mapStateToProps(state, ownProps) {
|
|||
_connectionStatus:
|
||||
connectionStatus
|
||||
|| JitsiParticipantConnectionStatus.ACTIVE,
|
||||
_isFakeParticipant: participant && participant.isFakeParticipant,
|
||||
_fakeParticipant: participant?.fakeParticipant,
|
||||
_participantName: participantName,
|
||||
_renderVideo: shouldRenderParticipantVideo(state, participantId) && !disableVideo,
|
||||
_videoTrack: videoTrack
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// @ts-ignore
|
||||
import { getGravatarURL } from '@jitsi/js-utils/avatar';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { IState, IStore } from '../../app/types';
|
||||
// @ts-ignore
|
||||
import { isStageFilmstripAvailable } from '../../filmstrip/functions';
|
||||
import { IStateful } from '../app/types';
|
||||
|
@ -24,7 +24,7 @@ import {
|
|||
} from './constants';
|
||||
// @ts-ignore
|
||||
import { preloadImage } from './preloadImage';
|
||||
import { Participant } from './types';
|
||||
import { FakeParticipant, Participant } from './types';
|
||||
|
||||
/**
|
||||
* Temp structures for avatar urls to be checked/preloaded.
|
||||
|
@ -34,10 +34,10 @@ const AVATAR_CHECKED_URLS = new Map();
|
|||
/* eslint-disable arrow-body-style, no-unused-vars */
|
||||
const AVATAR_CHECKER_FUNCTIONS = [
|
||||
(participant: Participant) => {
|
||||
return participant?.isJigasi ? JIGASI_PARTICIPANT_ICON : null;
|
||||
return isJigasiParticipant(participant) ? JIGASI_PARTICIPANT_ICON : null;
|
||||
},
|
||||
(participant: Participant) => {
|
||||
return participant?.isWhiteboard ? WHITEBOARD_PARTICIPANT_ICON : null;
|
||||
return isWhiteboardParticipant(participant) ? WHITEBOARD_PARTICIPANT_ICON : null;
|
||||
},
|
||||
(participant: Participant) => {
|
||||
return participant?.avatarURL ? participant.avatarURL : null;
|
||||
|
@ -115,7 +115,7 @@ export function getActiveSpeakersToBeDisplayed(stateful: IStateful) {
|
|||
}
|
||||
}
|
||||
|
||||
// Remove shared video from the count.
|
||||
// Remove fake participants from the count.
|
||||
if (fakeParticipants) {
|
||||
availableSlotsForActiveSpeakers -= fakeParticipants.size;
|
||||
}
|
||||
|
@ -301,6 +301,69 @@ export function getFakeParticipants(stateful: IStateful) {
|
|||
return toState(stateful)['features/base/participants'].fakeParticipants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the fake participant is Jigasi.
|
||||
*
|
||||
* @param {Participant|undefined} participant - The participant entity.
|
||||
* @returns {boolean} - True if it's a Jigasi participant.
|
||||
*/
|
||||
function isJigasiParticipant(participant?: Participant): boolean {
|
||||
return participant?.fakeParticipant === FakeParticipant.Jigasi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the fake participant is a local screenshare.
|
||||
*
|
||||
* @param {Participant|undefined} participant - The participant entity.
|
||||
* @returns {boolean} - True if it's a local screenshare participant.
|
||||
*/
|
||||
export function isLocalScreenshareParticipant(participant?: Participant): boolean {
|
||||
return participant?.fakeParticipant === FakeParticipant.LocalScreenShare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the fake participant is a remote screenshare.
|
||||
*
|
||||
* @param {Participant|undefined} participant - The participant entity.
|
||||
* @returns {boolean} - True if it's a remote screenshare participant.
|
||||
*/
|
||||
export function isRemoteScreenshareParticipant(participant?: Participant): boolean {
|
||||
return participant?.fakeParticipant === FakeParticipant.RemoteScreenShare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the fake participant is of local or virtual screenshare type.
|
||||
*
|
||||
* @param {IState} state - The (whole) redux state, or redux's.
|
||||
* @param {string|undefined} participantId - The participant id.
|
||||
* @returns {boolean} - True if it's one of the two.
|
||||
*/
|
||||
export function isScreenShareParticipantById(state: IState, participantId?: string): boolean {
|
||||
const participant = getParticipantByIdOrUndefined(state, participantId);
|
||||
|
||||
return isScreenShareParticipant(participant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the fake participant is of local or virtual screenshare type.
|
||||
*
|
||||
* @param {Participant|undefined} participant - The participant entity.
|
||||
* @returns {boolean} - True if it's one of the two.
|
||||
*/
|
||||
export function isScreenShareParticipant(participant?: Participant): boolean {
|
||||
return isLocalScreenshareParticipant(participant) || isRemoteScreenshareParticipant(participant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the fake participant is a whiteboard.
|
||||
*
|
||||
* @param {Participant|undefined} participant - The participant entity.
|
||||
* @returns {boolean} - True if it's a whiteboard participant.
|
||||
*/
|
||||
export function isWhiteboardParticipant(participant?: Participant): boolean {
|
||||
return participant?.fakeParticipant === FakeParticipant.Whiteboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a count of the known remote participants in the passed in redux state.
|
||||
*
|
||||
|
@ -349,15 +412,16 @@ export function getParticipantCountWithFake(stateful: IStateful) {
|
|||
* @returns {string}
|
||||
*/
|
||||
export function getParticipantDisplayName(stateful: IStateful, id: string): string {
|
||||
const participant = getParticipantById(stateful, id);
|
||||
const state = toState(stateful);
|
||||
const participant = getParticipantById(state, id);
|
||||
const {
|
||||
defaultLocalDisplayName,
|
||||
defaultRemoteDisplayName
|
||||
} = toState(stateful)['features/base/config'];
|
||||
} = state['features/base/config'];
|
||||
|
||||
if (participant) {
|
||||
if (participant.isVirtualScreenshareParticipant) {
|
||||
return getScreenshareParticipantDisplayName(stateful, id);
|
||||
if (isScreenShareParticipant(participant)) {
|
||||
return getScreenshareParticipantDisplayName(state, id);
|
||||
}
|
||||
|
||||
if (participant.name) {
|
||||
|
@ -546,7 +610,7 @@ export function shouldRenderParticipantVideo(stateful: IStateful, id: string) {
|
|||
}
|
||||
|
||||
/* First check if we have an unmuted video track. */
|
||||
const videoTrack = getVideoTrackByParticipant(state['features/base/tracks'], participant);
|
||||
const videoTrack = getVideoTrackByParticipant(state, participant);
|
||||
|
||||
if (!shouldRenderVideoTrack(videoTrack, /* waitForVideoStarted */ false)) {
|
||||
return false;
|
||||
|
|
|
@ -74,11 +74,13 @@ import {
|
|||
getRaiseHandsQueue,
|
||||
getRemoteParticipants,
|
||||
hasRaisedHand,
|
||||
isLocalParticipantModerator
|
||||
isLocalParticipantModerator,
|
||||
isScreenShareParticipant,
|
||||
isWhiteboardParticipant
|
||||
} from './functions';
|
||||
import logger from './logger';
|
||||
import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds';
|
||||
import { IJitsiParticipant } from './types';
|
||||
import { FakeParticipant, IJitsiParticipant } from './types';
|
||||
|
||||
import './subscriber';
|
||||
|
||||
|
@ -267,19 +269,19 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
}
|
||||
|
||||
case PARTICIPANT_JOINED: {
|
||||
const { isVirtualScreenshareParticipant, isWhiteboard } = action.participant;
|
||||
|
||||
// Do not play sounds when a virtual participant tile is created for screenshare.
|
||||
(!isVirtualScreenshareParticipant && !isWhiteboard) && _maybePlaySounds(store, action);
|
||||
// Do not play sounds when a screenshare or whiteboard participant tile is created for screenshare.
|
||||
(!isScreenShareParticipant(action.participant)
|
||||
&& !isWhiteboardParticipant(action.participant)
|
||||
) && _maybePlaySounds(store, action);
|
||||
|
||||
return _participantJoinedOrUpdated(store, next, action);
|
||||
}
|
||||
|
||||
case PARTICIPANT_LEFT: {
|
||||
const { isVirtualScreenshareParticipant, isWhiteboard } = action.participant;
|
||||
|
||||
// Do not play sounds when a tile for screenshare is removed.
|
||||
(!isVirtualScreenshareParticipant && !isWhiteboard) && _maybePlaySounds(store, action);
|
||||
// Do not play sounds when a tile for screenshare or whiteboard is removed.
|
||||
(!isScreenShareParticipant(action.participant)
|
||||
&& !isWhiteboardParticipant(action.participant)
|
||||
) && _maybePlaySounds(store, action);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -436,7 +438,7 @@ StateListenerRegistry.register(
|
|||
store.dispatch(participantUpdated({
|
||||
conference,
|
||||
id: participant.getId(),
|
||||
isJigasi: value
|
||||
fakeParticipant: value ? FakeParticipant.Jigasi : undefined
|
||||
})),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
'features_screen-sharing': (participant: IJitsiParticipant, value: string) =>
|
||||
|
|
|
@ -18,7 +18,12 @@ import {
|
|||
SET_LOADABLE_AVATAR_URL
|
||||
} from './actionTypes';
|
||||
import { LOCAL_PARTICIPANT_DEFAULT_ID, PARTICIPANT_ROLE } from './constants';
|
||||
import { isParticipantModerator } from './functions';
|
||||
import {
|
||||
isLocalScreenshareParticipant,
|
||||
isParticipantModerator,
|
||||
isRemoteScreenshareParticipant,
|
||||
isScreenShareParticipant
|
||||
} from './functions';
|
||||
import { LocalParticipant, Participant } from './types';
|
||||
|
||||
/**
|
||||
|
@ -241,10 +246,8 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
|
|||
case PARTICIPANT_JOINED: {
|
||||
const participant = _participantJoined(action);
|
||||
const {
|
||||
fakeParticipant,
|
||||
id,
|
||||
isFakeParticipant,
|
||||
isLocalScreenShare,
|
||||
isVirtualScreenshareParticipant,
|
||||
name,
|
||||
pinned
|
||||
} = participant;
|
||||
|
@ -281,7 +284,7 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
|
|||
};
|
||||
}
|
||||
|
||||
if (isLocalScreenShare) {
|
||||
if (isLocalScreenshareParticipant(participant)) {
|
||||
return {
|
||||
...state,
|
||||
localScreenShare: participant
|
||||
|
@ -300,7 +303,7 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
|
|||
// The sort order of participants is preserved since Map remembers the original insertion order of the keys.
|
||||
state.sortedRemoteParticipants = new Map(sortedRemoteParticipants);
|
||||
|
||||
if (isVirtualScreenshareParticipant) {
|
||||
if (isRemoteScreenshareParticipant(participant)) {
|
||||
const sortedRemoteVirtualScreenshareParticipants = [ ...state.sortedRemoteVirtualScreenshareParticipants ];
|
||||
|
||||
sortedRemoteVirtualScreenshareParticipants.push([ id, name ?? '' ]);
|
||||
|
@ -308,7 +311,8 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
|
|||
|
||||
state.sortedRemoteVirtualScreenshareParticipants = new Map(sortedRemoteVirtualScreenshareParticipants);
|
||||
}
|
||||
if (isFakeParticipant) {
|
||||
// Exclude the screenshare participant from the fake participant count to avoid duplicates.
|
||||
if (fakeParticipant && !isScreenShareParticipant(participant)) {
|
||||
state.fakeParticipants.set(id, participant);
|
||||
}
|
||||
|
||||
|
@ -509,12 +513,8 @@ function _participantJoined({ participant }: { participant: Participant; }) {
|
|||
connectionStatus,
|
||||
dominantSpeaker,
|
||||
email,
|
||||
isFakeParticipant,
|
||||
isVirtualScreenshareParticipant,
|
||||
isLocalScreenShare,
|
||||
fakeParticipant,
|
||||
isReplacing,
|
||||
isJigasi,
|
||||
isWhiteboard,
|
||||
loadableAvatarUrl,
|
||||
local,
|
||||
name,
|
||||
|
@ -543,13 +543,9 @@ function _participantJoined({ participant }: { participant: Participant; }) {
|
|||
connectionStatus,
|
||||
dominantSpeaker: dominantSpeaker || false,
|
||||
email,
|
||||
fakeParticipant,
|
||||
id,
|
||||
isFakeParticipant,
|
||||
isVirtualScreenshareParticipant,
|
||||
isLocalScreenShare,
|
||||
isReplacing,
|
||||
isJigasi,
|
||||
isWhiteboard,
|
||||
loadableAvatarUrl,
|
||||
local: local || false,
|
||||
name,
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
import StateListenerRegistry from '../redux/StateListenerRegistry';
|
||||
|
||||
import { createVirtualScreenshareParticipant, participantLeft } from './actions';
|
||||
import { FakeParticipant } from './types';
|
||||
|
||||
StateListenerRegistry.register(
|
||||
/* selector */ state => state['features/base/tracks'],
|
||||
|
@ -56,8 +57,8 @@ function _updateScreenshareParticipants({ getState, dispatch }: IStore) {
|
|||
|
||||
if (localScreenShare && !newLocalSceenshareSourceName) {
|
||||
dispatch(participantLeft(localScreenShare.id, conference, {
|
||||
isReplaced: undefined,
|
||||
isVirtualScreenshareParticipant: true
|
||||
fakeParticipant: FakeParticipant.LocalScreenShare,
|
||||
isReplaced: undefined
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +68,8 @@ function _updateScreenshareParticipants({ getState, dispatch }: IStore) {
|
|||
|
||||
if (removedScreenshareSourceNames.length) {
|
||||
removedScreenshareSourceNames.forEach(id => dispatch(participantLeft(id, conference, {
|
||||
isReplaced: undefined,
|
||||
isVirtualScreenshareParticipant: true
|
||||
fakeParticipant: FakeParticipant.RemoteScreenShare,
|
||||
isReplaced: undefined
|
||||
})));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
export enum FakeParticipant {
|
||||
Jigasi = 'Jigasi',
|
||||
LocalScreenShare = 'LocalScreenShare',
|
||||
RemoteScreenShare = 'RemoteScreenShare',
|
||||
SharedVideo = 'SharedVideo',
|
||||
Whiteboard = 'Whiteboard'
|
||||
}
|
||||
|
||||
export interface Participant {
|
||||
avatarURL?: string;
|
||||
botType?: string;
|
||||
|
@ -8,18 +16,14 @@ export interface Participant {
|
|||
e2eeEnabled?: boolean;
|
||||
e2eeSupported?: boolean;
|
||||
email?: string;
|
||||
fakeParticipant?: FakeParticipant;
|
||||
features?: {
|
||||
'screen-sharing'?: boolean | string;
|
||||
};
|
||||
getId?: Function;
|
||||
id: string;
|
||||
isFakeParticipant?: boolean;
|
||||
isJigasi?: boolean;
|
||||
isLocalScreenShare?: boolean;
|
||||
isReplaced?: boolean;
|
||||
isReplacing?: number;
|
||||
isVirtualScreenshareParticipant?: boolean;
|
||||
isWhiteboard?: boolean;
|
||||
jwtId?: string;
|
||||
loadableAvatarUrl?: string;
|
||||
loadableAvatarUrlUseCORS?: boolean;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { IState, IStore } from '../../app/types';
|
||||
import { getMultipleVideoSupportFeatureFlag } from '../config/functions.any';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE } from '../media/constants';
|
||||
import { getParticipantById } from '../participants/functions';
|
||||
import { getParticipantById, isScreenShareParticipant } from '../participants/functions';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
import { getTrackByMediaTypeAndParticipant, getVirtualScreenshareParticipantTrack } from '../tracks';
|
||||
|
@ -31,7 +31,7 @@ export function getRemoteVideoType({ getState }: IStore, id: string) {
|
|||
const state = getState();
|
||||
const participant = getParticipantById(state, id);
|
||||
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(participant)) {
|
||||
return VIDEO_TYPE.DESKTOP;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ export function isLargeVideoReceived({ getState }: IStore): boolean {
|
|||
const tracks = state['features/base/tracks'];
|
||||
let videoTrack;
|
||||
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && largeVideoParticipant?.isVirtualScreenshareParticipant) {
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(largeVideoParticipant)) {
|
||||
videoTrack = getVirtualScreenshareParticipantTrack(tracks, largeVideoParticipantId);
|
||||
} else {
|
||||
videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideoParticipantId);
|
||||
|
@ -75,7 +75,7 @@ export function isRemoteVideoReceived({ getState }: IStore, id: string): boolean
|
|||
const participant = getParticipantById(state, id);
|
||||
let videoTrack;
|
||||
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(participant)) {
|
||||
videoTrack = getVirtualScreenshareParticipantTrack(tracks, id);
|
||||
} else {
|
||||
videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, id);
|
||||
|
|
|
@ -8,7 +8,11 @@ import { isMobileBrowser } from '../environment/utils';
|
|||
import JitsiMeetJS, { JitsiTrackErrors, browser } from '../lib-jitsi-meet';
|
||||
import { setAudioMuted } from '../media/actions';
|
||||
import { MEDIA_TYPE, MediaType, VIDEO_TYPE } from '../media/constants';
|
||||
import { getParticipantByIdOrUndefined, getVirtualScreenshareParticipantOwnerId } from '../participants/functions';
|
||||
import {
|
||||
getParticipantByIdOrUndefined,
|
||||
getVirtualScreenshareParticipantOwnerId,
|
||||
isScreenShareParticipant
|
||||
} from '../participants/functions';
|
||||
import { Participant } from '../participants/types';
|
||||
import { toState } from '../redux/functions';
|
||||
import {
|
||||
|
@ -47,7 +51,7 @@ export function isParticipantMediaMuted(participant: Participant, mediaType: Med
|
|||
|
||||
if (participant?.local) {
|
||||
return isLocalTrackMuted(tracks, mediaType);
|
||||
} else if (!participant?.isFakeParticipant) {
|
||||
} else if (!participant?.fakeParticipant) {
|
||||
return isRemoteTrackMuted(tracks, mediaType, participant.id);
|
||||
}
|
||||
|
||||
|
@ -420,19 +424,21 @@ export function getLocalJitsiAudioTrack(state: IState) {
|
|||
/**
|
||||
* Returns track of specified media type for specified participant.
|
||||
*
|
||||
* @param {ITrack[]} tracks - List of all tracks.
|
||||
* @param {IState} state - The redux state.
|
||||
* @param {Participant} participant - Participant Object.
|
||||
* @returns {(Track|undefined)}
|
||||
*/
|
||||
export function getVideoTrackByParticipant(
|
||||
tracks: ITrack[],
|
||||
state: IState,
|
||||
participant?: Participant) {
|
||||
|
||||
if (!participant) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (participant?.isVirtualScreenshareParticipant) {
|
||||
const tracks = state['features/base/tracks'];
|
||||
|
||||
if (isScreenShareParticipant(participant)) {
|
||||
return getVirtualScreenshareParticipantTrack(tracks, participant.id);
|
||||
}
|
||||
|
||||
|
@ -448,8 +454,7 @@ export function getVideoTrackByParticipant(
|
|||
*/
|
||||
export function getSourceNameByParticipantId(state: IState, participantId: string) {
|
||||
const participant = getParticipantByIdOrUndefined(state, participantId);
|
||||
const tracks = state['features/base/tracks'];
|
||||
const track = getVideoTrackByParticipant(tracks, participant);
|
||||
const track = getVideoTrackByParticipant(state, participant);
|
||||
|
||||
return track?.jitsiTrack?.getSourceName();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,11 @@ import { IState } from '../../../app/types';
|
|||
import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { MEDIA_TYPE } from '../../../base/media/constants';
|
||||
import { getLocalParticipant, getParticipantById } from '../../../base/participants/functions';
|
||||
import {
|
||||
getLocalParticipant,
|
||||
getParticipantById,
|
||||
isScreenShareParticipant
|
||||
} from '../../../base/participants/functions';
|
||||
// @ts-ignore
|
||||
import { Popover } from '../../../base/popover';
|
||||
import {
|
||||
|
@ -401,7 +405,7 @@ export function _mapStateToProps(state: IState, ownProps: Props) {
|
|||
|
||||
let firstVideoTrack;
|
||||
|
||||
if (sourceNameSignalingEnabled && participant?.isVirtualScreenshareParticipant) {
|
||||
if (sourceNameSignalingEnabled && isScreenShareParticipant(participant)) {
|
||||
firstVideoTrack = getVirtualScreenshareParticipantTrack(tracks, participantId);
|
||||
} else {
|
||||
firstVideoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, participantId);
|
||||
|
|
|
@ -6,7 +6,7 @@ import type { Dispatch } from 'redux';
|
|||
import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { MEDIA_TYPE } from '../../../base/media';
|
||||
import { getLocalParticipant, getParticipantById } from '../../../base/participants';
|
||||
import { getLocalParticipant, getParticipantById, isScreenShareParticipant } from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { getSourceNameByParticipantId, getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
|
||||
import { ConnectionStatsTable } from '../../../connection-stats';
|
||||
|
@ -352,7 +352,7 @@ export function _mapStateToProps(state: Object, ownProps: Props) {
|
|||
_disableShowMoreStats: state['features/base/config'].disableShowMoreStats,
|
||||
_isConnectionStatusInactive,
|
||||
_isConnectionStatusInterrupted,
|
||||
_isVirtualScreenshareParticipant: sourceNameSignalingEnabled && participant?.isVirtualScreenshareParticipant,
|
||||
_isVirtualScreenshareParticipant: sourceNameSignalingEnabled && isScreenShareParticipant(participant),
|
||||
_isLocalVideo: participant?.local,
|
||||
_region: participant?.region,
|
||||
_sourceName: getSourceNameByParticipantId(state, participantId),
|
||||
|
|
|
@ -72,7 +72,7 @@ function _mapStateToProps(state: IState, ownProps: Partial<Props>) {
|
|||
|
||||
return {
|
||||
_participantName: getParticipantDisplayName(state, ownProps.participantId ?? ''),
|
||||
_render: participant && (!participant?.local || ownProps.contained) && !participant?.isFakeParticipant
|
||||
_render: participant && (!participant?.local || ownProps.contained) && !participant?.fakeParticipant
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,11 @@ import { makeStyles } from 'tss-react/mui';
|
|||
import { IState } from '../../../app/types';
|
||||
// @ts-ignore
|
||||
import { isDisplayNameVisible } from '../../../base/config/functions.any';
|
||||
import { getLocalParticipant, getParticipantDisplayName } from '../../../base/participants/functions';
|
||||
import {
|
||||
getLocalParticipant,
|
||||
getParticipantDisplayName,
|
||||
isWhiteboardParticipant
|
||||
} from '../../../base/participants/functions';
|
||||
import { Participant } from '../../../base/participants/types';
|
||||
import { withPixelLineHeight } from '../../../base/styles/functions.web';
|
||||
// @ts-ignore
|
||||
|
@ -64,7 +68,7 @@ const StageParticipantNameLabel = () => {
|
|||
&& nameToDisplay
|
||||
&& selectedId !== localId
|
||||
&& !isTileView
|
||||
&& !largeVideoParticipant?.isWhiteboard
|
||||
&& !isWhiteboardParticipant(largeVideoParticipant)
|
||||
) {
|
||||
return (
|
||||
<div
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
getParticipantById,
|
||||
getParticipantCount,
|
||||
getRemoteParticipants,
|
||||
isScreenShareParticipant,
|
||||
participantUpdated
|
||||
} from '../base/participants';
|
||||
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
|
||||
|
@ -94,11 +95,11 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
|||
}
|
||||
case PARTICIPANT_JOINED: {
|
||||
const result = next(action);
|
||||
const { e2eeEnabled, e2eeSupported, isVirtualScreenshareParticipant, local } = action.participant;
|
||||
const { e2eeEnabled, e2eeSupported, local } = action.participant;
|
||||
const { everyoneEnabledE2EE } = getState()['features/e2ee'];
|
||||
const participantCount = getParticipantCount(getState);
|
||||
|
||||
if (isVirtualScreenshareParticipant) {
|
||||
if (isScreenShareParticipant(action.participant)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -138,9 +139,9 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
|||
const participant = getParticipantById(previosState, action.participant?.id) || {};
|
||||
const result = next(action);
|
||||
const newState = getState();
|
||||
const { e2eeEnabled = false, e2eeSupported = false, isVirtualScreenshareParticipant } = participant;
|
||||
const { e2eeEnabled = false, e2eeSupported = false } = participant;
|
||||
|
||||
if (isVirtualScreenshareParticipant) {
|
||||
if (isScreenShareParticipant(participant)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -163,10 +163,10 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
|
||||
case PARTICIPANT_LEFT: {
|
||||
const { participant } = action;
|
||||
const { isFakeParticipant, isVirtualScreenshareParticipant, isWhiteboard } = participant;
|
||||
const { fakeParticipant } = participant;
|
||||
|
||||
// Skip sending participant left event for fake or virtual screenshare participants.
|
||||
if (isFakeParticipant || isVirtualScreenshareParticipant || isWhiteboard) {
|
||||
// Skip sending participant left event for fake participants.
|
||||
if (fakeParticipant) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -177,13 +177,13 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
const state = store.getState();
|
||||
const { defaultRemoteDisplayName } = state['features/base/config'];
|
||||
const { participant } = action;
|
||||
const { id, isFakeParticipant, isVirtualScreenshareParticipant, local, name } = participant;
|
||||
const { fakeParticipant, id, local, name } = participant;
|
||||
|
||||
// The version of external api outside of middleware did not emit
|
||||
// the local participant being created.
|
||||
if (!local) {
|
||||
// Skip sending participant joined event for fake or virtual screenshare participants.
|
||||
if (isFakeParticipant || isVirtualScreenshareParticipant) {
|
||||
// Skip sending participant joined event for fake participants.
|
||||
if (fakeParticipant) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,10 @@ import {
|
|||
getParticipantCount,
|
||||
hasRaisedHand,
|
||||
isEveryoneModerator,
|
||||
isScreenShareParticipant,
|
||||
pinParticipant
|
||||
} from '../../../base/participants';
|
||||
import { FakeParticipant } from '../../../base/participants/types';
|
||||
import { Container } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
import {
|
||||
|
@ -57,9 +59,9 @@ type Props = {
|
|||
_gifSrc: ?string,
|
||||
|
||||
/**
|
||||
* Indicates whether the participant is fake.
|
||||
* The type of participant if the participant is fake.
|
||||
*/
|
||||
_isFakeParticipant: boolean,
|
||||
_fakeParticipant?: FakeParticipant,
|
||||
|
||||
/**
|
||||
* Indicates whether the participant is screen sharing.
|
||||
|
@ -189,13 +191,13 @@ class Thumbnail extends PureComponent<Props> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onThumbnailLongPress() {
|
||||
const { _participantId, _local, _isFakeParticipant, _localVideoOwner, dispatch } = this.props;
|
||||
const { _fakeParticipant, _participantId, _local, _localVideoOwner, dispatch } = this.props;
|
||||
|
||||
if (_isFakeParticipant && _localVideoOwner) {
|
||||
if (_fakeParticipant && _localVideoOwner) {
|
||||
dispatch(showSharedVideoMenu(_participantId));
|
||||
}
|
||||
|
||||
if (!_isFakeParticipant) {
|
||||
if (!_fakeParticipant) {
|
||||
dispatch(showContextMenuDetails(_participantId, _local));
|
||||
}
|
||||
}
|
||||
|
@ -208,9 +210,9 @@ class Thumbnail extends PureComponent<Props> {
|
|||
_renderIndicators() {
|
||||
const {
|
||||
_audioMuted: audioMuted,
|
||||
_fakeParticipant,
|
||||
_isScreenShare: isScreenShare,
|
||||
_isVirtualScreenshare,
|
||||
_isFakeParticipant,
|
||||
_renderModeratorIndicator: renderModeratorIndicator,
|
||||
_participantId: participantId,
|
||||
_pinned,
|
||||
|
@ -219,7 +221,7 @@ class Thumbnail extends PureComponent<Props> {
|
|||
} = this.props;
|
||||
const indicators = [];
|
||||
|
||||
if (!_isFakeParticipant) {
|
||||
if (!_fakeParticipant) {
|
||||
indicators.push(<View
|
||||
key = 'top-left-indicators'
|
||||
style = { [
|
||||
|
@ -342,8 +344,8 @@ class Thumbnail extends PureComponent<Props> {
|
|||
*/
|
||||
render() {
|
||||
const {
|
||||
_fakeParticipant,
|
||||
_gifSrc,
|
||||
_isFakeParticipant,
|
||||
_isScreenShare: isScreenShare,
|
||||
_isVirtualScreenshare,
|
||||
_participantId: participantId,
|
||||
|
@ -378,7 +380,7 @@ class Thumbnail extends PureComponent<Props> {
|
|||
: <>
|
||||
<ParticipantView
|
||||
avatarSize = { tileView ? AVATAR_SIZE * 1.5 : AVATAR_SIZE }
|
||||
disableVideo = { isScreenShare || _isFakeParticipant }
|
||||
disableVideo = { isScreenShare || _fakeParticipant }
|
||||
participantId = { participantId }
|
||||
zOrder = { 1 } />
|
||||
{
|
||||
|
@ -406,7 +408,7 @@ function _mapStateToProps(state, ownProps) {
|
|||
const localParticipantId = getLocalParticipant(state).id;
|
||||
const id = participant?.id;
|
||||
const audioTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.AUDIO, id);
|
||||
const videoTrack = getVideoTrackByParticipant(tracks, participant);
|
||||
const videoTrack = getVideoTrackByParticipant(state, participant);
|
||||
const isMultiStreamSupportEnabled = getMultipleVideoSupportFeatureFlag(state);
|
||||
const isScreenShare = videoTrack?.videoType === VIDEO_TYPE.DESKTOP;
|
||||
const participantCount = getParticipantCount(state);
|
||||
|
@ -419,10 +421,10 @@ function _mapStateToProps(state, ownProps) {
|
|||
|
||||
return {
|
||||
_audioMuted: audioTrack?.muted ?? true,
|
||||
_fakeParticipant: participant?.fakeParticipant,
|
||||
_gifSrc: mode === 'chat' ? null : gifSrc,
|
||||
_isFakeParticipant: participant?.isFakeParticipant,
|
||||
_isScreenShare: isScreenShare,
|
||||
_isVirtualScreenshare: isMultiStreamSupportEnabled && participant?.isVirtualScreenshareParticipant,
|
||||
_isVirtualScreenshare: isMultiStreamSupportEnabled && isScreenShareParticipant(participant),
|
||||
_local: participant?.local,
|
||||
_localVideoOwner: Boolean(ownerId === localParticipantId),
|
||||
_participantId: id,
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
import { MEDIA_TYPE } from '../../../base/media';
|
||||
import { PARTICIPANT_ROLE, getParticipantByIdOrUndefined } from '../../../base/participants';
|
||||
import {
|
||||
PARTICIPANT_ROLE,
|
||||
getParticipantByIdOrUndefined,
|
||||
isScreenShareParticipantById
|
||||
} from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import {
|
||||
getVideoTrackByParticipant,
|
||||
|
@ -104,8 +108,9 @@ function _mapStateToProps(state, ownProps) {
|
|||
|
||||
if (participant?.local) {
|
||||
isAudioMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);
|
||||
} else if (!participant?.isFakeParticipant) { // remote participants excluding shared video
|
||||
const track = getVideoTrackByParticipant(tracks, participant);
|
||||
} else if (!participant?.fakeParticipant || isScreenShareParticipantById(state, participantID)) {
|
||||
// remote participants excluding shared video
|
||||
const track = getVideoTrackByParticipant(state, participant);
|
||||
|
||||
isScreenSharing = track?.videoType === 'desktop';
|
||||
isAudioMuted = isRemoteTrackMuted(tracks, MEDIA_TYPE.AUDIO, participantID);
|
||||
|
|
|
@ -22,7 +22,10 @@ import { pinParticipant } from '../../../base/participants/actions';
|
|||
import {
|
||||
getLocalParticipant,
|
||||
getParticipantByIdOrUndefined,
|
||||
hasRaisedHand
|
||||
hasRaisedHand,
|
||||
isLocalScreenshareParticipant,
|
||||
isScreenShareParticipant,
|
||||
isWhiteboardParticipant
|
||||
} from '../../../base/participants/functions';
|
||||
import { Participant } from '../../../base/participants/types';
|
||||
import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants';
|
||||
|
@ -1050,7 +1053,7 @@ class Thumbnail extends Component<Props, State> {
|
|||
_thumbnailType === THUMBNAIL_TYPE.TILE && 'tile-view-mode'
|
||||
) }>
|
||||
<ThumbnailTopIndicators
|
||||
disableConnectionIndicator = { _participant?.isWhiteboard }
|
||||
disableConnectionIndicator = { isWhiteboardParticipant(_participant) }
|
||||
hidePopover = { this._hidePopover }
|
||||
indicatorsClassName = { classes.indicatorsBackground }
|
||||
isHovered = { isHovered }
|
||||
|
@ -1067,10 +1070,9 @@ class Thumbnail extends Component<Props, State> {
|
|||
) }>
|
||||
<ThumbnailBottomIndicators
|
||||
className = { classes.indicatorsBackground }
|
||||
isVirtualScreenshareParticipant = { false }
|
||||
local = { local }
|
||||
participantId = { id }
|
||||
showStatusIndicators = { !_participant?.isWhiteboard }
|
||||
showStatusIndicators = { !isWhiteboardParticipant(_participant) }
|
||||
thumbnailType = { _thumbnailType } />
|
||||
</div>
|
||||
{!_gifSrc && this._renderAvatar(styles.avatar) }
|
||||
|
@ -1115,13 +1117,16 @@ class Thumbnail extends Component<Props, State> {
|
|||
return null;
|
||||
}
|
||||
|
||||
const { isFakeParticipant, isLocalScreenShare, isWhiteboard, local } = _participant;
|
||||
const { fakeParticipant, local } = _participant;
|
||||
|
||||
if (local) {
|
||||
return this._renderParticipant(true);
|
||||
}
|
||||
|
||||
if (isFakeParticipant && !isWhiteboard) {
|
||||
if (fakeParticipant
|
||||
&& !isWhiteboardParticipant(_participant)
|
||||
&& !_isVirtualScreenshareParticipant
|
||||
) {
|
||||
return this._renderFakeParticipant();
|
||||
}
|
||||
|
||||
|
@ -1141,7 +1146,7 @@ class Thumbnail extends Component<Props, State> {
|
|||
classes = { classes }
|
||||
containerClassName = { this._getContainerClassName() }
|
||||
isHovered = { isHovered }
|
||||
isLocal = { isLocalScreenShare }
|
||||
isLocal = { isLocalScreenshareParticipant(_participant) }
|
||||
isMobile = { _isMobile }
|
||||
onClick = { this._onClick }
|
||||
onMouseEnter = { this._onMouseEnter }
|
||||
|
@ -1177,11 +1182,12 @@ function _mapStateToProps(state: IState, ownProps: any): Object {
|
|||
const isLocal = participant?.local ?? true;
|
||||
const multipleVideoSupportEnabled = getMultipleVideoSupportFeatureFlag(state);
|
||||
const sourceNameSignalingEnabled = getSourceNameSignalingFeatureFlag(state);
|
||||
const _isVirtualScreenshareParticipant = multipleVideoSupportEnabled && isScreenShareParticipant(participant);
|
||||
const tracks = state['features/base/tracks'];
|
||||
|
||||
let _videoTrack;
|
||||
|
||||
if (multipleVideoSupportEnabled && participant?.isVirtualScreenshareParticipant) {
|
||||
if (_isVirtualScreenshareParticipant) {
|
||||
_videoTrack = getVirtualScreenshareParticipantTrack(tracks, id);
|
||||
} else {
|
||||
_videoTrack = isLocal
|
||||
|
@ -1304,7 +1310,7 @@ function _mapStateToProps(state: IState, ownProps: any): Object {
|
|||
_isScreenSharing: _videoTrack?.videoType === 'desktop',
|
||||
_isTestModeEnabled: isTestModeEnabled(state),
|
||||
_isVideoPlayable: id && isVideoPlayable(state, id),
|
||||
_isVirtualScreenshareParticipant: multipleVideoSupportEnabled && participant?.isVirtualScreenshareParticipant,
|
||||
_isVirtualScreenshareParticipant,
|
||||
_localFlipX: Boolean(localFlipX),
|
||||
_multipleVideoSupport: multipleVideoSupportEnabled,
|
||||
_participant: participant,
|
||||
|
|
|
@ -4,12 +4,14 @@ import React from 'react';
|
|||
import { useSelector } from 'react-redux';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import { IState } from '../../../app/types';
|
||||
import {
|
||||
getMultipleVideoSupportFeatureFlag,
|
||||
isDisplayNameVisible,
|
||||
isNameReadOnly
|
||||
// @ts-ignore
|
||||
} from '../../../base/config/functions.any';
|
||||
import { isScreenShareParticipantById } from '../../../base/participants/functions';
|
||||
// @ts-ignore
|
||||
import DisplayName from '../../../display-name/components/web/DisplayName';
|
||||
import { THUMBNAIL_TYPE } from '../../constants';
|
||||
|
@ -26,11 +28,6 @@ type Props = {
|
|||
*/
|
||||
className: string;
|
||||
|
||||
/**
|
||||
* Whether it is a virtual screenshare participant thumbnail.
|
||||
*/
|
||||
isVirtualScreenshareParticipant: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the indicators are for the local participant.
|
||||
*/
|
||||
|
@ -73,7 +70,6 @@ const useStyles = makeStyles()(() => {
|
|||
|
||||
const ThumbnailBottomIndicators = ({
|
||||
className,
|
||||
isVirtualScreenshareParticipant,
|
||||
local,
|
||||
participantId,
|
||||
showStatusIndicators = true,
|
||||
|
@ -84,6 +80,9 @@ const ThumbnailBottomIndicators = ({
|
|||
const _defaultLocalDisplayName = interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME;
|
||||
const _isMultiStreamEnabled = useSelector(getMultipleVideoSupportFeatureFlag);
|
||||
const _showDisplayName = useSelector(isDisplayNameVisible);
|
||||
const isVirtualScreenshareParticipant = useSelector(
|
||||
(state: IState) => isScreenShareParticipantById(state, participantId)
|
||||
);
|
||||
|
||||
return (<div className = { className }>
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@ import { IState } from '../../../app/types';
|
|||
// @ts-ignore
|
||||
import { getMultipleVideoSupportFeatureFlag } from '../../../base/config';
|
||||
import { isMobileBrowser } from '../../../base/environment/utils';
|
||||
import { isScreenShareParticipantById } from '../../../base/participants/functions';
|
||||
// @ts-ignore
|
||||
import ConnectionIndicator from '../../../connection-indicator/components/web/ConnectionIndicator';
|
||||
import { STATS_POPOVER_POSITION, THUMBNAIL_TYPE } from '../../constants';
|
||||
|
@ -46,11 +47,6 @@ type Props = {
|
|||
*/
|
||||
isHovered: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the thumbnail is a virtual screen share participant.
|
||||
*/
|
||||
isVirtualScreenshareParticipant?: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the indicators are for the local participant.
|
||||
*/
|
||||
|
@ -93,7 +89,6 @@ const ThumbnailTopIndicators = ({
|
|||
disableConnectionIndicator,
|
||||
hidePopover,
|
||||
indicatorsClassName,
|
||||
isVirtualScreenshareParticipant,
|
||||
isHovered,
|
||||
local,
|
||||
participantId,
|
||||
|
@ -112,6 +107,9 @@ const ThumbnailTopIndicators = ({
|
|||
|| Boolean(useSelector((state: IState) => state['features/base/config'].connectionIndicators?.disabled));
|
||||
const _isMultiStreamEnabled = useSelector(getMultipleVideoSupportFeatureFlag);
|
||||
const showConnectionIndicator = isHovered || !_connectionIndicatorAutoHideEnabled;
|
||||
const isVirtualScreenshareParticipant = useSelector(
|
||||
(state: IState) => isScreenShareParticipantById(state, participantId)
|
||||
);
|
||||
|
||||
if (_isMultiStreamEnabled && isVirtualScreenshareParticipant) {
|
||||
return (
|
||||
|
|
|
@ -147,7 +147,6 @@ const VirtualScreenshareParticipant = ({
|
|||
<ThumbnailTopIndicators
|
||||
currentLayout = { currentLayout }
|
||||
isHovered = { isHovered }
|
||||
isVirtualScreenshareParticipant = { true }
|
||||
participantId = { participantId }
|
||||
thumbnailType = { thumbnailType } />
|
||||
</div>
|
||||
|
@ -159,7 +158,6 @@ const VirtualScreenshareParticipant = ({
|
|||
<ThumbnailBottomIndicators
|
||||
className = { classes.indicatorsBackground }
|
||||
currentLayout = { currentLayout }
|
||||
isVirtualScreenshareParticipant = { true }
|
||||
local = { false }
|
||||
participantId = { participantId }
|
||||
showStatusIndicators = { true } />
|
||||
|
|
|
@ -8,7 +8,8 @@ import {
|
|||
getParticipantById,
|
||||
getParticipantCount,
|
||||
getParticipantCountWithFake,
|
||||
getPinnedParticipant
|
||||
getPinnedParticipant,
|
||||
isScreenShareParticipant
|
||||
} from '../base/participants';
|
||||
import { toState } from '../base/redux';
|
||||
import { shouldHideSelfView } from '../base/settings/functions.any';
|
||||
|
@ -129,7 +130,8 @@ export function isVideoPlayable(stateful: Object | Function, id: String) {
|
|||
const isVideoMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.VIDEO);
|
||||
|
||||
isPlayable = Boolean(videoTrack) && !isVideoMuted && !isAudioOnly;
|
||||
} else if (!participant?.isFakeParticipant) { // remote participants excluding shared video
|
||||
} else if (!participant?.fakeParticipant || isScreenShareParticipant(participant)) {
|
||||
// remote participants excluding shared video
|
||||
const isVideoMuted = isRemoteTrackMuted(tracks, MEDIA_TYPE.VIDEO, id);
|
||||
|
||||
if (getSourceNameSignalingFeatureFlag(state)) {
|
||||
|
@ -589,7 +591,7 @@ export function getDisplayModeInput(props: Object, state: Object) {
|
|||
connectionStatus: _participant?.connectionStatus,
|
||||
canPlayEventReceived,
|
||||
videoStream: Boolean(_videoTrack),
|
||||
isRemoteParticipant: !_participant?.isFakeParticipant && !_participant?.local,
|
||||
isRemoteParticipant: !_participant?.fakeParticipant && !_participant?.local,
|
||||
isScreenSharing: _isScreenSharing,
|
||||
isVirtualScreenshareParticipant: _isVirtualScreenshareParticipant,
|
||||
multipleVideoSupport: _multipleVideoSupport,
|
||||
|
|
|
@ -9,7 +9,8 @@ import {
|
|||
PARTICIPANT_LEFT,
|
||||
getDominantSpeakerParticipant,
|
||||
getLocalParticipant,
|
||||
getLocalScreenShareParticipant
|
||||
getLocalScreenShareParticipant,
|
||||
isScreenShareParticipant
|
||||
} from '../base/participants';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { CLIENT_RESIZED } from '../base/responsive-ui';
|
||||
|
@ -108,7 +109,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
}
|
||||
case PARTICIPANT_JOINED: {
|
||||
result = next(action);
|
||||
if (action.participant?.isLocalScreenShare) {
|
||||
if (isScreenShareParticipant(action.participant)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ function _mapStateToProps(state) {
|
|||
const { participantId } = state['features/large-video'];
|
||||
const participant = getParticipantById(state, participantId);
|
||||
const { clientHeight: height, clientWidth: width } = state['features/base/responsive-ui'];
|
||||
const videoTrack = getVideoTrackByParticipant(state['features/base/tracks'], participant);
|
||||
const videoTrack = getVideoTrackByParticipant(state, participant);
|
||||
let disableVideo = false;
|
||||
|
||||
if (participant?.local) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import React, { Component } from 'react';
|
|||
import VideoLayout from '../../../../modules/UI/videolayout/VideoLayout';
|
||||
import { getMultipleVideoSupportFeatureFlag } from '../../base/config';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE } from '../../base/media';
|
||||
import { getLocalParticipant } from '../../base/participants';
|
||||
import { getLocalParticipant, isScreenShareParticipant } from '../../base/participants';
|
||||
import { Watermarks } from '../../base/react';
|
||||
import { connect } from '../../base/redux';
|
||||
import { getTrackByMediaTypeAndParticipant, getVirtualScreenshareParticipantTrack } from '../../base/tracks';
|
||||
|
@ -346,7 +346,7 @@ function _mapStateToProps(state) {
|
|||
const largeVideoParticipant = getLargeVideoParticipant(state);
|
||||
let videoTrack;
|
||||
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && largeVideoParticipant?.isVirtualScreenshareParticipant) {
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(largeVideoParticipant)) {
|
||||
videoTrack = getVirtualScreenshareParticipantTrack(tracks, largeVideoParticipant?.id);
|
||||
} else {
|
||||
videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideoParticipant?.id);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
|
||||
import { getMultipleVideoSupportFeatureFlag } from '../base/config';
|
||||
import { MEDIA_TYPE } from '../base/media';
|
||||
import { isScreenShareParticipant } from '../base/participants';
|
||||
import { StateListenerRegistry } from '../base/redux';
|
||||
import { getTrackByMediaTypeAndParticipant, getVirtualScreenshareParticipantTrack } from '../base/tracks';
|
||||
|
||||
|
@ -27,7 +28,7 @@ StateListenerRegistry.register(
|
|||
const tracks = state['features/base/tracks'];
|
||||
let videoTrack;
|
||||
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && largeVideoParticipant?.isVirtualScreenshareParticipant) {
|
||||
if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(largeVideoParticipant)) {
|
||||
videoTrack = getVirtualScreenshareParticipantTrack(tracks, largeVideoParticipant?.id);
|
||||
} else {
|
||||
videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideoParticipant?.id);
|
||||
|
|
|
@ -32,7 +32,8 @@ import {
|
|||
PARTICIPANT_LEFT,
|
||||
getLocalParticipant,
|
||||
getParticipantById,
|
||||
getRemoteParticipants
|
||||
getRemoteParticipants,
|
||||
isScreenShareParticipant
|
||||
} from '../../base/participants';
|
||||
import { MiddlewareRegistry, StateListenerRegistry } from '../../base/redux';
|
||||
import { getLocalTracks, isLocalTrackMuted, toggleScreensharing } from '../../base/tracks';
|
||||
|
@ -182,7 +183,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
|
||||
const { participant } = action;
|
||||
|
||||
if (participant.isVirtualScreenshareParticipant) {
|
||||
if (isScreenShareParticipant(participant)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -343,7 +344,7 @@ function _registerForNativeEvents(store) {
|
|||
|
||||
participantsInfo.push(_participantToParticipantInfo(localParticipant));
|
||||
remoteParticipants.forEach(participant => {
|
||||
if (!participant.isFakeParticipant) {
|
||||
if (!participant.fakeParticipant) {
|
||||
participantsInfo.push(_participantToParticipantInfo(participant));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -9,7 +9,9 @@ import { PARTICIPANT_ROLE } from '../base/participants/constants';
|
|||
import {
|
||||
getLocalParticipant,
|
||||
getParticipantById,
|
||||
getParticipantDisplayName
|
||||
getParticipantDisplayName,
|
||||
isScreenShareParticipant,
|
||||
isWhiteboardParticipant
|
||||
} from '../base/participants/functions';
|
||||
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
|
||||
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
|
||||
|
@ -132,8 +134,8 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
// Do not display notifications for the virtual screenshare and whiteboard tiles.
|
||||
if (conference
|
||||
&& !p.local
|
||||
&& !p.isVirtualScreenshareParticipant
|
||||
&& !p.isWhiteboard
|
||||
&& !isScreenShareParticipant(p)
|
||||
&& !isWhiteboardParticipant(p)
|
||||
&& !joinLeaveNotificationsDisabled()
|
||||
&& !p.isReplacing) {
|
||||
dispatch(showParticipantJoinedNotification(
|
||||
|
@ -153,8 +155,8 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
// Do not display notifications for the virtual screenshare tiles.
|
||||
if (participant
|
||||
&& !participant.local
|
||||
&& !participant.isVirtualScreenshareParticipant
|
||||
&& !participant.isWhiteboard
|
||||
&& !isScreenShareParticipant(participant)
|
||||
&& !isWhiteboardParticipant(participant)
|
||||
&& !action.participant.isReplaced) {
|
||||
dispatch(showParticipantLeftNotification(
|
||||
getParticipantDisplayName(state, participant.id)
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
hasRaisedHand,
|
||||
isParticipantModerator
|
||||
} from '../../../base/participants';
|
||||
import { FakeParticipant } from '../../../base/participants/types';
|
||||
import { connect } from '../../../base/redux';
|
||||
import {
|
||||
isParticipantAudioMuted,
|
||||
|
@ -40,9 +41,9 @@ type Props = {
|
|||
_displayName: string,
|
||||
|
||||
/**
|
||||
* True if the participant is fake.
|
||||
* The type of fake participant.
|
||||
*/
|
||||
_isFakeParticipant: boolean,
|
||||
_fakeParticipant: FakeParticipant,
|
||||
|
||||
/**
|
||||
* Whether or not the user is a moderator.
|
||||
|
@ -110,16 +111,16 @@ class MeetingParticipantItem extends PureComponent<Props> {
|
|||
*/
|
||||
_onPress() {
|
||||
const {
|
||||
_fakeParticipant,
|
||||
_local,
|
||||
_localVideoOwner,
|
||||
_isFakeParticipant,
|
||||
_participantID,
|
||||
dispatch
|
||||
} = this.props;
|
||||
|
||||
if (_isFakeParticipant && _localVideoOwner) {
|
||||
if (_fakeParticipant && _localVideoOwner) {
|
||||
dispatch(showSharedVideoMenu(_participantID));
|
||||
} else if (!_isFakeParticipant) {
|
||||
} else if (!_fakeParticipant) {
|
||||
if (_local) {
|
||||
dispatch(showConnectionStatus(_participantID));
|
||||
} else {
|
||||
|
@ -188,8 +189,8 @@ function mapStateToProps(state, ownProps): Object {
|
|||
_audioMediaState: audioMediaState,
|
||||
_disableModeratorIndicator: disableModeratorIndicator,
|
||||
_displayName: getParticipantDisplayName(state, participant?.id),
|
||||
_fakeParticipant: participant?.fakeParticipant,
|
||||
_isAudioMuted,
|
||||
_isFakeParticipant: Boolean(participant?.isFakeParticipant),
|
||||
_isModerator: isParticipantModerator(participant),
|
||||
_local: Boolean(participant?.local),
|
||||
_localVideoOwner: Boolean(ownerId === localParticipantId),
|
||||
|
|
|
@ -102,7 +102,7 @@ class MeetingParticipantContextMenu extends Component<Props> {
|
|||
thumbnailMenu: false
|
||||
};
|
||||
|
||||
if (_participant?.isFakeParticipant) {
|
||||
if (_participant?.fakeParticipant) {
|
||||
return (
|
||||
<FakeParticipantContextMenu
|
||||
{ ...props }
|
||||
|
|
|
@ -252,7 +252,7 @@ function MeetingParticipantItem({
|
|||
<ParticipantItem
|
||||
actionsTrigger = { ACTION_TRIGGER.HOVER }
|
||||
{
|
||||
...(_participant?.isFakeParticipant ? {} : {
|
||||
...(_participant?.fakeParticipant ? {} : {
|
||||
audioMediaState,
|
||||
videoMediaState: _videoMediaState
|
||||
})
|
||||
|
@ -269,7 +269,7 @@ function MeetingParticipantItem({
|
|||
raisedHand = { _raisedHand }
|
||||
youText = { youText }>
|
||||
|
||||
{!overflowDrawer && !_participant?.isFakeParticipant
|
||||
{!overflowDrawer && !_participant?.fakeParticipant
|
||||
&& <>
|
||||
{!isInBreakoutRoom && (
|
||||
<ParticipantQuickAction
|
||||
|
@ -286,7 +286,7 @@ function MeetingParticipantItem({
|
|||
</>
|
||||
}
|
||||
|
||||
{!overflowDrawer && (_localVideoOwner || _participant?.isWhiteboard) && _participant?.isFakeParticipant && (
|
||||
{!overflowDrawer && (_localVideoOwner || _participant?.fakeParticipant) && (
|
||||
<ParticipantActionEllipsis
|
||||
accessibilityLabel = { participantActionEllipsisLabel }
|
||||
onClick = { onContextMenu } />
|
||||
|
|
|
@ -13,7 +13,7 @@ import participantsPaneTheme from '../../../base/components/themes/participantsP
|
|||
// @ts-ignore
|
||||
import { isToolbarButtonEnabled } from '../../../base/config/functions.web';
|
||||
import { MEDIA_TYPE } from '../../../base/media/constants';
|
||||
import { getParticipantById } from '../../../base/participants/functions';
|
||||
import { getParticipantById, isScreenShareParticipant } from '../../../base/participants/functions';
|
||||
import { connect } from '../../../base/redux/functions';
|
||||
import { withPixelLineHeight } from '../../../base/styles/functions.web';
|
||||
import Input from '../../../base/ui/components/web/Input';
|
||||
|
@ -174,7 +174,7 @@ function _mapStateToProps(state: IState): Object {
|
|||
sortedParticipantIds = sortedParticipantIds.filter((id: any) => {
|
||||
const participant = getParticipantById(state, id);
|
||||
|
||||
return !participant?.isVirtualScreenshareParticipant;
|
||||
return !isScreenShareParticipant(participant);
|
||||
});
|
||||
|
||||
const participantsCount = sortedParticipantIds.length;
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
import {
|
||||
getParticipantById,
|
||||
getVirtualScreenshareParticipantByOwnerId,
|
||||
getVirtualScreenshareParticipantOwnerId
|
||||
getVirtualScreenshareParticipantOwnerId,
|
||||
isScreenShareParticipant
|
||||
} from '../base/participants';
|
||||
import { StateListenerRegistry } from '../base/redux';
|
||||
|
||||
|
@ -24,7 +25,7 @@ StateListenerRegistry.register(
|
|||
|
||||
const participant = getParticipantById(state, participantId);
|
||||
|
||||
if (participant?.isVirtualScreenshareParticipant) {
|
||||
if (isScreenShareParticipant(participant)) {
|
||||
// multistream support is enabled and the user has selected the desktop sharing thumbnail.
|
||||
const id = getVirtualScreenshareParticipantOwnerId(participantId);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
participantLeft,
|
||||
pinParticipant
|
||||
} from '../base/participants';
|
||||
import { FakeParticipant } from '../base/participants/types';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
import { RESET_SHARED_VIDEO_STATUS, SET_SHARED_VIDEO_STATUS } from './actionTypes';
|
||||
|
@ -55,7 +56,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
const videoParticipant = getParticipantById(state, value);
|
||||
|
||||
dispatch(participantLeft(value, conference, {
|
||||
isFakeParticipant: videoParticipant?.isFakeParticipant
|
||||
fakeParticipant: videoParticipant?.fakeParticipant
|
||||
}));
|
||||
|
||||
if (localParticipantId !== from) {
|
||||
|
@ -162,8 +163,8 @@ function handleSharingVideoStatus(store, videoUrl, { state, time, from, muted },
|
|||
|
||||
dispatch(participantJoined({
|
||||
conference,
|
||||
fakeParticipant: FakeParticipant.SharedVideo,
|
||||
id: videoUrl,
|
||||
isFakeParticipant: true,
|
||||
avatarURL,
|
||||
name: VIDEO_PLAYER_PARTICIPANT_NAME
|
||||
}));
|
||||
|
|
|
@ -124,7 +124,7 @@ export function updateAutoPinnedParticipant(
|
|||
const pinned = getPinnedParticipant(getState);
|
||||
|
||||
// if the pinned participant is shared video or some other fake participant we want to skip auto-pinning
|
||||
if (pinned?.isFakeParticipant) {
|
||||
if (pinned?.fakeParticipant) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
if (!getAutoPinSetting() || isFollowMeActive(store)) {
|
||||
break;
|
||||
}
|
||||
shouldUpdateAutoPin = getParticipantById(store.getState(), action.participant.id)?.isFakeParticipant;
|
||||
shouldUpdateAutoPin = Boolean(getParticipantById(store.getState(), action.participant.id)?.fakeParticipant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import TogglePinToStageButton from '../../../../features/video-menu/components/w
|
|||
// @ts-ignore
|
||||
import { Avatar } from '../../../base/avatar';
|
||||
import { IconShareVideo } from '../../../base/icons/svg';
|
||||
import { isWhiteboardParticipant } from '../../../base/participants/functions';
|
||||
import { Participant } from '../../../base/participants/types';
|
||||
import ContextMenu from '../../../base/ui/components/web/ContextMenu';
|
||||
import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
|
||||
|
@ -106,7 +107,7 @@ const FakeParticipantContextMenu = ({
|
|||
}, [ setWhiteboardOpen ]);
|
||||
|
||||
const _getActions = useCallback(() => {
|
||||
if (participant.isWhiteboard) {
|
||||
if (isWhiteboardParticipant(participant)) {
|
||||
return [ {
|
||||
accessibilityLabel: t('toolbar.hideWhiteboard'),
|
||||
icon: IconShareVideo,
|
||||
|
@ -123,7 +124,7 @@ const FakeParticipantContextMenu = ({
|
|||
text: t('toolbar.stopSharedVideo')
|
||||
} ];
|
||||
}
|
||||
}, [ localVideoOwner, participant.isWhiteboard ]);
|
||||
}, [ localVideoOwner, participant.fakeParticipant ]);
|
||||
|
||||
return (
|
||||
<ContextMenu
|
||||
|
@ -148,9 +149,11 @@ const FakeParticipantContextMenu = ({
|
|||
|
||||
<ContextMenuItemGroup
|
||||
actions = { _getActions() }>
|
||||
{participant.isWhiteboard && <TogglePinToStageButton
|
||||
key = 'pinToStage'
|
||||
participantID = { WHITEBOARD_ID } />}
|
||||
{isWhiteboardParticipant(participant) && (
|
||||
<TogglePinToStageButton
|
||||
key = 'pinToStage'
|
||||
participantID = { WHITEBOARD_ID } />
|
||||
)}
|
||||
</ContextMenuItemGroup>
|
||||
|
||||
</ContextMenu>
|
||||
|
|
|
@ -250,7 +250,7 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
|
|||
thumbnailMenu: true
|
||||
};
|
||||
|
||||
if (_participant?.isFakeParticipant) {
|
||||
if (_participant?.fakeParticipant) {
|
||||
return (
|
||||
<FakeParticipantContextMenu
|
||||
{ ...props }
|
||||
|
|
|
@ -13,7 +13,6 @@ import { RESET_WHITEBOARD, SET_WHITEBOARD_OPEN } from './actionTypes';
|
|||
import { getCollabDetails, getCollabServerUrl, isWhiteboardPresent } from './functions';
|
||||
import { WHITEBOARD_ID, WHITEBOARD_PARTICIPANT_NAME } from './constants';
|
||||
import { resetWhiteboard, setWhiteboardOpen, setupWhiteboard } from './actions';
|
||||
import { getCurrentRoomId } from '../breakout-rooms/functions';
|
||||
|
||||
// @ts-ignore
|
||||
import { addStageParticipant } from '../filmstrip/actions.web';
|
||||
|
@ -21,6 +20,8 @@ import { addStageParticipant } from '../filmstrip/actions.web';
|
|||
// @ts-ignore
|
||||
import { isStageFilmstripAvailable } from '../filmstrip/functions';
|
||||
import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
|
||||
import { FakeParticipant } from '../base/participants/types';
|
||||
import { getCurrentRoomId } from '../breakout-rooms/functions';
|
||||
|
||||
const focusWhiteboard = (store: IStore) => {
|
||||
const { dispatch, getState } = store;
|
||||
|
@ -32,9 +33,8 @@ const focusWhiteboard = (store: IStore) => {
|
|||
if (!isPresent) {
|
||||
dispatch(participantJoined({
|
||||
conference,
|
||||
fakeParticipant: FakeParticipant.Whiteboard,
|
||||
id: WHITEBOARD_ID,
|
||||
isFakeParticipant: true,
|
||||
isWhiteboard: true,
|
||||
name: WHITEBOARD_PARTICIPANT_NAME
|
||||
}));
|
||||
}
|
||||
|
@ -85,11 +85,11 @@ MiddlewareRegistry.register((store: IStore) => (next: Function) => async (action
|
|||
return;
|
||||
}
|
||||
|
||||
dispatch(participantLeft(WHITEBOARD_ID, conference, { isWhiteboard: true }));
|
||||
dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
|
||||
break;
|
||||
}
|
||||
case RESET_WHITEBOARD: {
|
||||
dispatch(participantLeft(WHITEBOARD_ID, conference, { isWhiteboard: true }));
|
||||
dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue