Browse Source

Fix remote participant menu for moderator

j8
yanas 9 years ago
parent
commit
5654d34ee8
4 changed files with 149 additions and 129 deletions
  1. 1
    1
      css/jitsi_popover.css
  2. 14
    28
      css/popup_menu.css
  3. 9
    2
      css/videolayout_default.css
  4. 125
    98
      modules/UI/videolayout/RemoteVideo.js

+ 1
- 1
css/jitsi_popover.css View File

71
     height: 35px;
71
     height: 35px;
72
     width: 100px;
72
     width: 100px;
73
     position: absolute;
73
     position: absolute;
74
-    bottom: -35;
74
+    bottom: -35px;
75
 }
75
 }
76
 
76
 
77
 .jitsipopover_green
77
 .jitsipopover_green

+ 14
- 28
css/popup_menu.css View File

1
 /*Initialize*/
1
 /*Initialize*/
2
 ul.popupmenu {
2
 ul.popupmenu {
3
-    display:none;
4
-    position: absolute;
5
-    padding:10px;
3
+    padding: 0px 10px 0px 10px;
6
     margin: 0;
4
     margin: 0;
7
     bottom: 0;
5
     bottom: 0;
8
-    margin-bottom: 35px;
9
-    padding-bottom:  10px;
10
-    padding-top: 10px;
11
-    right: 10px;
12
-    left: -5px;
13
     width: 100px;
6
     width: 100px;
14
-    background-color: rgba(0,0,0,0.9);
15
-    border: 1px solid rgba(256, 256, 256, 0.2);
16
-    border-radius:3px;
17
-}
18
-
19
-ul.popupmenu:after {
20
-    content: url('../images/popupPointer.png');
21
-    display: block;
22
-    position: absolute;
23
-    bottom: -8px;
24
-    left: 11px;
7
+    height: auto;
25
 }
8
 }
26
 
9
 
27
 ul.popupmenu li {
10
 ul.popupmenu li {
36
 
19
 
37
 /*Link Appearance*/
20
 /*Link Appearance*/
38
 ul.popupmenu li a {
21
 ul.popupmenu li a {
22
+    display: block;
39
     text-decoration: none;
23
     text-decoration: none;
40
     color: #fff;
24
     color: #fff;
41
     padding: 5px;
25
     padding: 5px;
42
-    display: inline-block;
43
     font-size: 9pt;
26
     font-size: 9pt;
27
+    width: 100%;
28
+    cursor: hand;
44
 }
29
 }
45
 
30
 
46
 ul.popupmenu li a i.icon-kick {
31
 ul.popupmenu li a i.icon-kick {
54
     text-align: center;
39
     text-align: center;
55
 }
40
 }
56
 
41
 
42
+ul.popupmenu li a div {
43
+    display: inline-block;
44
+    line-height: 25px;
45
+}
46
+
47
+ul.popupmenu li a i {
48
+    line-height: 25px;
49
+}
50
+
57
 span.remotevideomenu:hover ul.popupmenu, ul.popupmenu:hover {
51
 span.remotevideomenu:hover ul.popupmenu, ul.popupmenu:hover {
58
     display:block !important;
52
     display:block !important;
59
 }
53
 }
61
 a.disabled {
55
 a.disabled {
62
     color: gray !important;
56
     color: gray !important;
63
     pointer-events: none;
57
     pointer-events: none;
64
-}
65
-
66
-.popupmenuPadding {
67
-    height: 35px;
68
-    width: 100px;
69
-    position: absolute;
70
-    bottom: -35;
71
-    left: 0px;
72
 }
58
 }

+ 9
- 2
css/videolayout_default.css View File

144
 }
144
 }
145
 
145
 
146
 #remoteVideos .videocontainer>span.focusindicator,
146
 #remoteVideos .videocontainer>span.focusindicator,
147
-#remoteVideos .videocontainer>span.remotevideomenu {
148
-    display: inline-block;
147
+#remoteVideos .videocontainer>div.remotevideomenu {
149
     position: absolute;
148
     position: absolute;
150
     color: #FFFFFF;
149
     color: #FFFFFF;
151
     top: 0;
150
     top: 0;
159
     text-align: center;
158
     text-align: center;
160
 }
159
 }
161
 
160
 
