Bläddra i källkod

Implements "raised hand".

master
Boris Grozev 8 år sedan
förälder
incheckning
2d2e27b8d0

+ 50
- 0
conference.js Visa fil

394
     videoMuted: false,
394
     videoMuted: false,
395
     isSharingScreen: false,
395
     isSharingScreen: false,
396
     isDesktopSharingEnabled: false,
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
      * Open new connection and join to the conference.
406
      * Open new connection and join to the conference.
399
      * @param {object} options
407
      * @param {object} options
1018
             APP.UI.handleLastNEndpoints(ids, enteringIds);
1026
             APP.UI.handleLastNEndpoints(ids, enteringIds);
1019
         });
1027
         });
1020
         room.on(ConferenceEvents.DOMINANT_SPEAKER_CHANGED, (id) => {
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
             APP.UI.markDominantSpeaker(id);
1039
             APP.UI.markDominantSpeaker(id);
1022
         });
1040
         });
1023
 
1041
 
1040
             APP.UI.changeDisplayName(id, displayName);
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
         room.on(ConferenceEvents.RECORDER_STATE_CHANGED, (status, error) => {
1068
         room.on(ConferenceEvents.RECORDER_STATE_CHANGED, (status, error) => {
1044
             console.log("Received recorder status change: ", status, error);
1069
             console.log("Received recorder status change: ", status, error);
1045
             APP.UI.updateRecordingState(status);
1070
             APP.UI.updateRecordingState(status);
1432
                 mediaDeviceHelper.setCurrentMediaDevices(devices);
1457
                 mediaDeviceHelper.setCurrentMediaDevices(devices);
1433
                 APP.UI.onAvailableDevicesChanged(devices);
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 Visa fil

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

+ 3
- 1
lang/main.json Visa fil

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

+ 19
- 1
modules/UI/UI.js Visa fil

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
 UI.initConference = function () {
278
 UI.initConference = function () {
261
     let id = APP.conference.localId;
279
     let id = APP.conference.localId;

+ 9
- 6
modules/UI/util/MessageHandler.js Visa fil

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
      * @param cls css class for the notification
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
      * @param messageArguments object with the arguments for the message.
226
      * @param messageArguments object with the arguments for the message.
224
      * @param options object with language options.
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
         if(!notificationsEnabled)
232
         if(!notificationsEnabled)
230
             return;
233
             return;

+ 51
- 19
modules/UI/videolayout/SmallVideo.js Visa fil

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
     if (!this.container) {
429
     if (!this.container) {
432
         console.warn( "Unable to set dominant speaker indicator - "
430
         console.warn( "Unable to set dominant speaker indicator - "
433
             + this.videoSpanId + " does not exist");
431
             + this.videoSpanId + " does not exist");
434
         return;
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
 export default SmallVideo;
490
 export default SmallVideo;

+ 17
- 5
modules/UI/videolayout/VideoLayout.js Visa fil

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
      * On dominant speaker changed event.
578
      * On dominant speaker changed event.
567
      */
579
      */
576
         if (APP.conference.isLocalId(id)) {
588
         if (APP.conference.isLocalId(id)) {
577
             if(oldSpeakerRemoteVideo)
589
             if(oldSpeakerRemoteVideo)
578
             {
590
             {
579
-                oldSpeakerRemoteVideo.updateDominantSpeakerIndicator(false);
591
+                oldSpeakerRemoteVideo.showDominantSpeakerIndicator(false);
580
                 currentDominantSpeaker = null;
592
                 currentDominantSpeaker = null;
581
             }
593
             }
582
-            localVideoThumbnail.updateDominantSpeakerIndicator(true);
594
+            localVideoThumbnail.showDominantSpeakerIndicator(true);
583
             return;
595
             return;
584
         }
596
         }
585
 
597
 
589
         }
601
         }
590
 
602
 
591
         // Update the current dominant speaker.
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
         // let's remove the indications from the remote video if any
607
         // let's remove the indications from the remote video if any
596
         if (oldSpeakerRemoteVideo) {
608
         if (oldSpeakerRemoteVideo) {
597
-            oldSpeakerRemoteVideo.updateDominantSpeakerIndicator(false);
609
+            oldSpeakerRemoteVideo.showDominantSpeakerIndicator(false);
598
         }
610
         }
599
         currentDominantSpeaker = id;
611
         currentDominantSpeaker = id;
600
 
612
 

+ 7
- 0
modules/keyboardshortcut/keyboardshortcut.js Visa fil

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

Laddar…
Avbryt
Spara