|
@@ -299,14 +299,14 @@ export function isLocalParticipantModerator(
|
299
|
299
|
|
300
|
300
|
/**
|
301
|
301
|
* Returns true if the video of the participant should be rendered.
|
|
302
|
+ * NOTE: This is currently only used on mobile.
|
302
|
303
|
*
|
303
|
304
|
* @param {Object|Function} stateful - Object or function that can be resolved
|
304
|
305
|
* to the Redux state.
|
305
|
306
|
* @param {string} id - The ID of the participant.
|
306
|
307
|
* @returns {boolean}
|
307
|
308
|
*/
|
308
|
|
-export function shouldRenderParticipantVideo(
|
309
|
|
- stateful: Object | Function, id: string) {
|
|
309
|
+export function shouldRenderParticipantVideo(stateful: Object | Function, id: string) {
|
310
|
310
|
const state = toState(stateful);
|
311
|
311
|
const participant = getParticipantById(state, id);
|
312
|
312
|
|
|
@@ -314,29 +314,35 @@ export function shouldRenderParticipantVideo(
|
314
|
314
|
return false;
|
315
|
315
|
}
|
316
|
316
|
|
|
317
|
+ /* First check if we have an unmuted video track. */
|
|
318
|
+ const videoTrack
|
|
319
|
+ = getTrackByMediaTypeAndParticipant(state['features/base/tracks'], MEDIA_TYPE.VIDEO, id);
|
|
320
|
+
|
|
321
|
+ if (!shouldRenderVideoTrack(videoTrack, /* waitForVideoStarted */ false)) {
|
|
322
|
+ return false;
|
|
323
|
+ }
|
|
324
|
+
|
|
325
|
+ /* Then check if the participant connection is active. */
|
|
326
|
+ const connectionStatus = participant.connectionStatus || JitsiParticipantConnectionStatus.ACTIVE;
|
|
327
|
+
|
|
328
|
+ if (connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE) {
|
|
329
|
+ return false;
|
|
330
|
+ }
|
|
331
|
+
|
|
332
|
+ /* Then check if audio-only mode is not active. */
|
317
|
333
|
const audioOnly = state['features/base/audio-only'].enabled;
|
318
|
|
- const connectionStatus = participant.connectionStatus
|
319
|
|
- || JitsiParticipantConnectionStatus.ACTIVE;
|
320
|
|
- const videoTrack = getTrackByMediaTypeAndParticipant(
|
321
|
|
- state['features/base/tracks'],
|
322
|
|
- MEDIA_TYPE.VIDEO,
|
323
|
|
- id);
|
324
|
|
-
|
325
|
|
- // Is the video to be rendered?
|
326
|
|
- // FIXME It's currently impossible to have true as the value of
|
327
|
|
- // waitForVideoStarted because videoTrack's state videoStarted will be
|
328
|
|
- // updated only after videoTrack is rendered.
|
329
|
|
- // XXX Note that, unlike on web, we don't render video when the
|
330
|
|
- // connection status is interrupted, this is because the renderer
|
331
|
|
- // doesn't retain the last frame forever, so we would end up with a
|
332
|
|
- // black screen.
|
333
|
|
- const waitForVideoStarted = false;
|
334
|
|
-
|
335
|
|
- return !audioOnly
|
336
|
|
- && (connectionStatus
|
337
|
|
- === JitsiParticipantConnectionStatus.ACTIVE)
|
338
|
|
- && shouldRenderVideoTrack(videoTrack, waitForVideoStarted);
|
339
|
334
|
|
|
335
|
+ if (!audioOnly) {
|
|
336
|
+ return true;
|
|
337
|
+ }
|
|
338
|
+
|
|
339
|
+ /* Last, check if the participant is sharing their screen and they are on stage. */
|
|
340
|
+ const screenShares = state['features/video-layout'].screenShares || [];
|
|
341
|
+ const largeVideoParticipantId = state['features/large-video'].participantId;
|
|
342
|
+ const participantIsInLargeVideoWithScreen
|
|
343
|
+ = participant.id === largeVideoParticipantId && screenShares.includes(participant.id);
|
|
344
|
+
|
|
345
|
+ return participantIsInLargeVideoWithScreen;
|
340
|
346
|
}
|
341
|
347
|
|
342
|
348
|
/**
|