161
+#remoteVideos .videocontainer>span.focusindicator {
162
+    display: inline-block;
163
+}
164
+
165
+#remoteVideos .videocontainer>div.remotevideomenu {
166
+    display: block;
167
+}
168
+
162
 .videocontainer>span.displayname,
169
 .videocontainer>span.displayname,
163
 .videocontainer>input.displayname {
170
 .videocontainer>input.displayname {
164
     display: none;
171
     display: none;

+ 125
- 98
modules/UI/videolayout/RemoteVideo.js View File

6
 import AudioLevels from "../audio_levels/AudioLevels";
6
 import AudioLevels from "../audio_levels/AudioLevels";
7
 import UIUtils from "../util/UIUtil";
7
 import UIUtils from "../util/UIUtil";
8
 import UIEvents from '../../../service/UI/UIEvents';
8
 import UIEvents from '../../../service/UI/UIEvents';
9
+import JitsiPopover from "../util/JitsiPopover";
9
 
10
 
10
 function RemoteVideo(id, VideoLayout, emitter) {
11
 function RemoteVideo(id, VideoLayout, emitter) {
11
     this.id = id;
12
     this.id = id;
18
     this.bindHoverHandler();
19
     this.bindHoverHandler();
19
     this.flipX = false;
20
     this.flipX = false;
20
     this.isLocal = false;
21
     this.isLocal = false;
22
+    this.isMuted = false;
21
 }
23
 }
22
 
24
 
23
 RemoteVideo.prototype = Object.create(SmallVideo.prototype);
25
 RemoteVideo.prototype = Object.create(SmallVideo.prototype);
34
     return this.container;
36
     return this.container;
35
 };
37
 };
36
 
38
 
39
+
40
+/**
41
+ * Initializes the remote participant popup menu, by specifying previously
42
+ * constructed popupMenuElement, containing all the menu items.
43
+ *
44
+ * @param popupMenuElement a pre-constructed element, containing the menu items
45
+ * to display in the popup
46
+ */
47
+RemoteVideo.prototype._initPopupMenu = function (popupMenuElement) {
48
+    this.popover = new JitsiPopover(
49
+        $("#" + this.videoSpanId + " > .remotevideomenu"),
50
+        {   content: popupMenuElement.outerHTML,
51
+            skin: "black"});
52
+
53
+    // override popover show method to make sure we will update the content
54
+    // before showing the popover
55
+    var origShowFunc = this.popover.show;
56
+    this.popover.show = function () {
57
+        // update content by forcing it, to finish even if popover
58
+        // is not visible
59
+        this.updateRemoteVideoMenu(this.isMuted, true);
60
+        // call the original show, passing its actual this
61
+        origShowFunc.call(this.popover);
62
+    }.bind(this);
63
+};
64
+
65
+/**
66
+ * Generates the popup menu content.
67
+ *
68
+ * @returns {Element|*} the constructed element, containing popup menu items
69
+ * @private
70
+ */
71
+RemoteVideo.prototype._generatePopupContent = function () {
72
+    var popupmenuElement = document.createElement('ul');
73
+    popupmenuElement.className = 'popupmenu';
74
+    popupmenuElement.id = `remote_popupmenu_${this.id}`;
75
+
76
+    var muteMenuItem = document.createElement('li');
77
+    var muteLinkItem = document.createElement('a');
78
+
79
+    var mutedIndicator = "<i class='icon-mic-disabled'></i>";
80
+
81
+    var doMuteHTML = mutedIndicator +
82
+        " <div " +
83
+        "data-i18n='videothumbnail.domute'>" +
84
+        APP.translation.translateString("videothumbnail.domute") +
85
+        "</div>";
86
+
87
+    var mutedHTML = mutedIndicator +
88
+        " <div " +
89
+        "data-i18n='videothumbnail.muted'>" +
90
+        APP.translation.translateString("videothumbnail.muted") +
91
+        "</div>";
92
+
93
+    muteLinkItem.id = "muteLinkItem";
94
+
95
+    if (this.isMuted) {
96
+        muteLinkItem.innerHTML = mutedHTML;
97
+        muteLinkItem.className = 'mutelink disabled';
98
+    }
99
+    else {
100
+        muteLinkItem.innerHTML = doMuteHTML;
101
+        muteLinkItem.className = 'mutelink';
102
+    }
103
+
104
+    // Delegate event to the document.
105
+    $(document).on("click", ".mutelink", function(){
106
+
107
+        if (this.isMuted)
108
+            return;
109
+
110
+        this.emitter.emit(UIEvents.REMOTE_AUDIO_MUTED, this.id);
111
+
112
+        this.popover.forceHide();
113
+    }.bind(this));
114
+
115
+    muteMenuItem.appendChild(muteLinkItem);
116
+    popupmenuElement.appendChild(muteMenuItem);
117
+
118
+    var ejectIndicator = "<i style='float:left;' class='fa fa-eject'></i>";
119
+
120
+    var ejectMenuItem = document.createElement('li');
121
+    var ejectLinkItem = document.createElement('a');
122
+
123
+    var ejectText = "<div " +
124
+        "data-i18n='videothumbnail.kick'>" +
125
+        APP.translation.translateString("videothumbnail.kick") +
126
+        "</div>";
127
+
128
+    ejectLinkItem.className = 'ejectlink';
129
+    ejectLinkItem.innerHTML = ejectIndicator + ' ' + ejectText;
130
+
131
+    $(document).on("click", ".ejectlink", function(){
132
+        this.emitter.emit(UIEvents.USER_KICKED, this.id);
133
+        this.popover.forceHide();
134
+    }.bind(this));
135
+
136
+    ejectMenuItem.appendChild(ejectLinkItem);
137
+    popupmenuElement.appendChild(ejectMenuItem);
138
+
139
+    return popupmenuElement;
140
+};
141
+
142
+/**
143
+ * Updates the remote video menu.
144
+ *
145
+ * @param isMuted the new muted state to update to
146
+ * @param force to work even if popover is not visible
147
+ */
148
+RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted, force) {
149
+
150
+    this.isMuted = isMuted;
151
+
152
+    // generate content, translate it and add it to document only if
153
+    // popover is visible or we force to do so.
154
+    if(this.popover.popoverShown || force) {
155
+        this.popover.updateContent(this._generatePopupContent());
156
+    }
157
+};
158
+
37
 /**
159
 /**
38
  * Adds the remote video menu element for the given <tt>id</tt> in the
160
  * Adds the remote video menu element for the given <tt>id</tt> in the
39
  * given <tt>parentElement</tt>.
161
  * given <tt>parentElement</tt>.
43
  */
