diff --git a/css/jitsi_popover.css b/css/jitsi_popover.css index 545ebf1c4..fcb6484f0 100644 --- a/css/jitsi_popover.css +++ b/css/jitsi_popover.css @@ -16,7 +16,6 @@ border-radius: 6px; /*-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);*/ /*box-shadow: 0 5px 10px rgba(0, 0, 0, 0.4);*/ - white-space: normal; margin-top: -10px; margin-bottom: 35px; } @@ -30,7 +29,6 @@ .jitsipopover-content { padding: 9px 14px; font-size: 10pt; - white-space:pre-wrap; text-align: center; } diff --git a/css/popup_menu.css b/css/popup_menu.css index 300d95f4b..ad1123508 100644 --- a/css/popup_menu.css +++ b/css/popup_menu.css @@ -1,32 +1,15 @@ /*Initialize*/ ul.popupmenu { - display:none; - position: absolute; - padding:10px; - margin: 0; - bottom: 0; - margin-bottom: 35px; - padding-bottom: 10px; - padding-top: 10px; - right: 10px; - left: -5px; width: 100px; - background-color: rgba(0,0,0,0.9); - border: 1px solid rgba(256, 256, 256, 0.2); - border-radius:8px; -} - -ul.popupmenu:after { - content: url('../images/popupPointer.png'); - display: block; - position: absolute; - bottom: -8px; - left: 11px; + padding: 0; + margin: 0; } ul.popupmenu li { list-style-type: none; + display: inline-block; text-align: left; + width: 100%; } ul.popupmenu li:hover { @@ -43,30 +26,15 @@ ul.popupmenu li a { font-size: 9pt; } -ul.popupmenu li a i.icon-kick { - font-size: 8pt; +ul.popupmenu li i { + width: 15px; } -ul.popupmenu li a span { - display: inline-block; - width: 20px; - height: 16px; - text-align: center; +ul.popupmenu li span { + padding-left: 5px; } -span.remotevideomenu:hover ul.popupmenu, ul.popupmenu:hover { - display:block !important; -} - -a.disabled { +ul.popupmenu a.disabled { color: gray !important; pointer-events: none; } - -.popupmenuPadding { - height: 35px; - width: 100px; - position: absolute; - bottom: -35; - left: 0px; -} \ No newline at end of file diff --git a/modules/UI/util/JitsiPopover.js b/modules/UI/util/JitsiPopover.js index f99d57747..5e278cb26 100644 --- a/modules/UI/util/JitsiPopover.js +++ b/modules/UI/util/JitsiPopover.js @@ -10,15 +10,26 @@ var JitsiPopover = (function () { { this.options = { skin: "white", - content: "" + content: "", + onClick: function () {}, + onShow: function () {} }; - if(options) - { - if(options.skin) + if (options) { + if (options.skin) { this.options.skin = options.skin; + } - if(options.content) + if (options.content) { this.options.content = options.content; + } + + if (options.onClick) { + this.options.onClick = options.onClick; + } + + if (options.onShow) { + this.options.onShow = options.onShow; + } } this.elementIsHovered = false; @@ -76,7 +87,10 @@ var JitsiPopover = (function () { */ JitsiPopover.prototype.createPopover = function () { $("body").append(this.template); - $(".jitsipopover > .jitsipopover-content").html(this.options.content); + $(".jitsipopover > .jitsipopover-content") + .html(this.options.content) + .click(this.options.onClick); + this.options.onShow(); var self = this; $(".jitsipopover").on("mouseenter", function () { self.popoverIsHovered = true; @@ -126,4 +140,4 @@ var JitsiPopover = (function () { return JitsiPopover; })(); -module.exports = JitsiPopover; \ No newline at end of file +module.exports = JitsiPopover; diff --git a/modules/UI/videolayout/RemoteVideo.js b/modules/UI/videolayout/RemoteVideo.js index 60c9fbcf9..a16f49b6d 100644 --- a/modules/UI/videolayout/RemoteVideo.js +++ b/modules/UI/videolayout/RemoteVideo.js @@ -6,6 +6,7 @@ import SmallVideo from "./SmallVideo"; import AudioLevels from "../audio_levels/AudioLevels"; import UIUtils from "../util/UIUtil"; import UIEvents from '../../../service/UI/UIEvents'; +import JitsiPopover from "../util/JitsiPopover"; function RemoteVideo(id, VideoLayout, emitter) { this.id = id; @@ -18,6 +19,7 @@ function RemoteVideo(id, VideoLayout, emitter) { this.bindHoverHandler(); this.flipX = false; this.isLocal = false; + this.popover = null; } RemoteVideo.prototype = Object.create(SmallVideo.prototype); @@ -35,100 +37,89 @@ RemoteVideo.prototype.addRemoteVideoContainer = function() { }; /** - * Adds the remote video menu element for the given id in the - * given parentElement. - * - * @param id the id indicating the video for which we're adding a menu. - * @param parentElement the parent element where this menu will be added + * Adds menu to the this remote video element. */ -if (!interfaceConfig.filmStripOnly) { - RemoteVideo.prototype.addRemoteVideoMenu = function () { - var spanElement = document.createElement('span'); - spanElement.className = 'remotevideomenu'; +RemoteVideo.prototype.addRemoteVideoMenu = function() { + if (interfaceConfig.filmStripOnly || this.popover) { + return; + } - this.container.appendChild(spanElement); - - var menuElement = document.createElement('i'); - menuElement.className = 'fa fa-angle-down'; - menuElement.title = 'Remote user controls'; - spanElement.appendChild(menuElement); - - - var popupmenuElement = document.createElement('ul'); - popupmenuElement.className = 'popupmenu'; - popupmenuElement.id = `remote_popupmenu_${this.id}`; - spanElement.appendChild(popupmenuElement); - - var muteMenuItem = document.createElement('li'); - var muteLinkItem = document.createElement('a'); - - var mutedIndicator = ""; - - if (!this.isMuted) { - muteLinkItem.innerHTML = mutedIndicator + - "
"; - muteLinkItem.className = 'mutelink'; - } - else { - muteLinkItem.innerHTML = mutedIndicator + - " "; - muteLinkItem.className = 'mutelink disabled'; + let $popup = $( + ` ` + ); + $(this.container).append($popup); + this.popover = new JitsiPopover($popup, { + skin: 'black', + onClick: this.onRemoteVideoMenuClicked.bind(this), + onShow: () => { + $(`#${this.getRemoteMenuId()} [data-i18n]`).each(function (i, el) { + APP.translation.translateElement($(el)); + }); } + }); + this.updatePopover(); +}; - muteLinkItem.onclick = (event) => { - if ($(this).attr('disabled')) { - event.preventDefault(); - } - var isMute = !!this.isMuted; - this.emitter.emit(UIEvents.REMOTE_AUDIO_MUTED, this.id); +/** + * Get id of menu element for this remote video element. + * @returns {string} remote menu element id + */ +RemoteVideo.prototype.getRemoteMenuId = function () { + return `remote_popupmenu_${this.id}`; +}; - popupmenuElement.setAttribute('style', 'display:none;'); +/** + * Generate menu html for this remote video. + * @returns {string} remote menu html + */ +RemoteVideo.prototype.generateRemoteVideoMenu = function () { + let muteLabeli18n = + this.isMuted + ? 'videothumbnail.muted' + : 'videothumbnail.domute'; + return ` + + `; +}; - if (isMute) { - this.innerHTML = mutedIndicator + - " "; - this.className = 'mutelink disabled'; - } - else { - this.innerHTML = mutedIndicator + - " "; - this.className = 'mutelink'; - } - }; +/** + * Update remote menu. + */ +RemoteVideo.prototype.updatePopover = function () { + this.popover.updateContent(this.generateRemoteVideoMenu()); +}; - muteMenuItem.appendChild(muteLinkItem); - popupmenuElement.appendChild(muteMenuItem); +/** + * Click handler for the remote menu. + */ +RemoteVideo.prototype.onRemoteVideoMenuClicked = function (e) { + e.preventDefault(); - var ejectIndicator = ""; + let $target = $(e.target); - var ejectMenuItem = document.createElement('li'); - var ejectLinkItem = document.createElement('a'); - var ejectText = "