diff --git a/css/_connection-info.scss b/css/_connection-info.scss
index eb0d406c4..6527cba5c 100644
--- a/css/_connection-info.scss
+++ b/css/_connection-info.scss
@@ -1,8 +1,7 @@
%connection-info {
- text-align: left;
font-size: 12px;
font-weight: 400;
- color: $popoverFontColor;
+ color: $modalTextColor;
td {
padding: 2px 0;
@@ -11,11 +10,14 @@
.connection-info
{
- float: left;
- padding: 5px;
- padding-left: 0;
@extend %connection-info;
+ /**
+ * Apply negative margin to reduce the appearance of padding in AtlasKit
+ * InlineDialog.
+ */
+ margin: -15px;
+
> table {
white-space: nowrap;
@extend %connection-info;
@@ -40,4 +42,11 @@
@extend .connection-info__icon;
color: $uploadConnectionIconColor;
}
+
+ .showmore {
+ display: block;
+ margin: 10px auto;
+ text-align: center;
+ width: 90px;
+ }
}
diff --git a/css/_jitsi_popover.scss b/css/_jitsi_popover.scss
deleted file mode 100644
index f10a25a69..000000000
--- a/css/_jitsi_popover.scss
+++ /dev/null
@@ -1,92 +0,0 @@
-.jitsipopover {
- position: absolute;
- top: 0;
- left: 0;
- z-index: $jitsipopoverZ;
- display: table;
- visibility: hidden;
- max-width: 300px;
- min-width: 100px;
- text-align: left;
- color: $popoverFontColor;
- background-color: $popoverBg;
- background-clip: padding-box;
- border-radius: $borderRadius;
- /*-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: -$popoverMenuPadding;
-
-
- &__menu-padding,
- &__menu-padding-top {
- position: absolute;
- width: 100px;
- }
-
- /**
- * Invisible padding is added to the bottom of the popover to extend its
- * height so it does not close when moving the mouse from the trigger
- * element towards the popover itself.
- */
- &__menu-padding {
- bottom: -$popoverMenuPadding;
- height: $popoverMenuPadding;
- }
-
- /**
- * Invisible padding is added to the top of the popover to extend its height
- * so it does not close automatically when its height is shrunk from showing
- * less video statistics.
- */
- &__menu-padding-top {
- height: 20px;
- top: -20px;
- }
-
- &__showmore {
- display: block;
- text-align: center;
- width: 90px;
- margin: 10px auto;
- }
-
- > .arrow {
- position: absolute;
- display: block;
- left: 50%;
- bottom: -5px;
- margin-left: -5px;
- width: 0;
- height: 0;
- border-color: transparent;
- border-top-color: $popoverBg;
- border-style: solid;
- border-width: 5px;
- border-bottom-width: 0;
- }
-
- /**
- * Override default "top" styles to support popovers appearing from the
- * left of the popover trigger element.
- */
- &.left {
- margin-left: -$popoverMenuPadding;
- margin-top: 0;
-
- .arrow {
- border-color: transparent transparent transparent $popoverBg;
- border-width: 5px 0px 5px 5px;
- margin-left: 0;
- margin-top: -5px;
- }
-
- .jitsipopover {
- &__menu-padding {
- bottom: 0;
- height: 100%;
- width: $popoverMenuPadding;
- }
- }
- }
-}
diff --git a/css/_popup_menu.scss b/css/_popup_menu.scss
index 9b7eb0064..7b34486a5 100644
--- a/css/_popup_menu.scss
+++ b/css/_popup_menu.scss
@@ -3,37 +3,31 @@
**/
.popupmenu {
+ text-align: left;
padding: 0;
- margin: 2px 0;
- bottom: 0;
- height: auto;
-
- &:first-child {
- margin-top: 2px;
- }
+ white-space: nowrap;
&__item {
list-style-type: none;
- text-align: left;
height: 35px;
&:hover {
- background-color: $popupMenuSelectedItemBackground;
+ background-color: rgba(9, 30, 66, 0.04);
}
}
// Link Appearance
&__link,
&__contents {
+ color: $modalTextColor;
display: block;
box-sizing: border-box;
text-decoration: none;
- color: #fff;
- padding: 5px;
height: 100%;
font-size: 9pt;
width: 100%;
- cursor: hand;
+ cursor: pointer;
+ padding: 0 5px;
&.disabled {
color: gray !important;
@@ -46,6 +40,12 @@
vertical-align: middle;
}
+ &__link {
+ i {
+ cursor: pointer;
+ }
+ }
+
&__contents {
display: flex;
@@ -73,7 +73,6 @@
display: inline-block;
min-width: 20px;
height: 100%;
- text-align: center;
> * {
@include absoluteAligning();
@@ -85,6 +84,15 @@
}
}
+/**
+ * Override reset css styling modifying all lists and set negative margin to
+ * reduce the visibility of padding on AtlasKit
+ * InlineDialogs.
+ */
+ul.popupmenu {
+ margin: -15px;
+}
+
span.remotevideomenu:hover ul.popupmenu, ul.popupmenu:hover {
display:block !important;
}
diff --git a/css/_variables.scss b/css/_variables.scss
index 2cf78565f..479ab9b30 100644
--- a/css/_variables.scss
+++ b/css/_variables.scss
@@ -112,7 +112,6 @@ $tooltipsZ: 401;
$dropdownMaskZ: 900;
$dropdownZ: 901;
$centeredVideoLabelZ: 1010;
-$jitsipopoverZ: 1012;
$popoverZ: 1015;
$overlayZ: 1016;
diff --git a/css/_vertical_filmstrip_overrides.scss b/css/_vertical_filmstrip_overrides.scss
index 434931d49..08aad336d 100644
--- a/css/_vertical_filmstrip_overrides.scss
+++ b/css/_vertical_filmstrip_overrides.scss
@@ -8,6 +8,14 @@
display: flex;
flex-direction: column-reverse;
height: 100%;
+ /**
+ * fixed positioning is necessary for remote menus and tooltips to pop
+ * out of the scrolling filmstrip. AtlasKit dialogs and tooltips use
+ * a library called popper which will position its elements fixed if
+ * any parent is also fixed.
+ */
+ position: fixed;
+ z-index: $tooltipsZ;
/**
* Hide videos by making them slight to the right.
@@ -60,13 +68,16 @@
* Move the remote video menu trigger to the bottom left of the
* video thumbnail.
*/
- .remotevideomenu {
+ .remotevideomenu,
+ .remote-video-menu-trigger {
bottom: 0;
left: 0;
top: auto;
right: auto;
+ }
+
+ .remote-video-menu-trigger {
margin-bottom: 7px;
- transform: translate3d(0,0,0);
}
#remoteVideos {
@@ -75,11 +86,6 @@
}
.videocontainer {
- &__toolbar,
- &__toptoolbar {
- transform: translate3d(0,0,0);
- }
-
/**
* Move status icons to the bottom right of the thumbnail.
*/
@@ -159,4 +165,17 @@
transition-delay: 0.1s;
}
}
+
+ /**
+ * Apply hardware acceleration to prevent flickering on scroll. The
+ * selectors are specific to icon wrappers to prevent fixed position dialogs
+ * and tooltips from getting a new location context due to translate3d.
+ */
+ .connection-indicator,
+ .remote-video-menu-trigger,
+ .videocontainer__toolbar,
+ .raisehandindicator,
+ #dominantspeakerindicator {
+ transform: translate3d(0, 0, 0);
+ }
}
diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss
index d64632c3f..6c8503e28 100644
--- a/css/_videolayout_default.scss
+++ b/css/_videolayout_default.scss
@@ -48,15 +48,30 @@
&__toolbar {
bottom: 0;
- padding: 0 5px 0 5px;
height: $thumbnailToolbarHeight;
+ padding: 0 5px 0 5px;
}
&__toptoolbar {
- $toolbarPadding: 5px;
+ $toolbarIconMargin: 5px;
top: 0;
- padding: $toolbarPadding;
padding-bottom: 0;
+ /**
+ * Override text-align center as icons need to be left justified.
+ */
+ text-align: left;
+
+ /**
+ * Intentionally use margin on the icon itself as AtlasKit InlineDialog
+ * positioning depends on the trigger (indicator icon).
+ */
+ .indicator {
+ margin-top: $toolbarIconMargin;
+ }
+
+ .indicator:nth-child(1) {
+ margin-left: $toolbarIconMargin;
+ }
.connection-indicator,
span.indicator {
@@ -71,6 +86,15 @@
}
}
+ .connection-indicator-container {
+ display: inline-block;
+ vertical-align: top;
+
+ .popover-trigger {
+ display: inline-block;
+ }
+ }
+
.connection-indicator,
span.indicator {
position: relative;
@@ -78,7 +102,6 @@
text-align: center;
line-height: $thumbnailIndicatorSize;
padding: 0;
- float: left;
@include circle($thumbnailIndicatorSize);
box-sizing: border-box;
z-index: $zindex3;
@@ -124,6 +147,7 @@
.icon-connection,
.icon-connection-lost {
+ cursor: pointer;
font-size: 1em;
}
}
@@ -309,13 +333,13 @@
background: $connectionIndicatorBg;
}
+.remote-video-menu-trigger,
.remotevideomenu
{
display: inline-block;
position: absolute;
top: 0px;
right: 0;
- margin-top: 7px;
z-index: $zindex3;
width: 18px;
height: 13px;
@@ -326,6 +350,9 @@
cursor: hand;
}
}
+.remote-video-menu-trigger {
+ margin-top: 7px;
+}
/**
* Audio indicator on video thumbnails.
diff --git a/css/main.scss b/css/main.scss
index 21cda1343..578b2a3b5 100644
--- a/css/main.scss
+++ b/css/main.scss
@@ -50,7 +50,6 @@
@import 'recording';
@import 'login_menu';
@import 'popover';
-@import 'jitsi_popover';
@import 'contact_list';
@import 'chat';
@import 'ringing/ringing';
diff --git a/modules/UI/UI.js b/modules/UI/UI.js
index 336625810..f172d7f3d 100644
--- a/modules/UI/UI.js
+++ b/modules/UI/UI.js
@@ -8,7 +8,6 @@ import Chat from "./side_pannels/chat/Chat";
import SidePanels from "./side_pannels/SidePanels";
import Avatar from "./avatar/Avatar";
import SideContainerToggler from "./side_pannels/SideContainerToggler";
-import JitsiPopover from "./util/JitsiPopover";
import messageHandler from "./util/MessageHandler";
import UIUtil from "./util/UIUtil";
import { activateTooltips } from './util/Tooltip';
@@ -322,7 +321,6 @@ UI.start = function () {
UI.showToolbar();
Filmstrip.setFilmstripOnly();
APP.store.dispatch(setNotificationsEnabled(false));
- JitsiPopover.enabled = false;
}
if (interfaceConfig.VERTICAL_FILMSTRIP) {
diff --git a/modules/UI/util/JitsiPopover.js b/modules/UI/util/JitsiPopover.js
deleted file mode 100644
index 94466a01c..000000000
--- a/modules/UI/util/JitsiPopover.js
+++ /dev/null
@@ -1,276 +0,0 @@
-/* global $ */
-
-/* eslint-disable no-unused-vars */
-import React, { Component } from 'react';
-import ReactDOM from 'react-dom';
-import { I18nextProvider } from 'react-i18next';
-
-import { i18next } from '../../../react/features/base/i18n';
-/* eslint-enable no-unused-vars */
-
-const positionConfigurations = {
- left: {
-
- // Align the popover's right side to the target element.
- my: 'right',
-
- // Align the popover to the left side of the target element.
- at: 'left',
-
- // Force the popover to fit within the viewport.
- collision: 'fit',
-
- /**
- * Callback invoked by jQuery UI tooltip.
- *
- * @param {Object} position - The top and bottom position the popover
- * element should be set at.
- * @param {Object} element. - Additional size and position information
- * about the popover element and target.
- * @param {Object} elements.element - Has position and size related data
- * for the popover element itself.
- * @param {Object} elements.target - Has position and size related data
- * for the target element the popover displays from.
- */
- using: function setPositionLeft(position, elements) {
- const { element, target } = elements;
-
- $('.jitsipopover').css({
- left: element.left,
- top: element.top,
- visibility: 'visible'
- });
-
- // Move additional padding to the right edge of the popover and
- // allow css to take care of width. The padding is used to maintain
- // a hover state between the target and the popover.
- $('.jitsipopover > .jitsipopover__menu-padding')
- .css({ left: element.width });
-
- // Find the distance from the top of the popover to the center of
- // the target and use that value to position the arrow to point to
- // it.
- const verticalCenterOfTarget = target.height / 2;
- const verticalDistanceFromTops = target.top - element.top;
- const verticalPositionOfTargetCenter
- = verticalDistanceFromTops + verticalCenterOfTarget;
-
- $('.jitsipopover > .arrow').css({
- left: element.width,
- top: verticalPositionOfTargetCenter
- });
- }
- },
- top: {
- my: "bottom",
- at: "top",
- collision: "fit",
- using: function setPositionTop(position, elements) {
- const { element, target } = elements;
- const calcLeft = target.left - element.left + target.width / 2;
- const paddingLeftPosition = calcLeft - 50;
- const $jistiPopover = $('.jitsipopover');
-
- $jistiPopover.css({
- left: element.left,
- top: element.top,
- visibility: 'visible'
- });
- $jistiPopover.find('.arrow').css({ left: calcLeft });
- $jistiPopover.find('.jitsipopover__menu-padding')
- .css({ left: paddingLeftPosition });
- $jistiPopover.find('.jitsipopover__menu-padding-top')
- .css({ left: paddingLeftPosition });
- }
- }
-};
-export default (function () {
- /**
- * The default options
- */
- const defaultOptions = {
- skin: 'white',
- content: '',
- hasArrow: true,
- onBeforePosition: undefined,
- position: 'top'
- };
-
- /**
- * Constructs new JitsiPopover and attaches it to the element
- * @param element jquery selector
- * @param options the options for the popover.
- * @constructor
- */
- function JitsiPopover(element, options)
- {
- this.options = Object.assign({}, defaultOptions, options);
- this.elementIsHovered = false;
- this.popoverIsHovered = false;
- this.popoverShown = false;
-
- element.data("jitsi_popover", this);
- this.element = element;
- this.template = this.getTemplate();
- var self = this;
- this.element.on("mouseenter", function () {
- self.elementIsHovered = true;
- self.show();
- }).on("mouseleave", function () {
- self.elementIsHovered = false;
- setTimeout(function () {
- self.hide();
- }, 10);
- });
- }
-
- /**
- * Returns template for popover
- */
- JitsiPopover.prototype.getTemplate = function () {
- const { hasArrow, position, skin } = this.options;
-
- let arrow = '';
- if (hasArrow) {
- arrow = '
';
- }
-
- return (
- ``
- );
- };
-
- /**
- * Shows the popover
- */
- JitsiPopover.prototype.show = function () {
- if(!JitsiPopover.enabled)
- return;
- this.createPopover();
- this.popoverShown = true;
- };
-
- /**
- * Hides the popover if not hovered or popover is not shown.
- */
- JitsiPopover.prototype.hide = function () {
- if(!this.elementIsHovered && !this.popoverIsHovered &&
- this.popoverShown) {
- this.forceHide();
- }
- };
-
- /**
- * Hides the popover and clears the document elements added by popover.
- */
- JitsiPopover.prototype.forceHide = function () {
- this.remove();
- this.popoverShown = false;
- if(this.popoverIsHovered) { //the browser is not firing hover events
- //when the element was on hover if got removed.
- this.popoverIsHovered = false;
- this.onHoverPopover(this.popoverIsHovered);
- }
- };
-
- /**
- * Creates the popover html.
- */
- JitsiPopover.prototype.createPopover = function () {
- let $popover = $('.jitsipopover');
-
- if (!$popover.length) {
- $('body').append(this.template);
-
- $popover = $('.jitsipopover');
-
- $popover.on('mouseenter', () => {
- this.popoverIsHovered = true;
- if (typeof this.onHoverPopover === 'function') {
- this.onHoverPopover(this.popoverIsHovered);
- }
- });
-
- $popover.on('mouseleave', () => {
- this.popoverIsHovered = false;
- this.hide();
- if (typeof this.onHoverPopover === 'function') {
- this.onHoverPopover(this.popoverIsHovered);
- }
- });
- }
-
- const $popoverContent = $popover.find('.jitsipopover__content');
-
- /* jshint ignore:start */
- ReactDOM.render(
-
- { this.options.content }
- ,
- $popoverContent.get(0),
- () => {
- this.refreshPosition();
- });
- /* jshint ignore:end */
- };
-
- /**
- * Adds a hover listener to the popover.
- */
- JitsiPopover.prototype.addOnHoverPopover = function (listener) {
- this.onHoverPopover = listener;
- };
-
- /**
- * Refreshes the position of the popover.
- */
- JitsiPopover.prototype.refreshPosition = function () {
- const positionOptions = Object.assign(
- {},
- positionConfigurations[this.options.position],
- {
- of: this.element
- }
- );
- $(".jitsipopover").position(positionOptions);
- };
-
- /**
- * Updates the content of popover.
- * @param content new content
- */
- JitsiPopover.prototype.updateContent = function (content) {
- this.options.content = content;
- if (!this.popoverShown) {
- return;
- }
- this.createPopover();
- };
-
- /**
- * Unmounts any present child React Component and removes the popover itself
- * from the DOM.
- *
- * @returns {void}
- */
- JitsiPopover.prototype.remove = function () {
- const $popover = $('.jitsipopover');
- const $popoverContent = $popover.find('.jitsipopover__content');
-
- if ($popoverContent.length) {
- ReactDOM.unmountComponentAtNode($popoverContent.get(0));
- }
-
- $popover.off();
- $popover.remove();
- };
-
- JitsiPopover.enabled = true;
-
- return JitsiPopover;
-})();
diff --git a/modules/UI/videolayout/LocalVideo.js b/modules/UI/videolayout/LocalVideo.js
index 3b41e79d3..d69a22e21 100644
--- a/modules/UI/videolayout/LocalVideo.js
+++ b/modules/UI/videolayout/LocalVideo.js
@@ -24,6 +24,9 @@ function LocalVideo(VideoLayout, emitter) {
this._buildContextMenu();
this.isLocal = true;
this.emitter = emitter;
+ this.statsPopoverLocation = interfaceConfig.VERTICAL_FILMSTRIP
+ ? 'left bottom' : 'top center';
+
Object.defineProperty(this, 'id', {
get: function () {
return APP.conference.getMyUserId();
@@ -67,23 +70,34 @@ LocalVideo.prototype.changeVideo = function (stream) {
this.videoStream = stream;
let localVideoClick = (event) => {
- // TODO Checking the classList is a workround to allow events to bubble
+ // TODO Checking the classes is a workround to allow events to bubble
// into the DisplayName component if it was clicked. React's synthetic
// events will fire after jQuery handlers execute, so stop propogation
// at this point will prevent DisplayName from getting click events.
// This workaround should be removeable once LocalVideo is a React
// Component because then the components share the same eventing system.
+ const $source = $(event.target || event.srcElement);
const { classList } = event.target;
- const clickedOnDisplayName = classList.contains('displayname')
- || classList.contains('editdisplayname');
+
+ const clickedOnDisplayName
+ = $source.parents('.displayNameContainer').length > 0;
+ const clickedOnPopover
+ = $source.parents('.connection-info').length > 0;
+ const clickedOnPopoverTrigger
+ = $source.parents('.popover-trigger').length > 0
+ || classList.contains('popover-trigger');
+
+ const ignoreClick = clickedOnDisplayName
+ || clickedOnPopoverTrigger
+ || clickedOnPopover;
// FIXME: with Temasys plugin event arg is not an event, but
// the clicked object itself, so we have to skip this call
- if (event.stopPropagation && !clickedOnDisplayName) {
+ if (event.stopPropagation && !ignoreClick) {
event.stopPropagation();
}
- if (!clickedOnDisplayName) {
+ if (!ignoreClick) {
this.VideoLayout.handleVideoThumbClicked(this.id);
}
};
diff --git a/modules/UI/videolayout/RemoteVideo.js b/modules/UI/videolayout/RemoteVideo.js
index 38804e120..0aec85b8b 100644
--- a/modules/UI/videolayout/RemoteVideo.js
+++ b/modules/UI/videolayout/RemoteVideo.js
@@ -4,15 +4,14 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
+import { I18nextProvider } from 'react-i18next';
+
+import { i18next } from '../../../react/features/base/i18n';
import { PresenceLabel } from '../../../react/features/presence-status';
import {
- MuteButton,
- KickButton,
REMOTE_CONTROL_MENU_STATES,
- RemoteControlButton,
- RemoteVideoMenu,
- VolumeSlider
+ RemoteVideoMenuTriggerButton
} from '../../../react/features/remote-video-menu';
/* eslint-enable no-unused-vars */
@@ -21,13 +20,7 @@ const logger = require("jitsi-meet-logger").getLogger(__filename);
import SmallVideo from "./SmallVideo";
import UIUtils from "../util/UIUtil";
-import UIEvents from '../../../service/UI/UIEvents';
-import JitsiPopover from "../util/JitsiPopover";
-const MUTED_DIALOG_BUTTON_VALUES = {
- cancel: 0,
- muted: 1
-};
const ParticipantConnectionStatus
= JitsiMeetJS.constants.participantConnectionStatus;
@@ -49,6 +42,8 @@ function RemoteVideo(user, VideoLayout, emitter) {
this._audioStreamElement = null;
this.hasRemoteVideoMenu = false;
this._supportsRemoteControl = false;
+ this.statsPopoverLocation = interfaceConfig.VERTICAL_FILMSTRIP
+ ? 'left top' : 'top center';
this.addRemoteVideoContainer();
this.updateIndicators();
this.setDisplayName();
@@ -78,8 +73,6 @@ function RemoteVideo(user, VideoLayout, emitter) {
// Bind event handlers so they are only bound once for every instance.
// TODO The event handlers should be turned into actions so changes can be
// handled through reducers and middleware.
- this._kickHandler = this._kickHandler.bind(this);
- this._muteHandler = this._muteHandler.bind(this);
this._requestRemoteControlPermissions
= this._requestRemoteControlPermissions.bind(this);
this._setAudioVolume = this._setAudioVolume.bind(this);
@@ -107,39 +100,6 @@ RemoteVideo.prototype.addRemoteVideoContainer = function() {
return this.container;
};
-/**
- * Initializes the remote participant popup menu, by specifying previously
- * constructed popupMenuElement, containing all the menu items.
- *
- * @param popupMenuElement a pre-constructed element, containing the menu items
- * to display in the popup
- */
-RemoteVideo.prototype._initPopupMenu = function (popupMenuElement) {
- let options = {
- content: popupMenuElement.outerHTML,
- skin: "black",
- hasArrow: false,
- position: interfaceConfig.VERTICAL_FILMSTRIP ? 'left' : 'top'
- };
- let element = $("#" + this.videoSpanId + " .remotevideomenu");
- this.popover = new JitsiPopover(element, options);
- this.popover.addOnHoverPopover(isHovered => {
- this.popupMenuIsHovered = isHovered;
- this.updateView();
- });
-
- // override popover show method to make sure we will update the content
- // before showing the popover
- let origShowFunc = this.popover.show;
- this.popover.show = function () {
- // update content by forcing it, to finish even if popover
- // is not visible
- this.updateRemoteVideoMenu(this.isAudioMuted, true);
- // call the original show, passing its actual this
- origShowFunc.call(this.popover);
- }.bind(this);
-};
-
/**
* Checks whether current video is considered hovered. Currently it is hovered
* if the mouse is over the video, or if the connection indicator or the popup
@@ -160,6 +120,17 @@ RemoteVideo.prototype._isHovered = function () {
* @private
*/
RemoteVideo.prototype._generatePopupContent = function () {
+ if (interfaceConfig.filmStripOnly) {
+ return;
+ }
+
+ const remoteVideoMenuContainer
+ = this.container.querySelector('.remotevideomenu');
+
+ if (!remoteVideoMenuContainer) {
+ return;
+ }
+
const { controller } = APP.remoteControl;
let remoteControlState = null;
let onRemoteControlToggle;
@@ -189,35 +160,28 @@ RemoteVideo.prototype._generatePopupContent = function () {
const participantID = this.id;
/* jshint ignore:start */
- return (
-
- { isModerator
- ?
+
+
- : null }
- { isModerator
- ?
- : null }
- { remoteControlState
- ?
- : null }
- { onVolumeChange
- ?
- : null }
-
- );
+
+ ,
+ remoteVideoMenuContainer);
/* jshint ignore:end */
};
+RemoteVideo.prototype._onRemoteVideoMenuDisplay = function () {
+ this.updateRemoteVideoMenu(this.isAudioMuted, true);
+};
+
/**
* Sets the remote control supported value and initializes or updates the menu
* depending on the remote control is supported or not.
@@ -288,27 +252,6 @@ RemoteVideo.prototype._stopRemoteControl = function () {
this.updateRemoteVideoMenu(this.isAudioMuted, true);
};
-RemoteVideo.prototype._muteHandler = function () {
- if (this.isAudioMuted)
- return;
-
- RemoteVideo.showMuteParticipantDialog().then(reason => {
- if(reason === MUTED_DIALOG_BUTTON_VALUES.muted) {
- this.emitter.emit(UIEvents.REMOTE_AUDIO_MUTED, this.id);
- }
- }).catch(e => {
- //currently shouldn't be called
- logger.error(e);
- });
-
- this.popover.forceHide();
-};
-
-RemoteVideo.prototype._kickHandler = function () {
- this.emitter.emit(UIEvents.USER_KICKED, this.id);
- this.popover.forceHide();
-};
-
/**
* Get the remote participant's audio element.
*
@@ -345,18 +288,10 @@ RemoteVideo.prototype._setAudioVolume = function (newVal) {
* @param isMuted the new muted state to update to
* @param force to work even if popover is not visible
*/
-RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted, force) {
+RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted) {
this.isAudioMuted = isMuted;
- if (!this.popover) {
- return;
- }
-
- // generate content, translate it and add it to document only if
- // popover is visible or we force to do so.
- if(this.popover.popoverShown || force) {
- this.popover.updateContent(this._generatePopupContent());
- }
+ this._generatePopupContent();
};
/**
@@ -395,17 +330,9 @@ RemoteVideo.prototype.addRemoteVideoMenu = function () {
if (interfaceConfig.filmStripOnly) {
return;
}
- var spanElement = document.createElement('span');
- spanElement.className = 'remotevideomenu';
- this.container.appendChild(spanElement);
+ this._generatePopupContent();
- var menuElement = document.createElement('i');
- menuElement.className = 'icon-thumb-menu';
- menuElement.title = 'Remote user controls';
- spanElement.appendChild(menuElement);
-
- this._initPopupMenu(this._generatePopupContent());
this.hasRemoteVideoMenu = true;
};
@@ -538,6 +465,8 @@ RemoteVideo.prototype.remove = function () {
this._unmountIndicators();
+ this.removeRemoteVideoMenu();
+
// Make sure that the large video is updated if are removing its
// corresponding small video.
this.VideoLayout.updateAfterThumbRemoved(this.id);
@@ -591,17 +520,29 @@ RemoteVideo.prototype.addRemoteStreamElement = function (stream) {
// Add click handler.
let onClickHandler = (event) => {
- let source = event.target || event.srcElement;
+ const $source = $(event.target || event.srcElement);
+ const { classList } = event.target;
- // ignore click if it was done in popup menu
- if ($(source).parents('.popupmenu').length === 0) {
+ const clickedOnPopover
+ = $source.parents('.connection-info').length > 0;
+ const clickedOnPopoverTrigger
+ = $source.parents('.popover-trigger').length > 0
+ || classList.contains('popover-trigger');
+ const clickedOnRemoteMenu
+ = $source.parents('.remotevideomenu').length > 0;
+
+ const ignoreClick = clickedOnPopoverTrigger
+ || clickedOnPopover
+ || clickedOnRemoteMenu;
+
+ if (!ignoreClick) {
this.VideoLayout.handleVideoThumbClicked(this.id);
}
// On IE we need to populate this handler on video