165
  */
44
 if (!interfaceConfig.filmStripOnly) {
166
 if (!interfaceConfig.filmStripOnly) {
45
     RemoteVideo.prototype.addRemoteVideoMenu = function () {
167
     RemoteVideo.prototype.addRemoteVideoMenu = function () {
46
-        var spanElement = document.createElement('span');
168
+        var spanElement = document.createElement('div');
47
         spanElement.className = 'remotevideomenu';
169
         spanElement.className = 'remotevideomenu';
48
-
49
         this.container.appendChild(spanElement);
170
         this.container.appendChild(spanElement);
50
 
171
 
51
         var menuElement = document.createElement('i');
172
         var menuElement = document.createElement('i');
53
         menuElement.title = 'Remote user controls';
174
         menuElement.title = 'Remote user controls';
54
         spanElement.appendChild(menuElement);
175
         spanElement.appendChild(menuElement);
55
 
176
 
56
-
57
-        var popupmenuElement = document.createElement('ul');
58
-        popupmenuElement.className = 'popupmenu';
59
-        popupmenuElement.id = `remote_popupmenu_${this.id}`;
60
-        spanElement.appendChild(popupmenuElement);
61
-
62
-        var muteMenuItem = document.createElement('li');
63
-        var muteLinkItem = document.createElement('a');
64
-
65
-        var mutedIndicator = "<i style='float:left;' " +
66
-            "class='icon-mic-disabled'></i>";
67
-
68
-        if (!this.isMuted) {
69
-            muteLinkItem.innerHTML = mutedIndicator +
70
-                " <div style='width: 90px;margin-left: 20px;' " +
71
-                "data-i18n='videothumbnail.domute'></div>";
72
-            muteLinkItem.className = 'mutelink';
73
-        }
74
-        else {
75
-            muteLinkItem.innerHTML = mutedIndicator +
76
-                " <div style='width: 90px;margin-left: 20px;' " +
77
-                "data-i18n='videothumbnail.muted'></div>";
78
-            muteLinkItem.className = 'mutelink disabled';
79
-        }
80
-
81
-        muteLinkItem.onclick = (event) => {
82
-            if ($(this).attr('disabled')) {
83
-                event.preventDefault();
84
-            }
85
-            var isMute = !!this.isMuted;
86
-            this.emitter.emit(UIEvents.REMOTE_AUDIO_MUTED, this.id);
87
-
88
-            popupmenuElement.setAttribute('style', 'display:none;');
89
-
90
-            if (isMute) {
91
-                this.innerHTML = mutedIndicator +
92
-                    " <div style='width: 90px;margin-left: 20px;' " +
93
-                    "data-i18n='videothumbnail.muted'></div>";
94
-                this.className = 'mutelink disabled';
95
-            }
96
-            else {
97
-                this.innerHTML = mutedIndicator +
98
-                    " <div style='width: 90px;margin-left: 20px;' " +
99
-                    "data-i18n='videothumbnail.domute'></div>";
100
-                this.className = 'mutelink';
101
-            }
102
-        };
103
-
104
-        muteMenuItem.appendChild(muteLinkItem);
105
-        popupmenuElement.appendChild(muteMenuItem);
106
-
107
-        var ejectIndicator = "<i style='float:left;' class='fa fa-eject'></i>";
108
-
109
-        var ejectMenuItem = document.createElement('li');
110
-        var ejectLinkItem = document.createElement('a');
111
-        var ejectText = "<div style='width: 90px;margin-left: 20px;' " +
112
-            "data-i18n='videothumbnail.kick'>&nbsp;</div>";
113
-        ejectLinkItem.innerHTML = ejectIndicator + ' ' + ejectText;
114
-        ejectLinkItem.onclick = (event) => {
115
-            this.emitter.emit(UIEvents.USER_KICKED, this.id);
116
-            popupmenuElement.setAttribute('style', 'display:none;');
117
-        };
118
-
119
-        ejectMenuItem.appendChild(ejectLinkItem);
120
-        popupmenuElement.appendChild(ejectMenuItem);
121
-
122
-        var paddingSpan = document.createElement('span');
123
-        paddingSpan.className = 'popupmenuPadding';
124
-        popupmenuElement.appendChild(paddingSpan);
125
-        APP.translation.translateElement(
126
-            $("#" + popupmenuElement.id + " > li > a > div"));
177
+        this._initPopupMenu(this._generatePopupContent());
127
     };
178
     };
128
 
179
 
129
 } else {
180
 } else {
313
         this.connectionIndicator.hide();
364
         this.connectionIndicator.hide();
314
 };
365
 };
