Parcourir la source

Implements "raised hand".

j8
Boris Grozev il y a 8 ans
Parent
révision
2d2e27b8d0

+ 50
- 0
conference.js Voir le fichier

@@ -394,6 +394,14 @@ export default {
394 394
     videoMuted: false,
395 395
     isSharingScreen: false,
396 396
     isDesktopSharingEnabled: false,
397
+    /*
398
+     * Whether the local "raisedHand" flag is on.
399
+     */
400
+    isHandRaised: false,
401
+    /*
402
+     * Whether the local participant is the dominant speaker in the conference.
403
+     */
404
+    isDominantSpeaker: false,
397 405
     /**
398 406
      * Open new connection and join to the conference.
399 407
      * @param {object} options
@@ -1018,6 +1026,16 @@ export default {
1018 1026
             APP.UI.handleLastNEndpoints(ids, enteringIds);
1019 1027
         });
1020 1028
         room.on(ConferenceEvents.DOMINANT_SPEAKER_CHANGED, (id) => {
1029
+            if (this.isLocalId(id)) {
1030
+                this.isDominantSpeaker = true;
1031
+                this.setRaisedHand(false);
1032
+            } else {
1033
+                this.isDominantSpeaker = false;
1034
+                var participant = room.getParticipantById(id);
1035
+                if (participant) {
1036
+                    APP.UI.setRaisedHandStatus(participant, false);
1037
+                }
1038
+            }
1021 1039
             APP.UI.markDominantSpeaker(id);
1022 1040
         });
1023 1041
 
@@ -1040,6 +1058,13 @@ export default {
1040 1058
             APP.UI.changeDisplayName(id, displayName);
1041 1059
         });
1042 1060
 
1061
+        room.on(ConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
1062
+                (participant, name, oldValue, newValue) => {
1063
+            if (name === "raisedHand") {
1064
+                APP.UI.setRaisedHandStatus(participant, newValue);
1065
+            }
1066
+        });
1067
+
1043 1068
         room.on(ConferenceEvents.RECORDER_STATE_CHANGED, (status, error) => {
1044 1069
             console.log("Received recorder status change: ", status, error);
1045 1070
             APP.UI.updateRecordingState(status);
@@ -1432,5 +1457,30 @@ export default {
1432 1457
                 mediaDeviceHelper.setCurrentMediaDevices(devices);
1433 1458
                 APP.UI.onAvailableDevicesChanged(devices);
1434 1459
             });
1460
+    },
1461
+
1462
+    /**
1463
+     * Toggles the local "raised hand" status, if the current state allows
1464
+     * toggling.
1465
+     */
1466
+    maybeToggleRaisedHand() {
1467
+        // If we are the dominant speaker, we don't enable "raise hand".
1468
+        if (this.isHandRaised || !this.isDominantSpeaker) {
1469
+            this.setRaisedHand(!this.isHandRaised);
1470
+        }
1471
+    },
1472
+
1473
+    /**
1474
+     * Sets the local "raised hand" status to a particular value.
1475
+     */
1476
+    setRaisedHand(raisedHand) {
1477
+        if (raisedHand !== this.isHandRaised)
1478
+        {
1479
+            this.isHandRaised = raisedHand;
1480
+            // Advertise the updated status
1481
+            room.setLocalParticipantProperty("raisedHand", raisedHand);
1482
+            // Update the view
1483
+            APP.UI.setLocalRaisedHandStatus(raisedHand);
1484
+        }
1435 1485
     }
1436 1486
 };

+ 2
- 2
css/videolayout_default.css Voir le fichier

@@ -310,7 +310,7 @@
310 310
     z-index: 3;
311 311
 }
312 312
 
313
-.videocontainer>span.dominantspeakerindicator {
313
+.videocontainer>span.indicator {
314 314
     bottom: 0px;
315 315
     left: 0px;
316 316
     width: 25px;
@@ -327,7 +327,7 @@
327 327
     border: 0px;
328 328
 }
329 329
 
330
-#speakerindicatoricon {
330
+#indicatoricon {
331 331
     padding-top: 5px;
332 332
 }
333 333
 

+ 3
- 1
lang/main.json Voir le fichier

@@ -8,6 +8,7 @@
8 8
     "participant": "Participant",
9 9
     "me": "me",
10 10
     "speaker": "Speaker",
11
+    "raisedHand": "Would like to speak",
11 12
     "defaultNickname": "ex. Jane Pink",
12 13
     "defaultLink": "e.g. __url__",
13 14
     "calling": "Calling __name__ ...",
@@ -154,7 +155,8 @@
154 155
         "grantedTo": "Moderator rights granted to __to__!",
155 156
         "grantedToUnknown": "Moderator rights granted to $t(somebody)!",
156 157
         "muted": "You have started the conversation muted.",
