Bläddra i källkod

ref(participants) use enum type to store fake participants (#12316)

factor2
Mihaela Dumitru 3 år sedan
förälder
incheckning
d0c22806ec
Inget konto är kopplat till bidragsgivarens mejladress
41 ändrade filer med 294 tillägg och 193 borttagningar
  1. 13
    12
      modules/UI/videolayout/LargeVideoManager.js
  2. 7
    4
      modules/UI/videolayout/VideoLayout.js
  3. 5
    10
      react/features/base/participants/actions.ts
  4. 8
    8
      react/features/base/participants/components/ParticipantView.native.js
  5. 74
    10
      react/features/base/participants/functions.ts
  6. 13
    11
      react/features/base/participants/middleware.ts
  7. 13
    17
      react/features/base/participants/reducer.ts
  8. 5
    4
      react/features/base/participants/subscriber.ts
  9. 9
    5
      react/features/base/participants/types.ts
  10. 4
    4
      react/features/base/testing/functions.ts
  11. 12
    7
      react/features/base/tracks/functions.ts
  12. 6
    2
      react/features/connection-indicator/components/web/ConnectionIndicator.tsx
  13. 2
    2
      react/features/connection-indicator/components/web/ConnectionIndicatorContent.js
  14. 1
    1
      react/features/display-name/components/native/DisplayNameLabel.tsx
  15. 6
    2
      react/features/display-name/components/web/StageParticipantNameLabel.tsx
  16. 5
    4
      react/features/e2ee/middleware.js
  17. 6
    6
      react/features/external-api/middleware.js
  18. 14
    12
      react/features/filmstrip/components/native/Thumbnail.js
  19. 8
    3
      react/features/filmstrip/components/web/StatusIndicators.js
  20. 15
    9
      react/features/filmstrip/components/web/Thumbnail.tsx
  21. 5
    6
      react/features/filmstrip/components/web/ThumbnailBottomIndicators.tsx
  22. 4
    6
      react/features/filmstrip/components/web/ThumbnailTopIndicators.tsx
  23. 0
    2
      react/features/filmstrip/components/web/VirtualScreenshareParticipant.js
  24. 5
    3
      react/features/filmstrip/functions.web.js
  25. 3
    2
      react/features/filmstrip/middleware.web.js
  26. 1
    1
      react/features/large-video/components/LargeVideo.native.js
  27. 2
    2
      react/features/large-video/components/LargeVideo.web.js
  28. 2
    1
      react/features/large-video/subscriber.web.js
  29. 4
    3
      react/features/mobile/external-api/middleware.js
  30. 7
    5
      react/features/notifications/middleware.ts
  31. 7
    6
      react/features/participants-pane/components/native/MeetingParticipantItem.js
  32. 1
    1
      react/features/participants-pane/components/web/MeetingParticipantContextMenu.js
  33. 3
    3
      react/features/participants-pane/components/web/MeetingParticipantItem.js
  34. 2
    2
      react/features/participants-pane/components/web/MeetingParticipants.tsx
  35. 3
    2
      react/features/remote-control/subscriber.js
  36. 3
    2
      react/features/shared-video/middleware.any.js
  37. 1
    1
      react/features/video-layout/functions.any.js
  38. 1
    1
      react/features/video-layout/middleware.any.js
  39. 8
    5
      react/features/video-menu/components/web/FakeParticipantContextMenu.tsx
  40. 1
    1
      react/features/video-menu/components/web/RemoteVideoMenuTriggerButton.tsx
  41. 5
    5
      react/features/whiteboard/middleware.ts

+ 13
- 12
modules/UI/videolayout/LargeVideoManager.js Visa fil

@@ -19,7 +19,9 @@ import { JitsiTrackEvents } from '../../../react/features/base/lib-jitsi-meet';
19 19
 import { VIDEO_TYPE } from '../../../react/features/base/media';
20 20
 import {
21 21
     getParticipantById,
22
-    getParticipantDisplayName
22
+    getParticipantDisplayName,
23
+    isLocalScreenshareParticipant,
24
+    isScreenShareParticipant
23 25
 } from '../../../react/features/base/participants';
24 26
 import {
25 27
     getVideoTrackByParticipant,
@@ -265,8 +267,7 @@ export default class LargeVideoManager {
265 267
             let isVideoRenderable;
266 268
 
267 269
             if (getSourceNameSignalingFeatureFlag(state)) {
268
-                const tracks = state['features/base/tracks'];
269
-                const videoTrack = getVideoTrackByParticipant(tracks, participant);
270
+                const videoTrack = getVideoTrackByParticipant(state, participant);
270 271
 
271 272
                 // Remove track streaming status listener from the old track and add it to the new track,
272 273
                 // 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 {
292 293
                 const streamingStatusActive = isTrackStreamingStatusActive(videoTrack);
293 294
 
294 295
                 isVideoRenderable = !isVideoMuted
295
-                    && (APP.conference.isLocalId(id) || participant?.isLocalScreenShare || streamingStatusActive);
296
+                    && (APP.conference.isLocalId(id)
297
+                        || isLocalScreenshareParticipant(participant)
298
+                        || streamingStatusActive
299
+                    );
296 300
                 this.videoTrack?.jitsiTrack?.getVideoType() === VIDEO_TYPE.DESKTOP
297 301
                     && logger.debug(`Remote track ${videoTrack?.jitsiTrack}, isVideoMuted=${isVideoMuted},`
298 302
                     + ` streamingStatusActive=${streamingStatusActive}, isVideoRenderable=${isVideoRenderable}`);
@@ -309,7 +313,7 @@ export default class LargeVideoManager {
309 313
             // progress.
310 314
             const legacyScreenshare = getMultipleVideoSupportFeatureFlag(state)
311 315
                                         && videoType === VIDEO_TYPE.DESKTOP
312
-                                        && !participant.isVirtualScreenshareParticipant;
316
+                                        && !isScreenShareParticipant(participant);
313 317
 
314 318
             const showAvatar
315 319
                 = isVideoContainer
@@ -329,11 +333,10 @@ export default class LargeVideoManager {
329 333
                 if ((!shouldDisplayTileView(state) || participant?.pinned) // In theory the tile view may not be
330 334
                 // enabled yet when we auto pin the participant.
331 335
 
332
-                        && participant && !participant.local && !participant.isFakeParticipant) {
336
+                        && participant && !participant.local && !participant.fakeParticipant) {
333 337
                     // remote participant only
334 338
 
335
-                    const tracks = state['features/base/tracks'];
336
-                    const track = getVideoTrackByParticipant(tracks, participant);
339
+                    const track = getVideoTrackByParticipant(state, participant);
337 340
 
338 341
                     const isScreenSharing = track?.videoType === 'desktop';
339 342
 
@@ -365,8 +368,7 @@ export default class LargeVideoManager {
365 368
             let messageKey;
366 369
 
367 370
             if (getSourceNameSignalingFeatureFlag(state)) {
368
-                const tracks = state['features/base/tracks'];
369
-                const videoTrack = getVideoTrackByParticipant(tracks, participant);
371
+                const videoTrack = getVideoTrackByParticipant(state, participant);
370 372
 
371 373
                 messageKey = isTrackStreamingStatusInactive(videoTrack) ? 'connection.LOW_BANDWIDTH' : null;
372 374
             } else {
@@ -619,8 +621,7 @@ export default class LargeVideoManager {
619 621
             const state = APP.store.getState();
620 622
 
621 623
             if (getSourceNameSignalingFeatureFlag(state)) {
622
-                const tracks = state['features/base/tracks'];
623
-                const videoTrack = getVideoTrackByParticipant(tracks, participant);
624
+                const videoTrack = getVideoTrackByParticipant(state, participant);
624 625
 
625 626
                 // eslint-disable-next-line no-param-reassign
626 627
                 show = !APP.conference.isLocalId(this.id)

+ 7
- 4
modules/UI/videolayout/VideoLayout.js Visa fil

@@ -6,7 +6,9 @@ import { getMultipleVideoSupportFeatureFlag } from '../../../react/features/base
6 6
 import { MEDIA_TYPE, VIDEO_TYPE } from '../../../react/features/base/media';
7 7
 import {
8 8
     getParticipantById,
9
-    getPinnedParticipant
9
+    getPinnedParticipant,
10
+    isScreenShareParticipant,
11
+    isScreenShareParticipantById
10 12
 } from '../../../react/features/base/participants';
11 13
 import {
12 14
     getTrackByMediaTypeAndParticipant,
@@ -90,12 +92,13 @@ const VideoLayout = {
90 92
     getRemoteVideoType(id) {
91 93
         const state = APP.store.getState();
92 94
         const participant = getParticipantById(state, id);
95
+        const isScreenShare = isScreenShareParticipantById(state, id);
93 96
 
94
-        if (participant?.isFakeParticipant) {
97
+        if (participant?.fakeParticipant && !isScreenShare) {
95 98
             return VIDEO_TYPE.CAMERA;
96 99
         }
97 100
 
98
-        if (getMultipleVideoSupportFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
101
+        if (getMultipleVideoSupportFeatureFlag(state) && isScreenShare) {
99 102
             return VIDEO_TYPE.DESKTOP;
100 103
         }
101 104
 
@@ -190,7 +193,7 @@ const VideoLayout = {
190 193
 
191 194
         let videoTrack;
192 195
 
193
-        if (getMultipleVideoSupportFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
196
+        if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(participant)) {
194 197
             videoTrack = getVirtualScreenshareParticipantTrack(tracks, id);
195 198
         } else {
196 199
             videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, id);

+ 5
- 10
react/features/base/participants/actions.ts Visa fil

@@ -36,7 +36,7 @@ import {
36 36
     getVirtualScreenshareParticipantOwnerId
37 37
 } from './functions';
38 38
 import logger from './logger';
39
-import { Participant } from './types';
39
+import { FakeParticipant, Participant } from './types';
40 40
 
41 41
 /**
42 42
  * Create an action for when dominant speaker changes.
@@ -386,10 +386,8 @@ export function hiddenParticipantLeft(id: string) {
386 386
  * instance.
387 387
  * @param {Object} participantLeftProps - Other participant properties.
388 388
  * @typedef {Object} participantLeftProps
389
+ * @param {FakeParticipant|undefined} participantLeftProps.fakeParticipant - The type of fake participant.
389 390
  * @param {boolean} participantLeftProps.isReplaced - Whether the participant is to be replaced in the meeting.
390
- * @param {boolean} participantLeftProps.isVirtualScreenshareParticipant - Whether the participant is a
391
- * virtual screen share participant.
392
- * @param {boolean} participantLeftProps.isFakeParticipant - Whether the participant is a fake participant.
393 391
  *
394 392
  * @returns {{
395 393
  *     type: PARTICIPANT_LEFT,
@@ -404,11 +402,9 @@ export function participantLeft(id: string, conference: any, participantLeftProp
404 402
         type: PARTICIPANT_LEFT,
405 403
         participant: {
406 404
             conference,
405
+            fakeParticipant: participantLeftProps.fakeParticipant,
407 406
             id,
408
-            isReplaced: participantLeftProps.isReplaced,
409
-            isVirtualScreenshareParticipant: participantLeftProps.isVirtualScreenshareParticipant,
410
-            isWhiteboard: participantLeftProps.isWhiteboard,
411
-            isFakeParticipant: participantLeftProps.isFakeParticipant
407
+            isReplaced: participantLeftProps.isReplaced
412 408
         }
413 409
     };
414 410
 }
@@ -538,9 +534,8 @@ export function createVirtualScreenshareParticipant(sourceName: string, local: b
538 534
 
539 535
         dispatch(participantJoined({
540 536
             conference: state['features/base/conference'].conference,
537
+            fakeParticipant: local ? FakeParticipant.LocalScreenShare : FakeParticipant.RemoteScreenShare,
541 538
             id: sourceName,
542
-            isVirtualScreenshareParticipant: true,
543
-            isLocalScreenShare: local,
544 539
             name: ownerName
545 540
         }));
546 541
     };

+ 8
- 8
react/features/base/participants/components/ParticipantView.native.js Visa fil

@@ -13,6 +13,7 @@ import { connect } from '../../redux';
13 13
 import { TestHint } from '../../testing/components';
14 14
 import { getVideoTrackByParticipant } from '../../tracks';
15 15
 import { getParticipantById, shouldRenderParticipantVideo } from '../functions';
16
+import { FakeParticipant } from '../types';
16 17
 
17 18
 import styles from './styles';
18 19
 
@@ -31,11 +32,11 @@ type Props = {
31 32
     _connectionStatus: string,
32 33
 
33 34
     /**
34
-     * True if the participant which this component represents is fake.
35
+     * The type of participant if the participant which this component represents is fake.
35 36
      *
36 37
      * @private
37 38
      */
38
-    _isFakeParticipant: boolean,
39
+    _fakeParticipant?: FakeParticipant,
39 40
 
40 41
     /**
41 42
      * The name of the participant which this component represents.
@@ -174,7 +175,7 @@ class ParticipantView extends Component<Props> {
174 175
     render() {
175 176
         const {
176 177
             _connectionStatus: connectionStatus,
177
-            _isFakeParticipant,
178
+            _fakeParticipant,
178 179
             _renderVideo: renderVideo,
179 180
             _videoTrack: videoTrack,
180 181
             disableVideo,
@@ -190,7 +191,7 @@ class ParticipantView extends Component<Props> {
190 191
                 ? this.props.testHintId
191 192
                 : `org.jitsi.meet.Participant#${this.props.participantId}`;
192 193
 
193
-        const renderSharedVideo = _isFakeParticipant && !disableVideo;
194
+        const renderSharedVideo = _fakeParticipant && !disableVideo;
194 195
 
195 196
         return (
196 197
             <Container
@@ -208,7 +209,7 @@ class ParticipantView extends Component<Props> {
208 209
 
209 210
                 { renderSharedVideo && <SharedVideo /> }
210 211
 
211
-                { !_isFakeParticipant && renderVideo
212
+                { !_fakeParticipant && renderVideo
212 213
                     && <VideoTrack
213 214
                         onPress = { onPress }
214 215
                         videoTrack = { videoTrack }
@@ -248,8 +249,7 @@ class ParticipantView extends Component<Props> {
248 249
 function _mapStateToProps(state, ownProps) {
249 250
     const { disableVideo, participantId } = ownProps;
250 251
     const participant = getParticipantById(state, participantId);
251
-    const tracks = state['features/base/tracks'];
252
-    const videoTrack = getVideoTrackByParticipant(tracks, participant);
252
+    const videoTrack = getVideoTrackByParticipant(state, participant);
253 253
     let connectionStatus;
254 254
     let participantName;
255 255
 
@@ -257,7 +257,7 @@ function _mapStateToProps(state, ownProps) {
257 257
         _connectionStatus:
258 258
             connectionStatus
259 259
                 || JitsiParticipantConnectionStatus.ACTIVE,
260
-        _isFakeParticipant: participant && participant.isFakeParticipant,
260
+        _fakeParticipant: participant?.fakeParticipant,
261 261
         _participantName: participantName,
262 262
         _renderVideo: shouldRenderParticipantVideo(state, participantId) && !disableVideo,
263 263
         _videoTrack: videoTrack

+ 74
- 10
react/features/base/participants/functions.ts Visa fil

@@ -2,7 +2,7 @@
2 2
 // @ts-ignore
3 3
 import { getGravatarURL } from '@jitsi/js-utils/avatar';
4 4
 
5
-import { IStore } from '../../app/types';
5
+import { IState, IStore } from '../../app/types';
6 6
 // @ts-ignore
7 7
 import { isStageFilmstripAvailable } from '../../filmstrip/functions';
8 8
 import { IStateful } from '../app/types';
@@ -24,7 +24,7 @@ import {
24 24
 } from './constants';
25 25
 // @ts-ignore
26 26
 import { preloadImage } from './preloadImage';
27
-import { Participant } from './types';
27
+import { FakeParticipant, Participant } from './types';
28 28
 
29 29
 /**
30 30
  * Temp structures for avatar urls to be checked/preloaded.
@@ -34,10 +34,10 @@ const AVATAR_CHECKED_URLS = new Map();
34 34
 /* eslint-disable arrow-body-style, no-unused-vars */
35 35
 const AVATAR_CHECKER_FUNCTIONS = [
36 36
     (participant: Participant) => {
37
-        return participant?.isJigasi ? JIGASI_PARTICIPANT_ICON : null;
37
+        return isJigasiParticipant(participant) ? JIGASI_PARTICIPANT_ICON : null;
38 38
     },
39 39
     (participant: Participant) => {
40
-        return participant?.isWhiteboard ? WHITEBOARD_PARTICIPANT_ICON : null;
40
+        return isWhiteboardParticipant(participant) ? WHITEBOARD_PARTICIPANT_ICON : null;
41 41
     },
42 42
     (participant: Participant) => {
43 43
         return participant?.avatarURL ? participant.avatarURL : null;
@@ -115,7 +115,7 @@ export function getActiveSpeakersToBeDisplayed(stateful: IStateful) {
115 115
         }
116 116
     }
117 117
 
118
-    // Remove shared video from the count.
118
+    // Remove fake participants from the count.
119 119
     if (fakeParticipants) {
120 120
         availableSlotsForActiveSpeakers -= fakeParticipants.size;
121 121
     }
@@ -301,6 +301,69 @@ export function getFakeParticipants(stateful: IStateful) {
301 301
     return toState(stateful)['features/base/participants'].fakeParticipants;
302 302
 }
303 303
 
304
+/**
305
+ * Returns whether the fake participant is Jigasi.
306
+ *
307
+ * @param {Participant|undefined} participant - The participant entity.
308
+ * @returns {boolean} - True if it's a Jigasi participant.
309
+ */
310
+function isJigasiParticipant(participant?: Participant): boolean {
311
+    return participant?.fakeParticipant === FakeParticipant.Jigasi;
312
+}
313
+
314
+/**
315
+ * Returns whether the fake participant is a local screenshare.
316
+ *
317
+ * @param {Participant|undefined} participant - The participant entity.
318
+ * @returns {boolean} - True if it's a local screenshare participant.
319
+ */
320
+export function isLocalScreenshareParticipant(participant?: Participant): boolean {
321
+    return participant?.fakeParticipant === FakeParticipant.LocalScreenShare;
322
+}
323
+
324
+/**
325
+ * Returns whether the fake participant is a remote screenshare.
326
+ *
327
+ * @param {Participant|undefined} participant - The participant entity.
328
+ * @returns {boolean} - True if it's a remote screenshare participant.
329
+ */
330
+export function isRemoteScreenshareParticipant(participant?: Participant): boolean {
331
+    return participant?.fakeParticipant === FakeParticipant.RemoteScreenShare;
332
+}
333
+
334
+/**
335
+ * Returns whether the fake participant is of local or virtual screenshare type.
336
+ *
337
+ * @param {IState} state - The (whole) redux state, or redux's.
338
+ * @param {string|undefined} participantId - The participant id.
339
+ * @returns {boolean} - True if it's one of the two.
340
+ */
341
+export function isScreenShareParticipantById(state: IState, participantId?: string): boolean {
342
+    const participant = getParticipantByIdOrUndefined(state, participantId);
343
+
344
+    return isScreenShareParticipant(participant);
345
+}
346
+
347
+/**
348
+ * Returns whether the fake participant is of local or virtual screenshare type.
349
+ *
350
+ * @param {Participant|undefined} participant - The participant entity.
351
+ * @returns {boolean} - True if it's one of the two.
352
+ */
353
+export function isScreenShareParticipant(participant?: Participant): boolean {
354
+    return isLocalScreenshareParticipant(participant) || isRemoteScreenshareParticipant(participant);
355
+}
356
+
357
+/**
358
+ * Returns whether the fake participant is a whiteboard.
359
+ *
360
+ * @param {Participant|undefined} participant - The participant entity.
361
+ * @returns {boolean} - True if it's a whiteboard participant.
362
+ */
363
+export function isWhiteboardParticipant(participant?: Participant): boolean {
364
+    return participant?.fakeParticipant === FakeParticipant.Whiteboard;
365
+}
366
+
304 367
 /**
305 368
  * Returns a count of the known remote participants in the passed in redux state.
306 369
  *
@@ -349,15 +412,16 @@ export function getParticipantCountWithFake(stateful: IStateful) {
349 412
  * @returns {string}
350 413
  */
351 414
 export function getParticipantDisplayName(stateful: IStateful, id: string): string {
352
-    const participant = getParticipantById(stateful, id);
415
+    const state = toState(stateful);
416
+    const participant = getParticipantById(state, id);
353 417
     const {
354 418
         defaultLocalDisplayName,
355 419
         defaultRemoteDisplayName
356
-    } = toState(stateful)['features/base/config'];
420
+    } = state['features/base/config'];
357 421
 
358 422
     if (participant) {
359
-        if (participant.isVirtualScreenshareParticipant) {
360
-            return getScreenshareParticipantDisplayName(stateful, id);
423
+        if (isScreenShareParticipant(participant)) {
424
+            return getScreenshareParticipantDisplayName(state, id);
361 425
         }
362 426
 
363 427
         if (participant.name) {
@@ -546,7 +610,7 @@ export function shouldRenderParticipantVideo(stateful: IStateful, id: string) {
546 610
     }
547 611
 
548 612
     /* First check if we have an unmuted video track. */
549
-    const videoTrack = getVideoTrackByParticipant(state['features/base/tracks'], participant);
613
+    const videoTrack = getVideoTrackByParticipant(state, participant);
550 614
 
551 615
     if (!shouldRenderVideoTrack(videoTrack, /* waitForVideoStarted */ false)) {
552 616
         return false;

+ 13
- 11
react/features/base/participants/middleware.ts Visa fil

@@ -74,11 +74,13 @@ import {
74 74
     getRaiseHandsQueue,
75 75
     getRemoteParticipants,
76 76
     hasRaisedHand,
77
-    isLocalParticipantModerator
77
+    isLocalParticipantModerator,
78
+    isScreenShareParticipant,
79
+    isWhiteboardParticipant
78 80
 } from './functions';
79 81
 import logger from './logger';
80 82
 import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds';
81
-import { IJitsiParticipant } from './types';
83
+import { FakeParticipant, IJitsiParticipant } from './types';
82 84
 
83 85
 import './subscriber';
84 86
 
@@ -267,19 +269,19 @@ MiddlewareRegistry.register(store => next => action => {
267 269
     }
268 270
 
269 271
     case PARTICIPANT_JOINED: {
270
-        const { isVirtualScreenshareParticipant, isWhiteboard } = action.participant;
271
-
272
-        // Do not play sounds when a virtual participant tile is created for screenshare.
273
-        (!isVirtualScreenshareParticipant && !isWhiteboard) && _maybePlaySounds(store, action);
272
+        // Do not play sounds when a screenshare or whiteboard participant tile is created for screenshare.
273
+        (!isScreenShareParticipant(action.participant)
274
+            && !isWhiteboardParticipant(action.participant)
275
+        ) && _maybePlaySounds(store, action);
274 276
 
275 277
         return _participantJoinedOrUpdated(store, next, action);
276 278
     }
277 279
 
278 280
     case PARTICIPANT_LEFT: {
279
-        const { isVirtualScreenshareParticipant, isWhiteboard } = action.participant;
280
-
281
-        // Do not play sounds when a tile for screenshare is removed.
282
-        (!isVirtualScreenshareParticipant && !isWhiteboard) && _maybePlaySounds(store, action);
281
+        // Do not play sounds when a tile for screenshare or whiteboard is removed.
282
+        (!isScreenShareParticipant(action.participant)
283
+            && !isWhiteboardParticipant(action.participant)
284
+        ) && _maybePlaySounds(store, action);
283 285
 
284 286
         break;
285 287
     }
@@ -436,7 +438,7 @@ StateListenerRegistry.register(
436 438
                     store.dispatch(participantUpdated({
437 439
                         conference,
438 440
                         id: participant.getId(),
439
-                        isJigasi: value
441
+                        fakeParticipant: value ? FakeParticipant.Jigasi : undefined
440 442
                     })),
441 443
                 // eslint-disable-next-line @typescript-eslint/no-unused-vars
442 444
                 'features_screen-sharing': (participant: IJitsiParticipant, value: string) =>

+ 13
- 17
react/features/base/participants/reducer.ts Visa fil

@@ -18,7 +18,12 @@ import {
18 18
     SET_LOADABLE_AVATAR_URL
19 19
 } from './actionTypes';
20 20
 import { LOCAL_PARTICIPANT_DEFAULT_ID, PARTICIPANT_ROLE } from './constants';
21
-import { isParticipantModerator } from './functions';
21
+import {
22
+    isLocalScreenshareParticipant,
23
+    isParticipantModerator,
24
+    isRemoteScreenshareParticipant,
25
+    isScreenShareParticipant
26
+} from './functions';
22 27
 import { LocalParticipant, Participant } from './types';
23 28
 
24 29
 /**
@@ -241,10 +246,8 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
241 246
     case PARTICIPANT_JOINED: {
242 247
         const participant = _participantJoined(action);
243 248
         const {
249
+            fakeParticipant,
244 250
             id,
245
-            isFakeParticipant,
246
-            isLocalScreenShare,
247
-            isVirtualScreenshareParticipant,
248 251
             name,
249 252
             pinned
250 253
         } = participant;
@@ -281,7 +284,7 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
281 284
             };
282 285
         }
283 286
 
284
-        if (isLocalScreenShare) {
287
+        if (isLocalScreenshareParticipant(participant)) {
285 288
             return {
286 289
                 ...state,
287 290
                 localScreenShare: participant
@@ -300,7 +303,7 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
300 303
         // The sort order of participants is preserved since Map remembers the original insertion order of the keys.
301 304
         state.sortedRemoteParticipants = new Map(sortedRemoteParticipants);
302 305
 
303
-        if (isVirtualScreenshareParticipant) {
306
+        if (isRemoteScreenshareParticipant(participant)) {
304 307
             const sortedRemoteVirtualScreenshareParticipants = [ ...state.sortedRemoteVirtualScreenshareParticipants ];
305 308
 
306 309
             sortedRemoteVirtualScreenshareParticipants.push([ id, name ?? '' ]);
@@ -308,7 +311,8 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
308 311
 
309 312
             state.sortedRemoteVirtualScreenshareParticipants = new Map(sortedRemoteVirtualScreenshareParticipants);
310 313
         }
311
-        if (isFakeParticipant) {
314
+        // Exclude the screenshare participant from the fake participant count to avoid duplicates.
315
+        if (fakeParticipant && !isScreenShareParticipant(participant)) {
312 316
             state.fakeParticipants.set(id, participant);
313 317
         }
314 318
 
@@ -509,12 +513,8 @@ function _participantJoined({ participant }: { participant: Participant; }) {
509 513
         connectionStatus,
510 514
         dominantSpeaker,
511 515
         email,
512
-        isFakeParticipant,
513
-        isVirtualScreenshareParticipant,
514
-        isLocalScreenShare,
516
+        fakeParticipant,
515 517
         isReplacing,
516
-        isJigasi,
517
-        isWhiteboard,
518 518
         loadableAvatarUrl,
519 519
         local,
520 520
         name,
@@ -543,13 +543,9 @@ function _participantJoined({ participant }: { participant: Participant; }) {
543 543
         connectionStatus,
544 544
         dominantSpeaker: dominantSpeaker || false,
545 545
         email,
546
+        fakeParticipant,
546 547
         id,
547
-        isFakeParticipant,
548
-        isVirtualScreenshareParticipant,
549
-        isLocalScreenShare,
550 548
         isReplacing,
551
-        isJigasi,
552
-        isWhiteboard,
553 549
         loadableAvatarUrl,
554 550
         local: local || false,
555 551
         name,

+ 5
- 4
react/features/base/participants/subscriber.ts Visa fil

@@ -9,6 +9,7 @@ import {
9 9
 import StateListenerRegistry from '../redux/StateListenerRegistry';
10 10
 
11 11
 import { createVirtualScreenshareParticipant, participantLeft } from './actions';
12
+import { FakeParticipant } from './types';
12 13
 
13 14
 StateListenerRegistry.register(
14 15
     /* selector */ state => state['features/base/tracks'],
@@ -56,8 +57,8 @@ function _updateScreenshareParticipants({ getState, dispatch }: IStore) {
56 57
 
57 58
         if (localScreenShare && !newLocalSceenshareSourceName) {
58 59
             dispatch(participantLeft(localScreenShare.id, conference, {
59
-                isReplaced: undefined,
60
-                isVirtualScreenshareParticipant: true
60
+                fakeParticipant: FakeParticipant.LocalScreenShare,
61
+                isReplaced: undefined
61 62
             }));
62 63
         }
63 64
     }
@@ -67,8 +68,8 @@ function _updateScreenshareParticipants({ getState, dispatch }: IStore) {
67 68
 
68 69
     if (removedScreenshareSourceNames.length) {
69 70
         removedScreenshareSourceNames.forEach(id => dispatch(participantLeft(id, conference, {
70
-            isReplaced: undefined,
71
-            isVirtualScreenshareParticipant: true
71
+            fakeParticipant: FakeParticipant.RemoteScreenShare,
72
+            isReplaced: undefined
72 73
         })));
73 74
     }
74 75
 

+ 9
- 5
react/features/base/participants/types.ts Visa fil

@@ -1,3 +1,11 @@
1
+export enum FakeParticipant {
2
+    Jigasi = 'Jigasi',
3
+    LocalScreenShare = 'LocalScreenShare',
4
+    RemoteScreenShare = 'RemoteScreenShare',
5
+    SharedVideo = 'SharedVideo',
6
+    Whiteboard = 'Whiteboard'
7
+}
8
+
1 9
 export interface Participant {
2 10
     avatarURL?: string;
3 11
     botType?: string;
@@ -8,18 +16,14 @@ export interface Participant {
8 16
     e2eeEnabled?: boolean;
9 17
     e2eeSupported?: boolean;
10 18
     email?: string;
19
+    fakeParticipant?: FakeParticipant;
11 20
     features?: {
12 21
         'screen-sharing'?: boolean | string;
13 22
     };
14 23
     getId?: Function;
15 24
     id: string;
16
-    isFakeParticipant?: boolean;
17
-    isJigasi?: boolean;
18
-    isLocalScreenShare?: boolean;
19 25
     isReplaced?: boolean;
20 26
     isReplacing?: number;
21
-    isVirtualScreenshareParticipant?: boolean;
22
-    isWhiteboard?: boolean;
23 27
     jwtId?: string;
24 28
     loadableAvatarUrl?: string;
25 29
     loadableAvatarUrlUseCORS?: boolean;

+ 4
- 4
react/features/base/testing/functions.ts Visa fil

@@ -1,7 +1,7 @@
1 1
 import { IState, IStore } from '../../app/types';
2 2
 import { getMultipleVideoSupportFeatureFlag } from '../config/functions.any';
3 3
 import { MEDIA_TYPE, VIDEO_TYPE } from '../media/constants';
4
-import { getParticipantById } from '../participants/functions';
4
+import { getParticipantById, isScreenShareParticipant } from '../participants/functions';
5 5
 // eslint-disable-next-line lines-around-comment
6 6
 // @ts-ignore
7 7
 import { getTrackByMediaTypeAndParticipant, getVirtualScreenshareParticipantTrack } from '../tracks';
@@ -31,7 +31,7 @@ export function getRemoteVideoType({ getState }: IStore, id: string) {
31 31
     const state = getState();
32 32
     const participant = getParticipantById(state, id);
33 33
 
34
-    if (getMultipleVideoSupportFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
34
+    if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(participant)) {
35 35
         return VIDEO_TYPE.DESKTOP;
36 36
     }
37 37
 
@@ -51,7 +51,7 @@ export function isLargeVideoReceived({ getState }: IStore): boolean {
51 51
     const tracks = state['features/base/tracks'];
52 52
     let videoTrack;
53 53
 
54
-    if (getMultipleVideoSupportFeatureFlag(state) && largeVideoParticipant?.isVirtualScreenshareParticipant) {
54
+    if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(largeVideoParticipant)) {
55 55
         videoTrack = getVirtualScreenshareParticipantTrack(tracks, largeVideoParticipantId);
56 56
     } else {
57 57
         videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideoParticipantId);
@@ -75,7 +75,7 @@ export function isRemoteVideoReceived({ getState }: IStore, id: string): boolean
75 75
     const participant = getParticipantById(state, id);
76 76
     let videoTrack;
77 77
 
78
-    if (getMultipleVideoSupportFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
78
+    if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(participant)) {
79 79
         videoTrack = getVirtualScreenshareParticipantTrack(tracks, id);
80 80
     } else {
81 81
         videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, id);

+ 12
- 7
react/features/base/tracks/functions.ts Visa fil

@@ -8,7 +8,11 @@ import { isMobileBrowser } from '../environment/utils';
8 8
 import JitsiMeetJS, { JitsiTrackErrors, browser } from '../lib-jitsi-meet';
9 9
 import { setAudioMuted } from '../media/actions';
10 10
 import { MEDIA_TYPE, MediaType, VIDEO_TYPE } from '../media/constants';
11
-import { getParticipantByIdOrUndefined, getVirtualScreenshareParticipantOwnerId } from '../participants/functions';
11
+import {
12
+    getParticipantByIdOrUndefined,
13
+    getVirtualScreenshareParticipantOwnerId,
14
+    isScreenShareParticipant
15
+} from '../participants/functions';
12 16
 import { Participant } from '../participants/types';
13 17
 import { toState } from '../redux/functions';
14 18
 import {
@@ -47,7 +51,7 @@ export function isParticipantMediaMuted(participant: Participant, mediaType: Med
47 51
 
48 52
     if (participant?.local) {
49 53
         return isLocalTrackMuted(tracks, mediaType);
50
-    } else if (!participant?.isFakeParticipant) {
54
+    } else if (!participant?.fakeParticipant) {
51 55
         return isRemoteTrackMuted(tracks, mediaType, participant.id);
52 56
     }
53 57
 
@@ -420,19 +424,21 @@ export function getLocalJitsiAudioTrack(state: IState) {
420 424
 /**
421 425
  * Returns track of specified media type for specified participant.
422 426
  *
423
- * @param {ITrack[]} tracks - List of all tracks.
427
+ * @param {IState} state - The redux state.
424 428
  * @param {Participant} participant - Participant Object.
425 429
  * @returns {(Track|undefined)}
426 430
  */
427 431
 export function getVideoTrackByParticipant(
428
-        tracks: ITrack[],
432
+        state: IState,
429 433
         participant?: Participant) {
430 434
 
431 435
     if (!participant) {
432 436
         return;
433 437
     }
434 438
 
435
-    if (participant?.isVirtualScreenshareParticipant) {
439
+    const tracks = state['features/base/tracks'];
440
+
441
+    if (isScreenShareParticipant(participant)) {
436 442
         return getVirtualScreenshareParticipantTrack(tracks, participant.id);
437 443
     }
438 444
 
@@ -448,8 +454,7 @@ export function getVideoTrackByParticipant(
448 454
  */
449 455
 export function getSourceNameByParticipantId(state: IState, participantId: string) {
450 456
     const participant = getParticipantByIdOrUndefined(state, participantId);
451
-    const tracks = state['features/base/tracks'];
452
-    const track = getVideoTrackByParticipant(tracks, participant);
457
+    const track = getVideoTrackByParticipant(state, participant);
453 458
 
454 459
     return track?.jitsiTrack?.getSourceName();
455 460
 }

+ 6
- 2
react/features/connection-indicator/components/web/ConnectionIndicator.tsx Visa fil

@@ -13,7 +13,11 @@ import { IState } from '../../../app/types';
13 13
 import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
14 14
 import { translate } from '../../../base/i18n/functions';
15 15
 import { MEDIA_TYPE } from '../../../base/media/constants';
16
-import { getLocalParticipant, getParticipantById } from '../../../base/participants/functions';
16
+import {
17
+    getLocalParticipant,
18
+    getParticipantById,
19
+    isScreenShareParticipant
20
+} from '../../../base/participants/functions';
17 21
 // @ts-ignore
18 22
 import { Popover } from '../../../base/popover';
19 23
 import {
@@ -401,7 +405,7 @@ export function _mapStateToProps(state: IState, ownProps: Props) {
401 405
 
402 406
     let firstVideoTrack;
403 407
 
404
-    if (sourceNameSignalingEnabled && participant?.isVirtualScreenshareParticipant) {
408
+    if (sourceNameSignalingEnabled && isScreenShareParticipant(participant)) {
405 409
         firstVideoTrack = getVirtualScreenshareParticipantTrack(tracks, participantId);
406 410
     } else {
407 411
         firstVideoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, participantId);

+ 2
- 2
react/features/connection-indicator/components/web/ConnectionIndicatorContent.js Visa fil

@@ -6,7 +6,7 @@ import type { Dispatch } from 'redux';
6 6
 import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
7 7
 import { translate } from '../../../base/i18n';
8 8
 import { MEDIA_TYPE } from '../../../base/media';
9
-import { getLocalParticipant, getParticipantById } from '../../../base/participants';
9
+import { getLocalParticipant, getParticipantById, isScreenShareParticipant } from '../../../base/participants';
10 10
 import { connect } from '../../../base/redux';
11 11
 import { getSourceNameByParticipantId, getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
12 12
 import { ConnectionStatsTable } from '../../../connection-stats';
@@ -352,7 +352,7 @@ export function _mapStateToProps(state: Object, ownProps: Props) {
352 352
         _disableShowMoreStats: state['features/base/config'].disableShowMoreStats,
353 353
         _isConnectionStatusInactive,
354 354
         _isConnectionStatusInterrupted,
355
-        _isVirtualScreenshareParticipant: sourceNameSignalingEnabled && participant?.isVirtualScreenshareParticipant,
355
+        _isVirtualScreenshareParticipant: sourceNameSignalingEnabled && isScreenShareParticipant(participant),
356 356
         _isLocalVideo: participant?.local,
357 357
         _region: participant?.region,
358 358
         _sourceName: getSourceNameByParticipantId(state, participantId),

+ 1
- 1
react/features/display-name/components/native/DisplayNameLabel.tsx Visa fil

@@ -72,7 +72,7 @@ function _mapStateToProps(state: IState, ownProps: Partial<Props>) {
72 72
 
73 73
     return {
74 74
         _participantName: getParticipantDisplayName(state, ownProps.participantId ?? ''),
75
-        _render: participant && (!participant?.local || ownProps.contained) && !participant?.isFakeParticipant
75
+        _render: participant && (!participant?.local || ownProps.contained) && !participant?.fakeParticipant
76 76
     };
77 77
 }
78 78
 

+ 6
- 2
react/features/display-name/components/web/StageParticipantNameLabel.tsx Visa fil

@@ -8,7 +8,11 @@ import { makeStyles } from 'tss-react/mui';
8 8
 import { IState } from '../../../app/types';
9 9
 // @ts-ignore
10 10
 import { isDisplayNameVisible } from '../../../base/config/functions.any';
11
-import { getLocalParticipant, getParticipantDisplayName } from '../../../base/participants/functions';
11
+import {
12
+    getLocalParticipant,
13
+    getParticipantDisplayName,
14
+    isWhiteboardParticipant
15
+} from '../../../base/participants/functions';
12 16
 import { Participant } from '../../../base/participants/types';
13 17
 import { withPixelLineHeight } from '../../../base/styles/functions.web';
14 18
 // @ts-ignore
@@ -64,7 +68,7 @@ const StageParticipantNameLabel = () => {
64 68
         && nameToDisplay
65 69
         && selectedId !== localId
66 70
         && !isTileView
67
-        && !largeVideoParticipant?.isWhiteboard
71
+        && !isWhiteboardParticipant(largeVideoParticipant)
68 72
     ) {
69 73
         return (
70 74
             <div

+ 5
- 4
react/features/e2ee/middleware.js Visa fil

@@ -12,6 +12,7 @@ import {
12 12
     getParticipantById,
13 13
     getParticipantCount,
14 14
     getRemoteParticipants,
15
+    isScreenShareParticipant,
15 16
     participantUpdated
16 17
 } from '../base/participants';
17 18
 import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
@@ -94,11 +95,11 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
94 95
     }
95 96
     case PARTICIPANT_JOINED: {
96 97
         const result = next(action);
97
-        const { e2eeEnabled, e2eeSupported, isVirtualScreenshareParticipant, local } = action.participant;
98
+        const { e2eeEnabled, e2eeSupported, local } = action.participant;
98 99
         const { everyoneEnabledE2EE } = getState()['features/e2ee'];
99 100
         const participantCount = getParticipantCount(getState);
100 101
 
101
-        if (isVirtualScreenshareParticipant) {
102
+        if (isScreenShareParticipant(action.participant)) {
102 103
             return result;
103 104
         }
104 105
 
@@ -138,9 +139,9 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
138 139
         const participant = getParticipantById(previosState, action.participant?.id) || {};
139 140
         const result = next(action);
140 141
         const newState = getState();
141
-        const { e2eeEnabled = false, e2eeSupported = false, isVirtualScreenshareParticipant } = participant;
142
+        const { e2eeEnabled = false, e2eeSupported = false } = participant;
142 143
 
143
-        if (isVirtualScreenshareParticipant) {
144
+        if (isScreenShareParticipant(participant)) {
144 145
             return result;
145 146
         }
146 147
 

+ 6
- 6
react/features/external-api/middleware.js Visa fil

@@ -163,10 +163,10 @@ MiddlewareRegistry.register(store => next => action => {
163 163
 
164 164
     case PARTICIPANT_LEFT: {
165 165
         const { participant } = action;
166
-        const { isFakeParticipant, isVirtualScreenshareParticipant, isWhiteboard } = participant;
166
+        const { fakeParticipant } = participant;
167 167
 
168
-        // Skip sending participant left event for fake or virtual screenshare participants.
169
-        if (isFakeParticipant || isVirtualScreenshareParticipant || isWhiteboard) {
168
+        // Skip sending participant left event for fake participants.
169
+        if (fakeParticipant) {
170 170
             break;
171 171
         }
172 172
 
@@ -177,13 +177,13 @@ MiddlewareRegistry.register(store => next => action => {
177 177
         const state = store.getState();
178 178
         const { defaultRemoteDisplayName } = state['features/base/config'];
179 179
         const { participant } = action;
180
-        const { id, isFakeParticipant, isVirtualScreenshareParticipant, local, name } = participant;
180
+        const { fakeParticipant, id, local, name } = participant;
181 181
 
182 182
         // The version of external api outside of middleware did not emit
183 183
         // the local participant being created.
184 184
         if (!local) {
185
-            // Skip sending participant joined event for fake or virtual screenshare participants.
186
-            if (isFakeParticipant || isVirtualScreenshareParticipant) {
185
+            // Skip sending participant joined event for fake participants.
186
+            if (fakeParticipant) {
187 187
                 break;
188 188
             }
189 189
 

+ 14
- 12
react/features/filmstrip/components/native/Thumbnail.js Visa fil

@@ -15,8 +15,10 @@ import {
15 15
     getParticipantCount,
16 16
     hasRaisedHand,
17 17
     isEveryoneModerator,
18
+    isScreenShareParticipant,
18 19
     pinParticipant
19 20
 } from '../../../base/participants';
21
+import { FakeParticipant } from '../../../base/participants/types';
20 22
 import { Container } from '../../../base/react';
21 23
 import { connect } from '../../../base/redux';
22 24
 import {
@@ -57,9 +59,9 @@ type Props = {
57 59
     _gifSrc: ?string,
58 60
 
59 61
     /**
60
-     * Indicates whether the participant is fake.
62
+     * The type of participant if the participant is fake.
61 63
      */
62
-    _isFakeParticipant: boolean,
64
+    _fakeParticipant?: FakeParticipant,
63 65
 
64 66
     /**
65 67
      * Indicates whether the participant is screen sharing.
@@ -189,13 +191,13 @@ class Thumbnail extends PureComponent<Props> {
189 191
      * @returns {void}
190 192
      */
191 193
     _onThumbnailLongPress() {
192
-        const { _participantId, _local, _isFakeParticipant, _localVideoOwner, dispatch } = this.props;
194
+        const { _fakeParticipant, _participantId, _local, _localVideoOwner, dispatch } = this.props;
193 195
 
194
-        if (_isFakeParticipant && _localVideoOwner) {
196
+        if (_fakeParticipant && _localVideoOwner) {
195 197
             dispatch(showSharedVideoMenu(_participantId));
196 198
         }
197 199
 
198
-        if (!_isFakeParticipant) {
200
+        if (!_fakeParticipant) {
199 201
             dispatch(showContextMenuDetails(_participantId, _local));
200 202
         }
201 203
     }
@@ -208,9 +210,9 @@ class Thumbnail extends PureComponent<Props> {
208 210
     _renderIndicators() {
209 211
         const {
210 212
             _audioMuted: audioMuted,
213
+            _fakeParticipant,
211 214
             _isScreenShare: isScreenShare,
212 215
             _isVirtualScreenshare,
213
-            _isFakeParticipant,
214 216
             _renderModeratorIndicator: renderModeratorIndicator,
215 217
             _participantId: participantId,
216 218
             _pinned,
@@ -219,7 +221,7 @@ class Thumbnail extends PureComponent<Props> {
219 221
         } = this.props;
220 222
         const indicators = [];
221 223
 
222
-        if (!_isFakeParticipant) {
224
+        if (!_fakeParticipant) {
223 225
             indicators.push(<View
224 226
                 key = 'top-left-indicators'
225 227
                 style = { [
@@ -342,8 +344,8 @@ class Thumbnail extends PureComponent<Props> {
342 344
      */
343 345
     render() {
344 346
         const {
347
+            _fakeParticipant,
345 348
             _gifSrc,
346
-            _isFakeParticipant,
347 349
             _isScreenShare: isScreenShare,
348 350
             _isVirtualScreenshare,
349 351
             _participantId: participantId,
@@ -378,7 +380,7 @@ class Thumbnail extends PureComponent<Props> {
378 380
                     : <>
379 381
                         <ParticipantView
380 382
                             avatarSize = { tileView ? AVATAR_SIZE * 1.5 : AVATAR_SIZE }
381
-                            disableVideo = { isScreenShare || _isFakeParticipant }
383
+                            disableVideo = { isScreenShare || _fakeParticipant }
382 384
                             participantId = { participantId }
383 385
                             zOrder = { 1 } />
384 386
                         {
@@ -406,7 +408,7 @@ function _mapStateToProps(state, ownProps) {
406 408
     const localParticipantId = getLocalParticipant(state).id;
407 409
     const id = participant?.id;
408 410
     const audioTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.AUDIO, id);
409
-    const videoTrack = getVideoTrackByParticipant(tracks, participant);
411
+    const videoTrack = getVideoTrackByParticipant(state, participant);
410 412
     const isMultiStreamSupportEnabled = getMultipleVideoSupportFeatureFlag(state);
411 413
     const isScreenShare = videoTrack?.videoType === VIDEO_TYPE.DESKTOP;
412 414
     const participantCount = getParticipantCount(state);
@@ -419,10 +421,10 @@ function _mapStateToProps(state, ownProps) {
419 421
 
420 422
     return {
421 423
         _audioMuted: audioTrack?.muted ?? true,
424
+        _fakeParticipant: participant?.fakeParticipant,
422 425
         _gifSrc: mode === 'chat' ? null : gifSrc,
423
-        _isFakeParticipant: participant?.isFakeParticipant,
424 426
         _isScreenShare: isScreenShare,
425
-        _isVirtualScreenshare: isMultiStreamSupportEnabled && participant?.isVirtualScreenshareParticipant,
427
+        _isVirtualScreenshare: isMultiStreamSupportEnabled && isScreenShareParticipant(participant),
426 428
         _local: participant?.local,
427 429
         _localVideoOwner: Boolean(ownerId === localParticipantId),
428 430
         _participantId: id,

+ 8
- 3
react/features/filmstrip/components/web/StatusIndicators.js Visa fil

@@ -3,7 +3,11 @@
3 3
 import React, { Component } from 'react';
4 4
 
5 5
 import { MEDIA_TYPE } from '../../../base/media';
6
-import { PARTICIPANT_ROLE, getParticipantByIdOrUndefined } from '../../../base/participants';
6
+import {
7
+    PARTICIPANT_ROLE,
8
+    getParticipantByIdOrUndefined,
9
+    isScreenShareParticipantById
10
+} from '../../../base/participants';
7 11
 import { connect } from '../../../base/redux';
8 12
 import {
9 13
     getVideoTrackByParticipant,
@@ -104,8 +108,9 @@ function _mapStateToProps(state, ownProps) {
104 108
 
105 109
     if (participant?.local) {
106 110
         isAudioMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);
107
-    } else if (!participant?.isFakeParticipant) { // remote participants excluding shared video
108
-        const track = getVideoTrackByParticipant(tracks, participant);
111
+    } else if (!participant?.fakeParticipant || isScreenShareParticipantById(state, participantID)) {
112
+        // remote participants excluding shared video
113
+        const track = getVideoTrackByParticipant(state, participant);
109 114
 
110 115
         isScreenSharing = track?.videoType === 'desktop';
111 116
         isAudioMuted = isRemoteTrackMuted(tracks, MEDIA_TYPE.AUDIO, participantID);

+ 15
- 9
react/features/filmstrip/components/web/Thumbnail.tsx Visa fil

@@ -22,7 +22,10 @@ import { pinParticipant } from '../../../base/participants/actions';
22 22
 import {
23 23
     getLocalParticipant,
24 24
     getParticipantByIdOrUndefined,
25
-    hasRaisedHand
25
+    hasRaisedHand,
26
+    isLocalScreenshareParticipant,
27
+    isScreenShareParticipant,
28
+    isWhiteboardParticipant
26 29
 } from '../../../base/participants/functions';
27 30
 import { Participant } from '../../../base/participants/types';
28 31
 import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants';
@@ -1050,7 +1053,7 @@ class Thumbnail extends Component<Props, State> {
1050 1053
                         _thumbnailType === THUMBNAIL_TYPE.TILE && 'tile-view-mode'
1051 1054
                     ) }>
1052 1055
                     <ThumbnailTopIndicators
1053
-                        disableConnectionIndicator = { _participant?.isWhiteboard }
1056
+                        disableConnectionIndicator = { isWhiteboardParticipant(_participant) }
1054 1057
                         hidePopover = { this._hidePopover }
1055 1058
                         indicatorsClassName = { classes.indicatorsBackground }
1056 1059
                         isHovered = { isHovered }
@@ -1067,10 +1070,9 @@ class Thumbnail extends Component<Props, State> {
1067 1070
                     ) }>
1068 1071
                     <ThumbnailBottomIndicators
1069 1072
                         className = { classes.indicatorsBackground }
1070
-                        isVirtualScreenshareParticipant = { false }
1071 1073
                         local = { local }
1072 1074
                         participantId = { id }
1073
-                        showStatusIndicators = { !_participant?.isWhiteboard }
1075
+                        showStatusIndicators = { !isWhiteboardParticipant(_participant) }
1074 1076
                         thumbnailType = { _thumbnailType } />
1075 1077
                 </div>
1076 1078
                 {!_gifSrc && this._renderAvatar(styles.avatar) }
@@ -1115,13 +1117,16 @@ class Thumbnail extends Component<Props, State> {
1115 1117
             return null;
1116 1118
         }
1117 1119
 
1118
-        const { isFakeParticipant, isLocalScreenShare, isWhiteboard, local } = _participant;
1120
+        const { fakeParticipant, local } = _participant;
1119 1121
 
1120 1122
         if (local) {
1121 1123
             return this._renderParticipant(true);
1122 1124
         }
1123 1125
 
1124
-        if (isFakeParticipant && !isWhiteboard) {
1126
+        if (fakeParticipant
1127
+            && !isWhiteboardParticipant(_participant)
1128
+            && !_isVirtualScreenshareParticipant
1129
+        ) {
1125 1130
             return this._renderFakeParticipant();
1126 1131
         }
1127 1132
 
@@ -1141,7 +1146,7 @@ class Thumbnail extends Component<Props, State> {
1141 1146
                     classes = { classes }
1142 1147
                     containerClassName = { this._getContainerClassName() }
1143 1148
                     isHovered = { isHovered }
1144
-                    isLocal = { isLocalScreenShare }
1149
+                    isLocal = { isLocalScreenshareParticipant(_participant) }
1145 1150
                     isMobile = { _isMobile }
1146 1151
                     onClick = { this._onClick }
1147 1152
                     onMouseEnter = { this._onMouseEnter }
@@ -1177,11 +1182,12 @@ function _mapStateToProps(state: IState, ownProps: any): Object {
1177 1182
     const isLocal = participant?.local ?? true;
1178 1183
     const multipleVideoSupportEnabled = getMultipleVideoSupportFeatureFlag(state);
1179 1184
     const sourceNameSignalingEnabled = getSourceNameSignalingFeatureFlag(state);
1185
+    const _isVirtualScreenshareParticipant = multipleVideoSupportEnabled && isScreenShareParticipant(participant);
1180 1186
     const tracks = state['features/base/tracks'];
1181 1187
 
1182 1188
     let _videoTrack;
1183 1189
 
1184
-    if (multipleVideoSupportEnabled && participant?.isVirtualScreenshareParticipant) {
1190
+    if (_isVirtualScreenshareParticipant) {
1185 1191
         _videoTrack = getVirtualScreenshareParticipantTrack(tracks, id);
1186 1192
     } else {
1187 1193
         _videoTrack = isLocal
@@ -1304,7 +1310,7 @@ function _mapStateToProps(state: IState, ownProps: any): Object {
1304 1310
         _isScreenSharing: _videoTrack?.videoType === 'desktop',
1305 1311
         _isTestModeEnabled: isTestModeEnabled(state),
1306 1312
         _isVideoPlayable: id && isVideoPlayable(state, id),
1307
-        _isVirtualScreenshareParticipant: multipleVideoSupportEnabled && participant?.isVirtualScreenshareParticipant,
1313
+        _isVirtualScreenshareParticipant,
1308 1314
         _localFlipX: Boolean(localFlipX),
1309 1315
         _multipleVideoSupport: multipleVideoSupportEnabled,
1310 1316
         _participant: participant,

+ 5
- 6
react/features/filmstrip/components/web/ThumbnailBottomIndicators.tsx Visa fil

@@ -4,12 +4,14 @@ import React from 'react';
4 4
 import { useSelector } from 'react-redux';
5 5
 import { makeStyles } from 'tss-react/mui';
6 6
 
7
+import { IState } from '../../../app/types';
7 8
 import {
8 9
     getMultipleVideoSupportFeatureFlag,
9 10
     isDisplayNameVisible,
10 11
     isNameReadOnly
11 12
     // @ts-ignore
12 13
 } from '../../../base/config/functions.any';
14
+import { isScreenShareParticipantById } from '../../../base/participants/functions';
13 15
 // @ts-ignore
14 16
 import DisplayName from '../../../display-name/components/web/DisplayName';
15 17
 import { THUMBNAIL_TYPE } from '../../constants';
@@ -26,11 +28,6 @@ type Props = {
26 28
      */
27 29
     className: string;
28 30
 
29
-    /**
30
-     * Whether it is a virtual screenshare participant thumbnail.
31
-     */
32
-    isVirtualScreenshareParticipant: boolean;
33
-
34 31
     /**
35 32
      * Whether or not the indicators are for the local participant.
36 33
      */
@@ -73,7 +70,6 @@ const useStyles = makeStyles()(() => {
73 70
 
74 71
 const ThumbnailBottomIndicators = ({
75 72
     className,
76
-    isVirtualScreenshareParticipant,
77 73
     local,
78 74
     participantId,
79 75
     showStatusIndicators = true,
@@ -84,6 +80,9 @@ const ThumbnailBottomIndicators = ({
84 80
     const _defaultLocalDisplayName = interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME;
85 81
     const _isMultiStreamEnabled = useSelector(getMultipleVideoSupportFeatureFlag);
86 82
     const _showDisplayName = useSelector(isDisplayNameVisible);
83
+    const isVirtualScreenshareParticipant = useSelector(
84
+        (state: IState) => isScreenShareParticipantById(state, participantId)
85
+    );
87 86
 
88 87
     return (<div className = { className }>
89 88
         {

+ 4
- 6
react/features/filmstrip/components/web/ThumbnailTopIndicators.tsx Visa fil

@@ -8,6 +8,7 @@ import { IState } from '../../../app/types';
8 8
 // @ts-ignore
9 9
 import { getMultipleVideoSupportFeatureFlag } from '../../../base/config';
10 10
 import { isMobileBrowser } from '../../../base/environment/utils';
11
+import { isScreenShareParticipantById } from '../../../base/participants/functions';
11 12
 // @ts-ignore
12 13
 import ConnectionIndicator from '../../../connection-indicator/components/web/ConnectionIndicator';
13 14
 import { STATS_POPOVER_POSITION, THUMBNAIL_TYPE } from '../../constants';
@@ -46,11 +47,6 @@ type Props = {
46 47
      */
47 48
     isHovered: boolean;
48 49
 
49
-    /**
50
-     * Whether or not the thumbnail is a virtual screen share participant.
51
-     */
52
-    isVirtualScreenshareParticipant?: boolean;
53
-
54 50
     /**
55 51
      * Whether or not the indicators are for the local participant.
56 52
      */
@@ -93,7 +89,6 @@ const ThumbnailTopIndicators = ({
93 89
     disableConnectionIndicator,
94 90
     hidePopover,
95 91
     indicatorsClassName,
96
-    isVirtualScreenshareParticipant,
97 92
     isHovered,
98 93
     local,
99 94
     participantId,
@@ -112,6 +107,9 @@ const ThumbnailTopIndicators = ({
112 107
         || Boolean(useSelector((state: IState) => state['features/base/config'].connectionIndicators?.disabled));
113 108
     const _isMultiStreamEnabled = useSelector(getMultipleVideoSupportFeatureFlag);
114 109
     const showConnectionIndicator = isHovered || !_connectionIndicatorAutoHideEnabled;
110
+    const isVirtualScreenshareParticipant = useSelector(
111
+        (state: IState) => isScreenShareParticipantById(state, participantId)
112
+    );
115 113
 
116 114
     if (_isMultiStreamEnabled && isVirtualScreenshareParticipant) {
117 115
         return (

+ 0
- 2
react/features/filmstrip/components/web/VirtualScreenshareParticipant.js Visa fil

@@ -147,7 +147,6 @@ const VirtualScreenshareParticipant = ({
147 147
                 <ThumbnailTopIndicators
148 148
                     currentLayout = { currentLayout }
149 149
                     isHovered = { isHovered }
150
-                    isVirtualScreenshareParticipant = { true }
151 150
                     participantId = { participantId }
152 151
                     thumbnailType = { thumbnailType } />
153 152
             </div>
@@ -159,7 +158,6 @@ const VirtualScreenshareParticipant = ({
159 158
                 <ThumbnailBottomIndicators
160 159
                     className = { classes.indicatorsBackground }
161 160
                     currentLayout = { currentLayout }
162
-                    isVirtualScreenshareParticipant = { true }
163 161
                     local = { false }
164 162
                     participantId = { participantId }
165 163
                     showStatusIndicators = { true } />

+ 5
- 3
react/features/filmstrip/functions.web.js Visa fil

@@ -8,7 +8,8 @@ import {
8 8
     getParticipantById,
9 9
     getParticipantCount,
10 10
     getParticipantCountWithFake,
11
-    getPinnedParticipant
11
+    getPinnedParticipant,
12
+    isScreenShareParticipant
12 13
 } from '../base/participants';
13 14
 import { toState } from '../base/redux';
14 15
 import { shouldHideSelfView } from '../base/settings/functions.any';
@@ -129,7 +130,8 @@ export function isVideoPlayable(stateful: Object | Function, id: String) {
129 130
         const isVideoMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.VIDEO);
130 131
 
131 132
         isPlayable = Boolean(videoTrack) && !isVideoMuted && !isAudioOnly;
132
-    } else if (!participant?.isFakeParticipant) { // remote participants excluding shared video
133
+    } else if (!participant?.fakeParticipant || isScreenShareParticipant(participant)) {
134
+        // remote participants excluding shared video
133 135
         const isVideoMuted = isRemoteTrackMuted(tracks, MEDIA_TYPE.VIDEO, id);
134 136
 
135 137
         if (getSourceNameSignalingFeatureFlag(state)) {
@@ -589,7 +591,7 @@ export function getDisplayModeInput(props: Object, state: Object) {
589 591
         connectionStatus: _participant?.connectionStatus,
590 592
         canPlayEventReceived,
591 593
         videoStream: Boolean(_videoTrack),
592
-        isRemoteParticipant: !_participant?.isFakeParticipant && !_participant?.local,
594
+        isRemoteParticipant: !_participant?.fakeParticipant && !_participant?.local,
593 595
         isScreenSharing: _isScreenSharing,
594 596
         isVirtualScreenshareParticipant: _isVirtualScreenshareParticipant,
595 597
         multipleVideoSupport: _multipleVideoSupport,

+ 3
- 2
react/features/filmstrip/middleware.web.js Visa fil

@@ -9,7 +9,8 @@ import {
9 9
     PARTICIPANT_LEFT,
10 10
     getDominantSpeakerParticipant,
11 11
     getLocalParticipant,
12
-    getLocalScreenShareParticipant
12
+    getLocalScreenShareParticipant,
13
+    isScreenShareParticipant
13 14
 } from '../base/participants';
14 15
 import { MiddlewareRegistry } from '../base/redux';
15 16
 import { CLIENT_RESIZED } from '../base/responsive-ui';
@@ -108,7 +109,7 @@ MiddlewareRegistry.register(store => next => action => {
108 109
     }
109 110
     case PARTICIPANT_JOINED: {
110 111
         result = next(action);
111
-        if (action.participant?.isLocalScreenShare) {
112
+        if (isScreenShareParticipant(action.participant)) {
112 113
             break;
113 114
         }
114 115
 

+ 1
- 1
react/features/large-video/components/LargeVideo.native.js Visa fil

@@ -255,7 +255,7 @@ function _mapStateToProps(state) {
255 255
     const { participantId } = state['features/large-video'];
256 256
     const participant = getParticipantById(state, participantId);
257 257
     const { clientHeight: height, clientWidth: width } = state['features/base/responsive-ui'];
258
-    const videoTrack = getVideoTrackByParticipant(state['features/base/tracks'], participant);
258
+    const videoTrack = getVideoTrackByParticipant(state, participant);
259 259
     let disableVideo = false;
260 260
 
261 261
     if (participant?.local) {

+ 2
- 2
react/features/large-video/components/LargeVideo.web.js Visa fil

@@ -5,7 +5,7 @@ import React, { Component } from 'react';
5 5
 import VideoLayout from '../../../../modules/UI/videolayout/VideoLayout';
6 6
 import { getMultipleVideoSupportFeatureFlag } from '../../base/config';
7 7
 import { MEDIA_TYPE, VIDEO_TYPE } from '../../base/media';
8
-import { getLocalParticipant } from '../../base/participants';
8
+import { getLocalParticipant, isScreenShareParticipant } from '../../base/participants';
9 9
 import { Watermarks } from '../../base/react';
10 10
 import { connect } from '../../base/redux';
11 11
 import { getTrackByMediaTypeAndParticipant, getVirtualScreenshareParticipantTrack } from '../../base/tracks';
@@ -346,7 +346,7 @@ function _mapStateToProps(state) {
346 346
     const largeVideoParticipant = getLargeVideoParticipant(state);
347 347
     let videoTrack;
348 348
 
349
-    if (getMultipleVideoSupportFeatureFlag(state) && largeVideoParticipant?.isVirtualScreenshareParticipant) {
349
+    if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(largeVideoParticipant)) {
350 350
         videoTrack = getVirtualScreenshareParticipantTrack(tracks, largeVideoParticipant?.id);
351 351
     } else {
352 352
         videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideoParticipant?.id);

+ 2
- 1
react/features/large-video/subscriber.web.js Visa fil

@@ -3,6 +3,7 @@
3 3
 import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
4 4
 import { getMultipleVideoSupportFeatureFlag } from '../base/config';
5 5
 import { MEDIA_TYPE } from '../base/media';
6
+import { isScreenShareParticipant } from '../base/participants';
6 7
 import { StateListenerRegistry } from '../base/redux';
7 8
 import { getTrackByMediaTypeAndParticipant, getVirtualScreenshareParticipantTrack } from '../base/tracks';
8 9
 
@@ -27,7 +28,7 @@ StateListenerRegistry.register(
27 28
         const tracks = state['features/base/tracks'];
28 29
         let videoTrack;
29 30
 
30
-        if (getMultipleVideoSupportFeatureFlag(state) && largeVideoParticipant?.isVirtualScreenshareParticipant) {
31
+        if (getMultipleVideoSupportFeatureFlag(state) && isScreenShareParticipant(largeVideoParticipant)) {
31 32
             videoTrack = getVirtualScreenshareParticipantTrack(tracks, largeVideoParticipant?.id);
32 33
         } else {
33 34
             videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideoParticipant?.id);

+ 4
- 3
react/features/mobile/external-api/middleware.js Visa fil

@@ -32,7 +32,8 @@ import {
32 32
     PARTICIPANT_LEFT,
33 33
     getLocalParticipant,
34 34
     getParticipantById,
35
-    getRemoteParticipants
35
+    getRemoteParticipants,
36
+    isScreenShareParticipant
36 37
 } from '../../base/participants';
37 38
 import { MiddlewareRegistry, StateListenerRegistry } from '../../base/redux';
38 39
 import { getLocalTracks, isLocalTrackMuted, toggleScreensharing } from '../../base/tracks';
@@ -182,7 +183,7 @@ MiddlewareRegistry.register(store => next => action => {
182 183
 
183 184
         const { participant } = action;
184 185
 
185
-        if (participant.isVirtualScreenshareParticipant) {
186
+        if (isScreenShareParticipant(participant)) {
186 187
             break;
187 188
         }
188 189
 
@@ -343,7 +344,7 @@ function _registerForNativeEvents(store) {
343 344
 
344 345
         participantsInfo.push(_participantToParticipantInfo(localParticipant));
345 346
         remoteParticipants.forEach(participant => {
346
-            if (!participant.isFakeParticipant) {
347
+            if (!participant.fakeParticipant) {
347 348
                 participantsInfo.push(_participantToParticipantInfo(participant));
348 349
             }
349 350
         });

+ 7
- 5
react/features/notifications/middleware.ts Visa fil

@@ -9,7 +9,9 @@ import { PARTICIPANT_ROLE } from '../base/participants/constants';
9 9
 import {
10 10
     getLocalParticipant,
11 11
     getParticipantById,
12
-    getParticipantDisplayName
12
+    getParticipantDisplayName,
13
+    isScreenShareParticipant,
14
+    isWhiteboardParticipant
13 15
 } from '../base/participants/functions';
14 16
 import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
15 17
 import StateListenerRegistry from '../base/redux/StateListenerRegistry';
@@ -132,8 +134,8 @@ MiddlewareRegistry.register(store => next => action => {
132 134
         // Do not display notifications for the virtual screenshare and whiteboard tiles.
133 135
         if (conference
134 136
             && !p.local
135
-            && !p.isVirtualScreenshareParticipant
136
-            && !p.isWhiteboard
137
+            && !isScreenShareParticipant(p)
138
+            && !isWhiteboardParticipant(p)
137 139
             && !joinLeaveNotificationsDisabled()
138 140
             && !p.isReplacing) {
139 141
             dispatch(showParticipantJoinedNotification(
@@ -153,8 +155,8 @@ MiddlewareRegistry.register(store => next => action => {
153 155
             // Do not display notifications for the virtual screenshare tiles.
154 156
             if (participant
155 157
                 && !participant.local
156
-                && !participant.isVirtualScreenshareParticipant
157
-                && !participant.isWhiteboard
158
+                && !isScreenShareParticipant(participant)
159
+                && !isWhiteboardParticipant(participant)
158 160
                 && !action.participant.isReplaced) {
159 161
                 dispatch(showParticipantLeftNotification(
160 162
                     getParticipantDisplayName(state, participant.id)

+ 7
- 6
react/features/participants-pane/components/native/MeetingParticipantItem.js Visa fil

@@ -10,6 +10,7 @@ import {
10 10
     hasRaisedHand,
11 11
     isParticipantModerator
12 12
 } from '../../../base/participants';
13
+import { FakeParticipant } from '../../../base/participants/types';
13 14
 import { connect } from '../../../base/redux';
14 15
 import {
15 16
     isParticipantAudioMuted,
@@ -40,9 +41,9 @@ type Props = {
40 41
     _displayName: string,
41 42
 
42 43
     /**
43
-     * True if the participant is fake.
44
+     * The type of fake participant.
44 45
      */
45
-    _isFakeParticipant: boolean,
46
+    _fakeParticipant: FakeParticipant,
46 47
 
47 48
     /**
48 49
      * Whether or not the user is a moderator.
@@ -110,16 +111,16 @@ class MeetingParticipantItem extends PureComponent<Props> {
110 111
      */
111 112
     _onPress() {
112 113
         const {
114
+            _fakeParticipant,
113 115
             _local,
114 116
             _localVideoOwner,
115
-            _isFakeParticipant,
116 117
             _participantID,
117 118
             dispatch
118 119
         } = this.props;
119 120
 
120
-        if (_isFakeParticipant && _localVideoOwner) {
121
+        if (_fakeParticipant && _localVideoOwner) {
121 122
             dispatch(showSharedVideoMenu(_participantID));
122
-        } else if (!_isFakeParticipant) {
123
+        } else if (!_fakeParticipant) {
123 124
             if (_local) {
124 125
                 dispatch(showConnectionStatus(_participantID));
125 126
             } else {
@@ -188,8 +189,8 @@ function mapStateToProps(state, ownProps): Object {
188 189
         _audioMediaState: audioMediaState,
189 190
         _disableModeratorIndicator: disableModeratorIndicator,
190 191
         _displayName: getParticipantDisplayName(state, participant?.id),
192
+        _fakeParticipant: participant?.fakeParticipant,
191 193
         _isAudioMuted,
192
-        _isFakeParticipant: Boolean(participant?.isFakeParticipant),
193 194
         _isModerator: isParticipantModerator(participant),
194 195
         _local: Boolean(participant?.local),
195 196
         _localVideoOwner: Boolean(ownerId === localParticipantId),

+ 1
- 1
react/features/participants-pane/components/web/MeetingParticipantContextMenu.js Visa fil

@@ -102,7 +102,7 @@ class MeetingParticipantContextMenu extends Component<Props> {
102 102
             thumbnailMenu: false
103 103
         };
104 104
 
105
-        if (_participant?.isFakeParticipant) {
105
+        if (_participant?.fakeParticipant) {
106 106
             return (
107 107
                 <FakeParticipantContextMenu
108 108
                     { ...props }

+ 3
- 3
react/features/participants-pane/components/web/MeetingParticipantItem.js Visa fil

@@ -252,7 +252,7 @@ function MeetingParticipantItem({
252 252
         <ParticipantItem
253 253
             actionsTrigger = { ACTION_TRIGGER.HOVER }
254 254
             {
255
-                ...(_participant?.isFakeParticipant ? {} : {
255
+                ...(_participant?.fakeParticipant ? {} : {
256 256
                     audioMediaState,
257 257
                     videoMediaState: _videoMediaState
258 258
                 })
@@ -269,7 +269,7 @@ function MeetingParticipantItem({
269 269
             raisedHand = { _raisedHand }
270 270
             youText = { youText }>
271 271
 
272
-            {!overflowDrawer && !_participant?.isFakeParticipant
272
+            {!overflowDrawer && !_participant?.fakeParticipant
273 273
                 && <>
274 274
                     {!isInBreakoutRoom && (
275 275
                         <ParticipantQuickAction
@@ -286,7 +286,7 @@ function MeetingParticipantItem({
286 286
                 </>
287 287
             }
288 288
 
289
-            {!overflowDrawer && (_localVideoOwner || _participant?.isWhiteboard) && _participant?.isFakeParticipant && (
289
+            {!overflowDrawer && (_localVideoOwner || _participant?.fakeParticipant) && (
290 290
                 <ParticipantActionEllipsis
291 291
                     accessibilityLabel = { participantActionEllipsisLabel }
292 292
                     onClick = { onContextMenu } />

+ 2
- 2
react/features/participants-pane/components/web/MeetingParticipants.tsx Visa fil

@@ -13,7 +13,7 @@ import participantsPaneTheme from '../../../base/components/themes/participantsP
13 13
 // @ts-ignore
14 14
 import { isToolbarButtonEnabled } from '../../../base/config/functions.web';
15 15
 import { MEDIA_TYPE } from '../../../base/media/constants';
16
-import { getParticipantById } from '../../../base/participants/functions';
16
+import { getParticipantById, isScreenShareParticipant } from '../../../base/participants/functions';
17 17
 import { connect } from '../../../base/redux/functions';
18 18
 import { withPixelLineHeight } from '../../../base/styles/functions.web';
19 19
 import Input from '../../../base/ui/components/web/Input';
@@ -174,7 +174,7 @@ function _mapStateToProps(state: IState): Object {
174 174
     sortedParticipantIds = sortedParticipantIds.filter((id: any) => {
175 175
         const participant = getParticipantById(state, id);
176 176
 
177
-        return !participant?.isVirtualScreenshareParticipant;
177
+        return !isScreenShareParticipant(participant);
178 178
     });
179 179
 
180 180
     const participantsCount = sortedParticipantIds.length;

+ 3
- 2
react/features/remote-control/subscriber.js Visa fil

@@ -3,7 +3,8 @@
3 3
 import {
4 4
     getParticipantById,
5 5
     getVirtualScreenshareParticipantByOwnerId,
6
-    getVirtualScreenshareParticipantOwnerId
6
+    getVirtualScreenshareParticipantOwnerId,
7
+    isScreenShareParticipant
7 8
 } from '../base/participants';
8 9
 import { StateListenerRegistry } from '../base/redux';
9 10
 
@@ -24,7 +25,7 @@ StateListenerRegistry.register(
24 25
 
25 26
         const participant = getParticipantById(state, participantId);
26 27
 
27
-        if (participant?.isVirtualScreenshareParticipant) {
28
+        if (isScreenShareParticipant(participant)) {
28 29
             // multistream support is enabled and the user has selected the desktop sharing thumbnail.
29 30
             const id = getVirtualScreenshareParticipantOwnerId(participantId);
30 31
 

+ 3
- 2
react/features/shared-video/middleware.any.js Visa fil

@@ -13,6 +13,7 @@ import {
13 13
     participantLeft,
14 14
     pinParticipant
15 15
 } from '../base/participants';
16
+import { FakeParticipant } from '../base/participants/types';
16 17
 import { MiddlewareRegistry } from '../base/redux';
17 18
 
18 19
 import { RESET_SHARED_VIDEO_STATUS, SET_SHARED_VIDEO_STATUS } from './actionTypes';
@@ -55,7 +56,7 @@ MiddlewareRegistry.register(store => next => action => {
55 56
                     const videoParticipant = getParticipantById(state, value);
56 57
 
57 58
                     dispatch(participantLeft(value, conference, {
58
-                        isFakeParticipant: videoParticipant?.isFakeParticipant
59
+                        fakeParticipant: videoParticipant?.fakeParticipant
59 60
                     }));
60 61
 
61 62
                     if (localParticipantId !== from) {
@@ -162,8 +163,8 @@ function handleSharingVideoStatus(store, videoUrl, { state, time, from, muted },
162 163
 
163 164
         dispatch(participantJoined({
164 165
             conference,
166
+            fakeParticipant: FakeParticipant.SharedVideo,
165 167
             id: videoUrl,
166
-            isFakeParticipant: true,
167 168
             avatarURL,
168 169
             name: VIDEO_PLAYER_PARTICIPANT_NAME
169 170
         }));

+ 1
- 1
react/features/video-layout/functions.any.js Visa fil

@@ -124,7 +124,7 @@ export function updateAutoPinnedParticipant(
124 124
     const pinned = getPinnedParticipant(getState);
125 125
 
126 126
     // if the pinned participant is shared video or some other fake participant we want to skip auto-pinning
127
-    if (pinned?.isFakeParticipant) {
127
+    if (pinned?.fakeParticipant) {
128 128
         return;
129 129
     }
130 130
 

+ 1
- 1
react/features/video-layout/middleware.any.js Visa fil

@@ -39,7 +39,7 @@ MiddlewareRegistry.register(store => next => action => {
39 39
         if (!getAutoPinSetting() || isFollowMeActive(store)) {
40 40
             break;
41 41
         }
42
-        shouldUpdateAutoPin = getParticipantById(store.getState(), action.participant.id)?.isFakeParticipant;
42
+        shouldUpdateAutoPin = Boolean(getParticipantById(store.getState(), action.participant.id)?.fakeParticipant);
43 43
         break;
44 44
     }
45 45
     }

+ 8
- 5
react/features/video-menu/components/web/FakeParticipantContextMenu.tsx Visa fil

@@ -9,6 +9,7 @@ import TogglePinToStageButton from '../../../../features/video-menu/components/w
9 9
 // @ts-ignore
10 10
 import { Avatar } from '../../../base/avatar';
11 11
 import { IconShareVideo } from '../../../base/icons/svg';
12
+import { isWhiteboardParticipant } from '../../../base/participants/functions';
12 13
 import { Participant } from '../../../base/participants/types';
13 14
 import ContextMenu from '../../../base/ui/components/web/ContextMenu';
14 15
 import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
@@ -106,7 +107,7 @@ const FakeParticipantContextMenu = ({
106 107
     }, [ setWhiteboardOpen ]);
107 108
 
108 109
     const _getActions = useCallback(() => {
109
-        if (participant.isWhiteboard) {
110
+        if (isWhiteboardParticipant(participant)) {
110 111
             return [ {
111 112
                 accessibilityLabel: t('toolbar.hideWhiteboard'),
112 113
                 icon: IconShareVideo,
@@ -123,7 +124,7 @@ const FakeParticipantContextMenu = ({
123 124
                 text: t('toolbar.stopSharedVideo')
124 125
             } ];
125 126
         }
126
-    }, [ localVideoOwner, participant.isWhiteboard ]);
127
+    }, [ localVideoOwner, participant.fakeParticipant ]);
127 128
 
128 129
     return (
129 130
         <ContextMenu
@@ -148,9 +149,11 @@ const FakeParticipantContextMenu = ({
148 149
 
149 150
             <ContextMenuItemGroup
150 151
                 actions = { _getActions() }>
151
-                {participant.isWhiteboard && <TogglePinToStageButton
152
-                    key = 'pinToStage'
153
-                    participantID = { WHITEBOARD_ID } />}
152
+                {isWhiteboardParticipant(participant) && (
153
+                    <TogglePinToStageButton
154
+                        key = 'pinToStage'
155
+                        participantID = { WHITEBOARD_ID } />
156
+                )}
154 157
             </ContextMenuItemGroup>
155 158
 
156 159
         </ContextMenu>

+ 1
- 1
react/features/video-menu/components/web/RemoteVideoMenuTriggerButton.tsx Visa fil

@@ -250,7 +250,7 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
250 250
             thumbnailMenu: true
251 251
         };
252 252
 
253
-        if (_participant?.isFakeParticipant) {
253
+        if (_participant?.fakeParticipant) {
254 254
             return (
255 255
                 <FakeParticipantContextMenu
256 256
                     { ...props }

+ 5
- 5
react/features/whiteboard/middleware.ts Visa fil

@@ -13,7 +13,6 @@ import { RESET_WHITEBOARD, SET_WHITEBOARD_OPEN } from './actionTypes';
13 13
 import { getCollabDetails, getCollabServerUrl, isWhiteboardPresent } from './functions';
14 14
 import { WHITEBOARD_ID, WHITEBOARD_PARTICIPANT_NAME } from './constants';
15 15
 import { resetWhiteboard, setWhiteboardOpen, setupWhiteboard } from './actions';
16
-import { getCurrentRoomId } from '../breakout-rooms/functions';
17 16
 
18 17
 // @ts-ignore
19 18
 import { addStageParticipant } from '../filmstrip/actions.web';
@@ -21,6 +20,8 @@ import { addStageParticipant } from '../filmstrip/actions.web';
21 20
 // @ts-ignore
22 21
 import { isStageFilmstripAvailable } from '../filmstrip/functions';
23 22
 import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
23
+import { FakeParticipant } from '../base/participants/types';
24
+import { getCurrentRoomId } from '../breakout-rooms/functions';
24 25
 
25 26
 const focusWhiteboard = (store: IStore) => {
26 27
     const { dispatch, getState } = store;
@@ -32,9 +33,8 @@ const focusWhiteboard = (store: IStore) => {
32 33
     if (!isPresent) {
33 34
         dispatch(participantJoined({
34 35
             conference,
36
+            fakeParticipant: FakeParticipant.Whiteboard,
35 37
             id: WHITEBOARD_ID,
36
-            isFakeParticipant: true,
37
-            isWhiteboard: true,
38 38
             name: WHITEBOARD_PARTICIPANT_NAME
39 39
         }));
40 40
     }
@@ -85,11 +85,11 @@ MiddlewareRegistry.register((store: IStore) => (next: Function) => async (action
85 85
             return;
86 86
         }
87 87
 
88
-        dispatch(participantLeft(WHITEBOARD_ID, conference, { isWhiteboard: true }));
88
+        dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
89 89
         break;
90 90
     }
91 91
     case RESET_WHITEBOARD: {
92
-        dispatch(participantLeft(WHITEBOARD_ID, conference, { isWhiteboard: true }));
92
+        dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
93 93
         break;
94 94
     }
95 95
     }

Laddar…
Avbryt
Spara