315
 
366
 
316
-/**
317
- * Updates the remote video menu.
318
- *
319
- * @param id the id indicating the video for which we're adding a menu.
320
- * @param isMuted indicates the current mute state
321
- */
322
-RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted) {
323
-    var muteMenuItem = $(`#remote_popupmenu_${this.id}>li>a.mutelink`);
324
-
325
-    var mutedIndicator = "<i class='icon-mic-disabled'></i>";
326
-
327
-    if (muteMenuItem.length) {
328
-        var muteLink = muteMenuItem.get(0);
329
-
330
-        if (isMuted) {
331
-            muteLink.innerHTML = mutedIndicator + ' Muted';
332
-            muteLink.className = 'mutelink disabled';
333
-        }
334
-        else {
335
-            muteLink.innerHTML = mutedIndicator + ' Mute';
336
-            muteLink.className = 'mutelink';
337
-        }
338
-    }
339
-};
340
-
341
 /**
367
 /**
342
  * Sets the display name for the given video span id.
368
  * Sets the display name for the given video span id.
343
  */
369
  */
388
 RemoteVideo.prototype.removeRemoteVideoMenu = function() {
414
 RemoteVideo.prototype.removeRemoteVideoMenu = function() {
389
     var menuSpan = $('#' + this.videoSpanId + '>span.remotevideomenu');
415
     var menuSpan = $('#' + this.videoSpanId + '>span.remotevideomenu');
390
     if (menuSpan.length) {
416
     if (menuSpan.length) {
417
+        this.popover.forceHide();
391
         menuSpan.remove();
418
         menuSpan.remove();
392
     }
419
     }
393
 };
420
 };

Loading…
Cancel
Save