Sfoglia il codice sorgente

feat(VideoLayout): add ninja icon

Add ninja icon which wil be displayed when user's connection status is
inactive.

Apply grey filter only for interrupted state.

Do not use isLastN directly, but check ParticipantConnectionStatus.
j8
paweldomas 8 anni fa
parent
commit
12d7e61362

+ 0
- 12
conference.js Vedi File

2125
         eventEmitter.removeListener(eventName, listener);
2125
         eventEmitter.removeListener(eventName, listener);
2126
     },
2126
     },
2127
 
2127
 
2128
-    /**
2129
-     * Checks if the participant given by participantId is currently in the
2130
-     * last N set if there's one supported.
2131
-     *
2132
-     * @param participantId the identifier of the participant
2133
-     * @returns {boolean} {true} if the participant given by the participantId
2134
-     * is currently in the last N set or if there's no last N set at this point
2135
-     * and {false} otherwise
2136
-     */
2137
-    isInLastN(participantId) {
2138
-        return room.isInLastN(participantId);
2139
-    },
2140
     /**
2128
     /**
2141
      * Changes the display name for the local user
2129
      * Changes the display name for the local user
2142
      * @param nickname {string} the new display name
2130
      * @param nickname {string} the new display name

+ 5
- 0
css/_videolayout_default.scss Vedi File

97
                     color: #FFFFFF;/*#15A1ED*/
97
                     color: #FFFFFF;/*#15A1ED*/
98
                     overflow: hidden;
98
                     overflow: hidden;
99
                 }
99
                 }
100
+
101
+                &_ninja
102
+                {
103
+                    font-size: 1.5em;
104
+                }
100
             }
105
             }
101
 
106
 
102
             .icon-connection,
107
             .icon-connection,

+ 28
- 15
modules/UI/videolayout/ConnectionIndicator.js Vedi File

1
-/* global $, APP, interfaceConfig */
1
+/* global $, APP, interfaceConfig, JitsiMeetJS */
2
 /* jshint -W101 */
2
 /* jshint -W101 */
3
 
3
 
4
 import JitsiPopover from "../util/JitsiPopover";
4
 import JitsiPopover from "../util/JitsiPopover";
5
 import UIUtil from "../util/UIUtil";
5
 import UIUtil from "../util/UIUtil";
6
 
6
 
7
+const ParticipantConnectionStatus
8
+    = JitsiMeetJS.constants.participantConnectionStatus;
9
+
7
 /**
10
 /**
8
  * Maps a connection quality value (in percent) to the width of the "full" icon.
11
  * Maps a connection quality value (in percent) to the width of the "full" icon.
9
  */
12
  */
334
         createIcon(["connection_full"], "icon-connection"));
337
         createIcon(["connection_full"], "icon-connection"));
335
     this.interruptedIndicator = connectionIconContainer.appendChild(
338
     this.interruptedIndicator = connectionIconContainer.appendChild(
336
         createIcon(["connection_lost"],"icon-connection-lost"));
339
         createIcon(["connection_lost"],"icon-connection-lost"));
340
+    this.ninjaIndicator = connectionIconContainer.appendChild(
341
+        createIcon(["connection_ninja"],"icon-ninja"));
337
 
342
 
338
     $(this.interruptedIndicator).hide();
343
     $(this.interruptedIndicator).hide();
344
+    $(this.ninjaIndicator).hide();
339
     this.connectionIndicatorContainer.appendChild(connectionIconContainer);
345
     this.connectionIndicatorContainer.appendChild(connectionIconContainer);
340
 };
346
 };
341
 
347
 
351
 };
357
 };
352
 
358
 
353
 /**
359
 /**
354
- * Updates the UI which displays warning about user's connectivity problems.
360
+ * Updates the UI which displays or not a warning about user's connectivity
361
+ * problems.
355
  *
362
  *
356
- * @param {boolean} isActive true if the connection is working fine or false if
357
- * the user is having connectivity issues.
363
+ * @param {ParticipantConnectionStatus} connectionStatus
358
  */
364
  */
359
 ConnectionIndicator.prototype.updateConnectionStatusIndicator
365
 ConnectionIndicator.prototype.updateConnectionStatusIndicator