157
-        "mutedTitle": "You're muted!"
158
+        "mutedTitle": "You're muted!",
159
+        "raisedHand": "Would like to speak."
158 160
     },
159 161
     "dialog": {
160 162
         "kickMessage": "Ouch! You have been kicked out of the meet!",

+ 19
- 1
modules/UI/UI.js Voir le fichier

@@ -255,7 +255,25 @@ UI.changeDisplayName = function (id, displayName) {
255 255
 };
256 256
 
257 257
 /**
258
- * Intitialize conference UI.
258
+ * Sets the "raised hand" status for a participant.
259
+ */
260
+UI.setRaisedHandStatus = (participant, raisedHandStatus) => {
261
+    VideoLayout.setRaisedHandStatus(participant.getId(), raisedHandStatus);
262
+    if (raisedHandStatus) {
263
+        messageHandler.notify(participant.getDisplayName(), 'notify.somebody',
264
+                          'connected', 'notify.raisedHand');
265
+    }
266
+};
267
+
268
+/**
269
+ * Sets the local "raised hand" status.
270
+ */
271
+UI.setLocalRaisedHandStatus = (raisedHandStatus) => {
272
+    VideoLayout.setRaisedHandStatus(APP.conference.localId, raisedHandStatus);
273
+};
274
+
275
+/**
276
+ * Initialize conference UI.
259 277
  */
260 278
 UI.initConference = function () {
261 279
     let id = APP.conference.localId;

+ 9
- 6
modules/UI/util/MessageHandler.js Voir le fichier

@@ -215,16 +215,19 @@ var messageHandler = {
215 215
     },
216 216
 
217 217
     /**
218
-     * Displayes notification.
219
-     * @param displayName display name of the participant that is associated with the notification.
220
-     * @param displayNameKey the key from the language file for the display name.
218
+     * Displays a notification.
219
+     * @param displayName the display name of the participant that is
220
+     * associated with the notification.
221
+     * @param displayNameKey the key from the language file for the display
222
+     * name. Only used if displayName i not provided.
221 223
      * @param cls css class for the notification
222
-     * @param messageKey the key from the language file for the text of the message.
224
+     * @param messageKey the key from the language file for the text of the
225
+     * message.
223 226
      * @param messageArguments object with the arguments for the message.
224 227
      * @param options object with language options.
225 228
      */
226
-    notify: function(displayName, displayNameKey,
227
-                         cls, messageKey, messageArguments, options) {
229
+    notify: function(displayName, displayNameKey, cls, messageKey,
230
+                     messageArguments, options) {
228 231
 
229 232
         if(!notificationsEnabled)
230 233
             return;

+ 51
- 19
modules/UI/videolayout/SmallVideo.js Voir le fichier

@@ -422,37 +422,69 @@ SmallVideo.prototype.avatarChanged = function (avatarUrl) {
422 422
 };
423 423
 
424 424
 /**
425
- * Updates the Indicator for dominant speaker.
426
- *
427
- * @param isSpeaker indicates the current indicator state
425
+ * Shows or hides the dominant speaker indicator.
426
+ * @param show whether to show or hide.
428 427
  */
429
-SmallVideo.prototype.updateDominantSpeakerIndicator = function (isSpeaker) {
430
-
428
+SmallVideo.prototype.showDominantSpeakerIndicator = function (show) {
431 429
     if (!this.container) {
432 430
         console.warn( "Unable to set dominant speaker indicator - "
433 431
             + this.videoSpanId + " does not exist");
434 432
         return;
435 433
     }
436 434
 
437
-    var indicatorSpan
438
-        = $('#' + this.videoSpanId + '>span.dominantspeakerindicator');
439
-
440
-    // If we do not have an indicator for this video.
441
-    if (indicatorSpan.length <= 0) {
442
-        indicatorSpan = document.createElement('span');
435
+    var indicatorSpanId = "dominantspeakerindicator";
436
+    var indicatorSpan = this.getIndicatorSpan(indicatorSpanId);
443 437
 
444
-        indicatorSpan.innerHTML
445
-            = "<i id='speakerindicatoricon' class='fa fa-bullhorn'></i>";
446
-        indicatorSpan.className = 'dominantspeakerindicator';
438
+    indicatorSpan.innerHTML
439
+        = "<i id='indicatoricon' class='fa fa-bullhorn'></i>";
440
+    // adds a tooltip
441
+    UIUtil.setTooltip(indicatorSpan, "speaker", "left");
442
+    APP.translation.translateElement($(indicatorSpan));
447 443
 
448
-        $('#' + this.videoSpanId)[0].appendChild(indicatorSpan);
444
+    $(indicatorSpan).css("visibility", show ? "visible" : "hidden");
445
+};
449 446
 
450
-        // adds a tooltip
451
-        UIUtil.setTooltip(indicatorSpan, "speaker", "left");
452
-        APP.translation.translateElement($(indicatorSpan));
447
+/**
448
+ * Shows or hides the raised hand indicator.
449
+ * @param show whether to show or hide.
450
+ */
451
+SmallVideo.prototype.showRaisedHandIndicator = function (show) {
452
+    if (!this.container) {
453
+        console.warn( "Unable to raised hand indication - "
454
+            + this.videoSpanId + " does not exist");
455
+        return;
453 456
     }
454 457
 
455
-    $(indicatorSpan).css("visibility", isSpeaker ? "visible" : "hidden");
458
+    var indicatorSpanId = "raisehandindicator";
459
+    var indicatorSpan = this.getIndicatorSpan(indicatorSpanId);
460
+
461
+    indicatorSpan.style.background = "#D6D61E";
462
+    indicatorSpan.innerHTML
463
+        = "<i id='indicatoricon' class='fa fa-hand-paper-o'></i>";
464
+
465
+    // adds a tooltip
466
+    UIUtil.setTooltip(indicatorSpan, "raisedHand", "left");
467
+    APP.translation.translateElement($(indicatorSpan));
468
+
469
+    $(indicatorSpan).css("visibility", show ? "visible" : "hidden");
470
+};
471
+
472
+/**
473
+ * Gets (creating if necessary) the "indicator" span for this SmallVideo
474
+  identified by an ID.
475
+ */
476
+SmallVideo.prototype.getIndicatorSpan = function(id) {
477
+    var indicatorSpan;
478
+    var spans = $(`#${this.videoSpanId}>[id=${id}`);
479
+    if (spans.length <= 0) {
480
+        indicatorSpan = document.createElement('span');
481
+        indicatorSpan.id = id;
482
+        indicatorSpan.className = "indicator";
483
+        $('#' + this.videoSpanId)[0].appendChild(indicatorSpan);
484
+    } else {
485
+        indicatorSpan = spans[0];
486
+    }
487
+    return indicatorSpan;
456 488
 };
457 489
 
458 490
 export default SmallVideo;

+ 17
- 5
modules/UI/videolayout/VideoLayout.js Voir le fichier

@@ -562,6 +562,18 @@ var VideoLayout = {
562 562
         }
563 563
     },
564 564
 
565
+    /**
566
+     * Sets the "raised hand" status for a participant identified by 'id'.
567
+     */
568
+    setRaisedHandStatus(id, raisedHandStatus) {
569
+        var video
570
+            = APP.conference.isLocalId(id)
571
+                ? localVideoThumbnail : remoteVideos[id];
572
+        if (video) {
573
+            video.showRaisedHandIndicator(raisedHandStatus);
574
+        }
575
+    },
576
+
565 577
     /**
566 578
      * On dominant speaker changed event.
567 579
      */
@@ -576,10 +588,10 @@ var VideoLayout = {
576 588
         if (APP.conference.isLocalId(id)) {
577 589
             if(oldSpeakerRemoteVideo)
578 590
             {
579
-                oldSpeakerRemoteVideo.updateDominantSpeakerIndicator(false);
591
+                oldSpeakerRemoteVideo.showDominantSpeakerIndicator(false);
580 592
                 currentDominantSpeaker = null;
581 593
             }
582
-            localVideoThumbnail.updateDominantSpeakerIndicator(true);
594
+            localVideoThumbnail.showDominantSpeakerIndicator(true);
583 595
             return;
584 596
         }
585 597
 
@@ -589,12 +601,12 @@ var VideoLayout = {
589 601
         }
590 602
 
591 603
         // Update the current dominant speaker.
592
-        remoteVideo.updateDominantSpeakerIndicator(true);
593
-        localVideoThumbnail.updateDominantSpeakerIndicator(false);
604
+        remoteVideo.showDominantSpeakerIndicator(true);
605
+        localVideoThumbnail.showDominantSpeakerIndicator(false);
594 606
 
595 607
         // let's remove the indications from the remote video if any
596 608
         if (oldSpeakerRemoteVideo) {
597
-            oldSpeakerRemoteVideo.updateDominantSpeakerIndicator(false);
609
+            oldSpeakerRemoteVideo.showDominantSpeakerIndicator(false);
598 610
         }
599 611
         currentDominantSpeaker = id;
600 612
 

+ 7
- 0
modules/keyboardshortcut/keyboardshortcut.js Voir le fichier

@@ -40,6 +40,13 @@ function initShortcutHandlers() {
40 40
                 APP.conference.toggleAudioMuted();
41 41
             }
42 42
         },
43
+        82: {
44
+            character: "R",
45
+            function: function() {
46
+                APP.conference.maybeToggleRaisedHand();
47
+            }
48
+
49
+        },
43 50
         84: {
44 51
             character: "T",
45 52
             function: function() {

Chargement…
Annuler
Enregistrer