360
-    = function (isActive) {
361
-        this.isConnectionActive = isActive;
362
-        if (this.isConnectionActive) {
363
-            $(this.interruptedIndicator).hide();
364
-            $(this.emptyIcon).show();
365
-            $(this.fullIcon).show();
366
-        } else {
367
-            $(this.interruptedIndicator).show();
368
-            $(this.emptyIcon).hide();
369
-            $(this.fullIcon).hide();
370
-        }
366
+= function (connectionStatus) {
367
+    this.connectionStatus = connectionStatus;
368
+    if (connectionStatus === ParticipantConnectionStatus.INTERRUPTED) {
369
+        $(this.interruptedIndicator).show();
370
+        $(this.emptyIcon).hide();
371
+        $(this.fullIcon).hide();
372
+        $(this.ninjaIndicator).hide();
373
+    } else if (connectionStatus === ParticipantConnectionStatus.INACTIVE) {
374
+        $(this.interruptedIndicator).hide();
375
+        $(this.emptyIcon).hide();
376
+        $(this.fullIcon).hide();
377
+        $(this.ninjaIndicator).show();
378
+    } else {
379
+        $(this.interruptedIndicator).hide();
380
+        $(this.emptyIcon).show();
381
+        $(this.fullIcon).show();
382
+        $(this.ninjaIndicator).hide();
383
+    }
371
 };
384
 };
372
 
385
 
373
 /**
386
 /**

+ 72
- 52
modules/UI/videolayout/LargeVideoManager.js Vedi File

26
  * Manager for all Large containers.
26
  * Manager for all Large containers.
27
  */
27
  */
28
 export default class LargeVideoManager {
28
 export default class LargeVideoManager {
29
+    /**
30
+     * Checks whether given container is a {@link VIDEO_CONTAINER_TYPE}.
31
+     * FIXME currently this is a workaround for the problem where video type is
32
+     * mixed up with container type.
33
+     * @param {string} containerType
34
+     * @return {boolean}
35
+     */
36
+    static isVideoContainer(containerType) {
37
+        return containerType === VIDEO_CONTAINER_TYPE
38
+            || containerType === DESKTOP_CONTAINER_TYPE;
39
+    }
40
+
29
     constructor (emitter) {
41
     constructor (emitter) {
30
         /**
42
         /**
31
          * The map of <tt>LargeContainer</tt>s where the key is the video
43
          * The map of <tt>LargeContainer</tt>s where the key is the video
116
         this.enableLocalConnectionProblemFilter(true);
128
         this.enableLocalConnectionProblemFilter(true);
117
         this._setLocalConnectionMessage("connection.RECONNECTING");
129
         this._setLocalConnectionMessage("connection.RECONNECTING");
118
         // Show the message only if the video is currently being displayed
130
         // Show the message only if the video is currently being displayed
119
-        this.showLocalConnectionMessage(this.state === VIDEO_CONTAINER_TYPE);
131
+        this.showLocalConnectionMessage(
132
+            LargeVideoManager.isVideoContainer(this.state));
120
     }
133
     }
121
 
134
 
122
     /**
135
     /**
146
 
159
 
147
         preUpdate.then(() => {
160
         preUpdate.then(() => {
148
             const { id, stream, videoType, resolve } = this.newStreamData;
161
             const { id, stream, videoType, resolve } = this.newStreamData;
149
-            const isVideoFromCamera = videoType === VIDEO_CONTAINER_TYPE;
162
+
163
+            // FIXME this does not really make sense, because the videoType
164
+            // (camera or desktop) is a completely different thing than
165
+            // the video container type (Etherpad, SharedVideo, VideoContainer).
166
+            const isVideoContainer
167
+                = LargeVideoManager.isVideoContainer(videoType);
150
 
168
 
151
             this.newStreamData = null;
169
             this.newStreamData = null;
152
 
170
 
158
             // change the avatar url on large
176
             // change the avatar url on large
159
             this.updateAvatar(Avatar.getAvatarUrl(id));
177
             this.updateAvatar(Avatar.getAvatarUrl(id));
160
 
178
 
161
-            // FIXME that does not really make sense, because the videoType
162
-            // (camera or desktop) is a completely different thing than
163
-            // the video container type (Etherpad, SharedVideo, VideoContainer).
164
-            // ----------------------------------------------------------------
165
-            // If the container is VIDEO_CONTAINER_TYPE, we need to check
166
-            // its stream whether exist and is muted to set isVideoMuted
167
-            // in rest of the cases it is false
168
-            let showAvatar = isVideoFromCamera && (!stream || stream.isMuted());
169
-
170
             // If the user's connection is disrupted then the avatar will be
179
             // If the user's connection is disrupted then the avatar will be
171
             // displayed in case we have no video image cached. That is if
180
             // displayed in case we have no video image cached. That is if
172
-            // there was a user switch(image is lost on stream detach) or if
181
+            // there was a user switch (image is lost on stream detach) or if
173
             // the video was not rendered, before the connection has failed.
182
             // the video was not rendered, before the connection has failed.
174
-            const isConnectionActive = this._isConnectionActive(id);
175
-
176
-            if (isVideoFromCamera
177
-                    && !isConnectionActive
178
-                    && (isUserSwitch || !container.wasVideoRendered)) {
179
-                showAvatar = true;
180
-            }
181
-
182
-            // If audio only mode is enabled, always show the avatar for
183
-            // videos from another participant.
184
-            if (APP.conference.isAudioOnly()
185
-                && (isVideoFromCamera
186
-                    || videoType === DESKTOP_CONTAINER_TYPE)) {
187
-                showAvatar = true;
188
-            }
183
+            const wasUsersImageCached
184
+                = !isUserSwitch && container.wasVideoRendered;
185
+            const isVideoMuted = !stream || stream.isMuted();
186
+
187
+            const connectionStatus
188
+                = APP.conference.getParticipantConnectionStatus(id);
189
+            const isVideoRenderable
190
+                = !isVideoMuted
191
+                    && (APP.conference.isLocalId(id)
192
+                        || connectionStatus
193
+                                === ParticipantConnectionStatus.ACTIVE
194
+                        || wasUsersImageCached);
195
+
196
+            let showAvatar
197
+                = isVideoContainer
198
+                    && (APP.conference.isAudioOnly() || !isVideoRenderable);
189
 
199
 
190
             let promise;
200
             let promise;
191
 
201
 
208
                 this.updateLargeVideoAudioLevel(0);
218
                 this.updateLargeVideoAudioLevel(0);
209
             }
219
             }
210
 
220
 
221
+            const isConnectionInterrupted
222
+                = APP.conference.getParticipantConnectionStatus(id)
223
+                    === ParticipantConnectionStatus.INTERRUPTED;
224
+            let messageKey = null;
225
+
226
+            if (isConnectionInterrupted) {
227
+                messageKey = "connection.USER_CONNECTION_INTERRUPTED";
228
+            } else if (connectionStatus
229
+                    === ParticipantConnectionStatus.INACTIVE) {
230
+                messageKey = "connection.LOW_BANDWIDTH";
231
+            }
232
+
211
             // Make sure no notification about remote failure is shown as
233
             // Make sure no notification about remote failure is shown as
212
             // its UI conflicts with the one for local connection interrupted.
234
             // its UI conflicts with the one for local connection interrupted.
213
             // For the purposes of UI indicators, audio only is considered as
235
             // For the purposes of UI indicators, audio only is considered as
214
             // an "active" connection.
236
             // an "active" connection.
215
-            const isConnected
237
+            const overrideAndHide
216
                 = APP.conference.isAudioOnly()
238
                 = APP.conference.isAudioOnly()
217
-                    || APP.conference.isConnectionInterrupted()
218
-                    || isConnectionActive;
219
-
220
-            // when isHavingConnectivityIssues, state can be inactive,
221
-            // interrupted or restoring. We show different message for
222
-            // interrupted and the rest.
223
-            const isConnectionInterrupted =
224
-                APP.conference.getParticipantConnectionStatus(id)
225
-                    === ParticipantConnectionStatus.INTERRUPTED;
239
+                    || APP.conference.isConnectionInterrupted();
226
 
240
 
227
             this.updateParticipantConnStatusIndication(
241
             this.updateParticipantConnStatusIndication(
228
                     id,
242
                     id,
229
-                    isConnected,
230
-                    (isConnectionInterrupted)
231
-                        ? "connection.USER_CONNECTION_INTERRUPTED"
232
-                        : "connection.LOW_BANDWIDTH");
243
+                    !overrideAndHide && isConnectionInterrupted,
244
+                    !overrideAndHide && messageKey !== null,
245
+                    messageKey);
233
 
246
 
234
             // resolve updateLargeVideo promise after everything is done
247
             // resolve updateLargeVideo promise after everything is done
235
             promise.then(resolve);
248
             promise.then(resolve);
265
      * shown on the large video area.
278
      * shown on the large video area.
266
      *
279
      *
267
      * @param {string} id the id of remote participant(MUC nickname)
280
      * @param {string} id the id of remote participant(MUC nickname)
268
-     * @param {boolean} isConnected true if the connection is active or false
269
-     * when the user is having connectivity issues.
281
+     * @param {boolean} showProblemsIndication
282
+     * @param {boolean} showMessage
270
      * @param {string} messageKey the i18n key of the message
283
      * @param {string} messageKey the i18n key of the message
271
      *
284
      *
272
      * @private
285
      * @private
273
      */
286
      */
274
-    updateParticipantConnStatusIndication (id, isConnected, messageKey) {
287
+    updateParticipantConnStatusIndication (
288
+        id, showProblemsIndication, showMessage, messageKey) {
275
 
289
 
276
         // Apply grey filter on the large video
290
         // Apply grey filter on the large video
277
-        this.videoContainer.showRemoteConnectionProblemIndicator(!isConnected);
291
+        this.videoContainer.showRemoteConnectionProblemIndicator(
292
+            showProblemsIndication);
278
 
293
 
279
-        if (isConnected) {
294
+        if (!showMessage) {
280
             // Hide the message
295
             // Hide the message
281
             this.showRemoteConnectionMessage(false);
296
             this.showRemoteConnectionMessage(false);
282
         } else {
297
         } else {
289
 
304
 
290
             // Show it now only if the VideoContainer is on top
305
             // Show it now only if the VideoContainer is on top
291
             this.showRemoteConnectionMessage(
306
             this.showRemoteConnectionMessage(
292
-                this.state === VIDEO_CONTAINER_TYPE);
307
+                LargeVideoManager.isVideoContainer(this.state));
293
         }
308
         }
294
     }
309
     }
295
 
310
 
412
      * Shows hides the "avatar" message which is to be displayed either in
427
      * Shows hides the "avatar" message which is to be displayed either in
413
      * the middle of the screen or below the avatar image.
428
      * the middle of the screen or below the avatar image.
414
      *
429
      *
415
-     * @param {null|boolean} show (optional) <tt>true</tt> to show the avatar
430
+     * @param {null|boolean} [show=null] <tt>true</tt> to show the avatar
416
      * message or <tt>false</tt> to hide it. If not provided then the connection
431
      * message or <tt>false</tt> to hide it. If not provided then the connection
417
      * status of the user currently on the large video will be obtained form
432
      * status of the user currently on the large video will be obtained form
418
      * "APP.conference" and the message will be displayed if the user's
433
      * "APP.conference" and the message will be displayed if the user's
419
-     * connection is interrupted.
434
+     * connection is either interrupted or inactive.
420
      */
435
      */
421
     showRemoteConnectionMessage (show) {
436
     showRemoteConnectionMessage (show) {
422
         if (typeof show !== 'boolean') {
437
         if (typeof show !== 'boolean') {
423
-            show = !this._isConnectionActive(this.id);
438
+            const connStatus
439
+                = APP.conference.getParticipantConnectionStatus(this.id);
440
+
441
+            show = !APP.conference.isLocalId(this.id)
442
+                && (connStatus === ParticipantConnectionStatus.INTERRUPTED
443
+                    || connStatus === ParticipantConnectionStatus.INACTIVE);
424
         }
444
         }
425
 
445
 
426
         if (show) {
446
         if (show) {
526
         // FIXME when video is being replaced with other content we need to hide
546
         // FIXME when video is being replaced with other content we need to hide
527
         // companion icons/messages. It would be best if the container would
547
         // companion icons/messages. It would be best if the container would
528
         // be taking care of it by itself, but that is a bigger refactoring
548
         // be taking care of it by itself, but that is a bigger refactoring
529
-        if (this.state === VIDEO_CONTAINER_TYPE) {
549
+        if (LargeVideoManager.isVideoContainer(this.state)) {
530
             this.showWatermark(false);
550
             this.showWatermark(false);
531
             this.showLocalConnectionMessage(false);
551
             this.showLocalConnectionMessage(false);
532
             this.showRemoteConnectionMessage(false);
552
             this.showRemoteConnectionMessage(false);
537
         let container = this.getContainer(type);
557
         let container = this.getContainer(type);
538
 
558
 
539
         return container.show().then(() => {
559
         return container.show().then(() => {
540
-            if (type === VIDEO_CONTAINER_TYPE) {
560
+            if (LargeVideoManager.isVideoContainer(type)) {
541
                 // FIXME when video appears on top of other content we need to
561
                 // FIXME when video appears on top of other content we need to
542
                 // show companion icons/messages. It would be best if
562
                 // show companion icons/messages. It would be best if
543
                 // the container would be taking care of it by itself, but that
563
                 // the container would be taking care of it by itself, but that

+ 23
- 26
modules/UI/videolayout/RemoteVideo.js Vedi File

448
 
448
 
449
 /**
449
 /**
450
  * @inheritDoc
450
  * @inheritDoc
451
+ * @override
451
  */
452
  */
452
-RemoteVideo.prototype.setMutedView = function(isMuted) {
453
-    SmallVideo.prototype.setMutedView.call(this, isMuted);
453
+RemoteVideo.prototype.setVideoMutedView = function(isMuted) {
454
+    SmallVideo.prototype.setVideoMutedView.call(this, isMuted);
454
     // Update 'mutedWhileDisconnected' flag
455
     // Update 'mutedWhileDisconnected' flag
455
-    this._figureOutMutedWhileDisconnected(this.isConnectionInterrupted());
456
+    this._figureOutMutedWhileDisconnected();
456
 };
457
 };
457
 
458
 
458
 /**
459
 /**
459
  * Figures out the value of {@link #mutedWhileDisconnected} flag by taking into
460
  * Figures out the value of {@link #mutedWhileDisconnected} flag by taking into
460
  * account remote participant's network connectivity and video muted status.
461
  * account remote participant's network connectivity and video muted status.
461
  *
462
  *
462
- * @param {boolean} isDisconnected <tt>true</tt> if the remote participant is
463
- * currently having connectivity issues or <tt>false</tt> otherwise.
464
- *
465
  * @private
463
  * @private
466
  */
464
  */
467
-RemoteVideo.prototype._figureOutMutedWhileDisconnected
468
-    = function(isDisconnected) {
469
-        if (isDisconnected && this.isVideoMuted) {
470
-            this.mutedWhileDisconnected = true;
471
-        } else if (!isDisconnected && !this.isVideoMuted) {
472
-            this.mutedWhileDisconnected = false;
473
-        }
465
+RemoteVideo.prototype._figureOutMutedWhileDisconnected = function() {
466
+    const isActive = this.isConnectionActive();
467
+    if (!isActive && this.isVideoMuted) {
468
+        this.mutedWhileDisconnected = true;
469
+    } else if (isActive && !this.isVideoMuted) {
470
+        this.mutedWhileDisconnected = false;
471
+    }
474
 };
472
 };
475
 
473
 
476
 /**
474
 /**
572
  * Updates the UI to reflect user's connectivity status.
570
  * Updates the UI to reflect user's connectivity status.
573
  */
571
  */
574
 RemoteVideo.prototype.updateConnectionStatusIndicator = function () {
572
 RemoteVideo.prototype.updateConnectionStatusIndicator = function () {
575
-    const isActive = this.isConnectionActive();
573
+    const connectionStatus = this.user.getConnectionStatus();
576
 
574
 
577
-    if (isActive === null) {
578
-        // Cancel processing at this point - no update
579
-        return;
580
-    }
581
-
582
-    logger.debug(this.id + " thumbnail is connection active ? " + isActive);
575
+    logger.debug(`${this.id} thumbnail connection status: ${connectionStatus}`);
583
 
576
 
577
+    // FIXME rename 'mutedWhileDisconnected' to 'mutedWhileNotRendering'
584
     // Update 'mutedWhileDisconnected' flag
578
     // Update 'mutedWhileDisconnected' flag
585
-    this._figureOutMutedWhileDisconnected(!isActive);
586
-
587
-    if(this.connectionIndicator)
588
-        this.connectionIndicator.updateConnectionStatusIndicator(isActive);
579
+    this._figureOutMutedWhileDisconnected();
580
+    if(this.connectionIndicator) {
581
+        this.connectionIndicator.updateConnectionStatusIndicator(
582
+            connectionStatus);
583
+    }
589
 
584
 
585
+    const isInterrupted
586
+        = connectionStatus === ParticipantConnectionStatus.INTERRUPTED;
590
     // Toggle thumbnail video problem filter
587
     // Toggle thumbnail video problem filter
591
     this.selectVideoElement().toggleClass(
588
     this.selectVideoElement().toggleClass(
592
-        "videoThumbnailProblemFilter", !isActive);
589
+        "videoThumbnailProblemFilter", isInterrupted);
593
     this.$avatar().toggleClass(
590
     this.$avatar().toggleClass(
594
-        "videoThumbnailProblemFilter", !isActive);
591
+        "videoThumbnailProblemFilter", isInterrupted);
595
 };
592
 };
596
 
593
 
597
 /**
594
 /**

+ 7
- 1
modules/UI/videolayout/SmallVideo.js Vedi File

6
 import UIEvents from "../../../service/UI/UIEvents";
6
 import UIEvents from "../../../service/UI/UIEvents";
7
 import AudioLevels from "../audio_levels/AudioLevels";
7
 import AudioLevels from "../audio_levels/AudioLevels";
8
 
8
 
9
+const ParticipantConnectionStatus
10
+    = JitsiMeetJS.constants.participantConnectionStatus;
9
 const RTCUIHelper = JitsiMeetJS.util.RTCUIHelper;
11
 const RTCUIHelper = JitsiMeetJS.util.RTCUIHelper;
10
 
12
 
11
 /**
13
 /**
444
  * or <tt>false</tt> otherwise.
446
  * or <tt>false</tt> otherwise.
445
  */
447
  */
446
 SmallVideo.prototype.isVideoPlayable = function() {
448
 SmallVideo.prototype.isVideoPlayable = function() {
449
+    const connectionState
450
+        = APP.conference.getParticipantConnectionStatus(this.id);
451
+
447
     return this.videoStream // Is there anything to display ?
452
     return this.videoStream // Is there anything to display ?
448
         && !this.isVideoMuted && !this.videoStream.isMuted() // Muted ?
453
         && !this.isVideoMuted && !this.videoStream.isMuted() // Muted ?
449
-        && (this.isLocal || APP.conference.isInLastN(this.id));
454
+        && (this.isLocal
455
+                || connectionState === ParticipantConnectionStatus.ACTIVE);
450
 };
456
 };
451
 
457
 
452
 /**
458
 /**

+ 14
- 3
modules/UI/videolayout/VideoLayout.js Vedi File

1
-/* global APP, $, interfaceConfig */
1
+/* global APP, $, interfaceConfig, JitsiMeetJS  */
2
 const logger = require("jitsi-meet-logger").getLogger(__filename);
2
 const logger = require("jitsi-meet-logger").getLogger(__filename);
3
 
3
 
4
 import Filmstrip from "./Filmstrip";
4
 import Filmstrip from "./Filmstrip";
10
 import {VIDEO_CONTAINER_TYPE} from "./VideoContainer";
10
 import {VIDEO_CONTAINER_TYPE} from "./VideoContainer";
11
 import LocalVideo from "./LocalVideo";
11
 import LocalVideo from "./LocalVideo";
12
 
12
 
13
+const ParticipantConnectionStatus
14
+    = JitsiMeetJS.constants.participantConnectionStatus;
15
+
13
 var remoteVideos = {};
16
 var remoteVideos = {};
14
 var localVideoThumbnail = null;
17
 var localVideoThumbnail = null;
15
 
18
 
559
      * is fine.
562
      * is fine.
560
      */
563
      */
561
     showLocalConnectionInterrupted (isInterrupted) {
564
     showLocalConnectionInterrupted (isInterrupted) {
562
-        localVideoThumbnail.connectionIndicator
563
-            .updateConnectionStatusIndicator(!isInterrupted);
565
+        // Currently local video thumbnail displays only "active" or
566
+        // "interrupted" despite the fact that ConnectionIndicator supports more
567
+        // states.
568
+        const status
569
+            = isInterrupted
570
+                ? ParticipantConnectionStatus.INTERRUPTED
571
+                : ParticipantConnectionStatus.ACTIVE;
572
+
573
+        localVideoThumbnail
574
+            .connectionIndicator.updateConnectionStatusIndicator(status);
564
     },
575
     },
565
 
576
 
566
     /**
577
     /**

Loading…
Annulla
Salva