Merge pull request #773 from jitsi/object-fit-fix-and-refactoring-around-it
Object fit fix and refactoring around it
This commit is contained in:
commit
fe6588516f
|
@ -71,7 +71,7 @@
|
||||||
height: 35px;
|
height: 35px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -35;
|
bottom: -35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jitsipopover_green
|
.jitsipopover_green
|
||||||
|
|
|
@ -1,27 +1,10 @@
|
||||||
/*Initialize*/
|
/*Initialize*/
|
||||||
ul.popupmenu {
|
ul.popupmenu {
|
||||||
display:none;
|
padding: 0px 10px 0px 10px;
|
||||||
position: absolute;
|
|
||||||
padding:10px;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
margin-bottom: 35px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
padding-top: 10px;
|
|
||||||
right: 10px;
|
|
||||||
left: -5px;
|
|
||||||
width: 100px;
|
width: 100px;
|
||||||
background-color: rgba(0,0,0,0.9);
|
height: auto;
|
||||||
border: 1px solid rgba(256, 256, 256, 0.2);
|
|
||||||
border-radius:3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.popupmenu:after {
|
|
||||||
content: url('../images/popupPointer.png');
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
bottom: -8px;
|
|
||||||
left: 11px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.popupmenu li {
|
ul.popupmenu li {
|
||||||
|
@ -36,11 +19,13 @@ ul.popupmenu li:hover {
|
||||||
|
|
||||||
/*Link Appearance*/
|
/*Link Appearance*/
|
||||||
ul.popupmenu li a {
|
ul.popupmenu li a {
|
||||||
|
display: block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
display: inline-block;
|
|
||||||
font-size: 9pt;
|
font-size: 9pt;
|
||||||
|
width: 100%;
|
||||||
|
cursor: hand;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.popupmenu li a i.icon-kick {
|
ul.popupmenu li a i.icon-kick {
|
||||||
|
@ -54,6 +39,15 @@ ul.popupmenu li a span {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.popupmenu li a div {
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.popupmenu li a i {
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
span.remotevideomenu:hover ul.popupmenu, ul.popupmenu:hover {
|
span.remotevideomenu:hover ul.popupmenu, ul.popupmenu:hover {
|
||||||
display:block !important;
|
display:block !important;
|
||||||
}
|
}
|
||||||
|
@ -62,11 +56,3 @@ a.disabled {
|
||||||
color: gray !important;
|
color: gray !important;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popupmenuPadding {
|
|
||||||
height: 35px;
|
|
||||||
width: 100px;
|
|
||||||
position: absolute;
|
|
||||||
bottom: -35;
|
|
||||||
left: 0px;
|
|
||||||
}
|
|
|
@ -41,20 +41,22 @@
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
border-radius:1px;
|
border-radius:1px;
|
||||||
border: 1px solid #212425;
|
border: 1px solid #212425;
|
||||||
/*margin-right: 1px;*/
|
/**
|
||||||
|
* Some browsers don't have full support of the object-fit property for the
|
||||||
|
* video element and when we set video object-fit to "cover" the video
|
||||||
|
* actually overflows the boundaries of its container, so it's important
|
||||||
|
* to indicate that the "overflow" should be hidden.
|
||||||
|
*/
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#remoteVideos .videocontainer:hover,*/
|
|
||||||
#remoteVideos .videocontainer.videoContainerFocused {
|
#remoteVideos .videocontainer.videoContainerFocused {
|
||||||
cursor: hand;
|
cursor: hand;
|
||||||
/* transform:scale(1.08, 1.08);
|
|
||||||
-webkit-transform:scale(1.08, 1.08); */
|
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
-webkit-transition-duration: 0.5s;
|
-webkit-transition-duration: 0.5s;
|
||||||
-webkit-animation-name: greyPulse;
|
-webkit-animation-name: greyPulse;
|
||||||
-webkit-animation-duration: 2s;
|
-webkit-animation-duration: 2s;
|
||||||
-webkit-animation-iteration-count: 1;
|
-webkit-animation-iteration-count: 1;
|
||||||
overflow: visible !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#remoteVideos .videocontainer:hover {
|
#remoteVideos .videocontainer:hover {
|
||||||
|
@ -82,6 +84,7 @@
|
||||||
cursor: hand;
|
cursor: hand;
|
||||||
border-radius:1px;
|
border-radius:1px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flipVideoX {
|
.flipVideoX {
|
||||||
|
@ -144,8 +147,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#remoteVideos .videocontainer>span.focusindicator,
|
#remoteVideos .videocontainer>span.focusindicator,
|
||||||
#remoteVideos .videocontainer>span.remotevideomenu {
|
#remoteVideos .videocontainer>div.remotevideomenu {
|
||||||
display: inline-block;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -159,6 +161,14 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#remoteVideos .videocontainer>span.focusindicator {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#remoteVideos .videocontainer>div.remotevideomenu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.videocontainer>span.displayname,
|
.videocontainer>span.displayname,
|
||||||
.videocontainer>input.displayname {
|
.videocontainer>input.displayname {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import SmallVideo from "./SmallVideo";
|
||||||
import AudioLevels from "../audio_levels/AudioLevels";
|
import AudioLevels from "../audio_levels/AudioLevels";
|
||||||
import UIUtils from "../util/UIUtil";
|
import UIUtils from "../util/UIUtil";
|
||||||
import UIEvents from '../../../service/UI/UIEvents';
|
import UIEvents from '../../../service/UI/UIEvents';
|
||||||
|
import JitsiPopover from "../util/JitsiPopover";
|
||||||
|
|
||||||
function RemoteVideo(id, VideoLayout, emitter) {
|
function RemoteVideo(id, VideoLayout, emitter) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -18,6 +19,7 @@ function RemoteVideo(id, VideoLayout, emitter) {
|
||||||
this.bindHoverHandler();
|
this.bindHoverHandler();
|
||||||
this.flipX = false;
|
this.flipX = false;
|
||||||
this.isLocal = false;
|
this.isLocal = false;
|
||||||
|
this.isMuted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteVideo.prototype = Object.create(SmallVideo.prototype);
|
RemoteVideo.prototype = Object.create(SmallVideo.prototype);
|
||||||
|
@ -34,6 +36,126 @@ RemoteVideo.prototype.addRemoteVideoContainer = function() {
|
||||||
return this.container;
|
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) {
|
||||||
|
this.popover = new JitsiPopover(
|
||||||
|
$("#" + this.videoSpanId + " > .remotevideomenu"),
|
||||||
|
{ content: popupMenuElement.outerHTML,
|
||||||
|
skin: "black"});
|
||||||
|
|
||||||
|
// override popover show method to make sure we will update the content
|
||||||
|
// before showing the popover
|
||||||
|
var origShowFunc = this.popover.show;
|
||||||
|
this.popover.show = function () {
|
||||||
|
// update content by forcing it, to finish even if popover
|
||||||
|
// is not visible
|
||||||
|
this.updateRemoteVideoMenu(this.isMuted, true);
|
||||||
|
// call the original show, passing its actual this
|
||||||
|
origShowFunc.call(this.popover);
|
||||||
|
}.bind(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the popup menu content.
|
||||||
|
*
|
||||||
|
* @returns {Element|*} the constructed element, containing popup menu items
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
RemoteVideo.prototype._generatePopupContent = function () {
|
||||||
|
var popupmenuElement = document.createElement('ul');
|
||||||
|
popupmenuElement.className = 'popupmenu';
|
||||||
|
popupmenuElement.id = `remote_popupmenu_${this.id}`;
|
||||||
|
|
||||||
|
var muteMenuItem = document.createElement('li');
|
||||||
|
var muteLinkItem = document.createElement('a');
|
||||||
|
|
||||||
|
var mutedIndicator = "<i class='icon-mic-disabled'></i>";
|
||||||
|
|
||||||
|
var doMuteHTML = mutedIndicator +
|
||||||
|
" <div " +
|
||||||
|
"data-i18n='videothumbnail.domute'>" +
|
||||||
|
APP.translation.translateString("videothumbnail.domute") +
|
||||||
|
"</div>";
|
||||||
|
|
||||||
|
var mutedHTML = mutedIndicator +
|
||||||
|
" <div " +
|
||||||
|
"data-i18n='videothumbnail.muted'>" +
|
||||||
|
APP.translation.translateString("videothumbnail.muted") +
|
||||||
|
"</div>";
|
||||||
|
|
||||||
|
muteLinkItem.id = "muteLinkItem";
|
||||||
|
|
||||||
|
if (this.isMuted) {
|
||||||
|
muteLinkItem.innerHTML = mutedHTML;
|
||||||
|
muteLinkItem.className = 'mutelink disabled';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
muteLinkItem.innerHTML = doMuteHTML;
|
||||||
|
muteLinkItem.className = 'mutelink';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delegate event to the document.
|
||||||
|
$(document).on("click", ".mutelink", function(){
|
||||||
|
|
||||||
|
if (this.isMuted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.emitter.emit(UIEvents.REMOTE_AUDIO_MUTED, this.id);
|
||||||
|
|
||||||
|
this.popover.forceHide();
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
muteMenuItem.appendChild(muteLinkItem);
|
||||||
|
popupmenuElement.appendChild(muteMenuItem);
|
||||||
|
|
||||||
|
var ejectIndicator = "<i style='float:left;' class='fa fa-eject'></i>";
|
||||||
|
|
||||||
|
var ejectMenuItem = document.createElement('li');
|
||||||
|
var ejectLinkItem = document.createElement('a');
|
||||||
|
|
||||||
|
var ejectText = "<div " +
|
||||||
|
"data-i18n='videothumbnail.kick'>" +
|
||||||
|
APP.translation.translateString("videothumbnail.kick") +
|
||||||
|
"</div>";
|
||||||
|
|
||||||
|
ejectLinkItem.className = 'ejectlink';
|
||||||
|
ejectLinkItem.innerHTML = ejectIndicator + ' ' + ejectText;
|
||||||
|
|
||||||
|
$(document).on("click", ".ejectlink", function(){
|
||||||
|
this.emitter.emit(UIEvents.USER_KICKED, this.id);
|
||||||
|
this.popover.forceHide();
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
ejectMenuItem.appendChild(ejectLinkItem);
|
||||||
|
popupmenuElement.appendChild(ejectMenuItem);
|
||||||
|
|
||||||
|
return popupmenuElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the remote video menu.
|
||||||
|
*
|
||||||
|
* @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) {
|
||||||
|
|
||||||
|
this.isMuted = isMuted;
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the remote video menu element for the given <tt>id</tt> in the
|
* Adds the remote video menu element for the given <tt>id</tt> in the
|
||||||
* given <tt>parentElement</tt>.
|
* given <tt>parentElement</tt>.
|
||||||
|
@ -43,9 +165,8 @@ RemoteVideo.prototype.addRemoteVideoContainer = function() {
|
||||||
*/
|
*/
|
||||||
if (!interfaceConfig.filmStripOnly) {
|
if (!interfaceConfig.filmStripOnly) {
|
||||||
RemoteVideo.prototype.addRemoteVideoMenu = function () {
|
RemoteVideo.prototype.addRemoteVideoMenu = function () {
|
||||||
var spanElement = document.createElement('span');
|
var spanElement = document.createElement('div');
|
||||||
spanElement.className = 'remotevideomenu';
|
spanElement.className = 'remotevideomenu';
|
||||||
|
|
||||||
this.container.appendChild(spanElement);
|
this.container.appendChild(spanElement);
|
||||||
|
|
||||||
var menuElement = document.createElement('i');
|
var menuElement = document.createElement('i');
|
||||||
|
@ -53,77 +174,7 @@ if (!interfaceConfig.filmStripOnly) {
|
||||||
menuElement.title = 'Remote user controls';
|
menuElement.title = 'Remote user controls';
|
||||||
spanElement.appendChild(menuElement);
|
spanElement.appendChild(menuElement);
|
||||||
|
|
||||||
|
this._initPopupMenu(this._generatePopupContent());
|
||||||
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 = "<i style='float:left;' " +
|
|
||||||
"class='icon-mic-disabled'></i>";
|
|
||||||
|
|
||||||
if (!this.isMuted) {
|
|
||||||
muteLinkItem.innerHTML = mutedIndicator +
|
|
||||||
" <div style='width: 90px;margin-left: 20px;' " +
|
|
||||||
"data-i18n='videothumbnail.domute'></div>";
|
|
||||||
muteLinkItem.className = 'mutelink';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
muteLinkItem.innerHTML = mutedIndicator +
|
|
||||||
" <div style='width: 90px;margin-left: 20px;' " +
|
|
||||||
"data-i18n='videothumbnail.muted'></div>";
|
|
||||||
muteLinkItem.className = 'mutelink disabled';
|
|
||||||
}
|
|
||||||
|
|
||||||
muteLinkItem.onclick = (event) => {
|
|
||||||
if ($(this).attr('disabled')) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
var isMute = !!this.isMuted;
|
|
||||||
this.emitter.emit(UIEvents.REMOTE_AUDIO_MUTED, this.id);
|
|
||||||
|
|
||||||
popupmenuElement.setAttribute('style', 'display:none;');
|
|
||||||
|
|
||||||
if (isMute) {
|
|
||||||
this.innerHTML = mutedIndicator +
|
|
||||||
" <div style='width: 90px;margin-left: 20px;' " +
|
|
||||||
"data-i18n='videothumbnail.muted'></div>";
|
|
||||||
this.className = 'mutelink disabled';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.innerHTML = mutedIndicator +
|
|
||||||
" <div style='width: 90px;margin-left: 20px;' " +
|
|
||||||
"data-i18n='videothumbnail.domute'></div>";
|
|
||||||
this.className = 'mutelink';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
muteMenuItem.appendChild(muteLinkItem);
|
|
||||||
popupmenuElement.appendChild(muteMenuItem);
|
|
||||||
|
|
||||||
var ejectIndicator = "<i style='float:left;' class='fa fa-eject'></i>";
|
|
||||||
|
|
||||||
var ejectMenuItem = document.createElement('li');
|
|
||||||
var ejectLinkItem = document.createElement('a');
|
|
||||||
var ejectText = "<div style='width: 90px;margin-left: 20px;' " +
|
|
||||||
"data-i18n='videothumbnail.kick'> </div>";
|
|
||||||
ejectLinkItem.innerHTML = ejectIndicator + ' ' + ejectText;
|
|
||||||
ejectLinkItem.onclick = (event) => {
|
|
||||||
this.emitter.emit(UIEvents.USER_KICKED, this.id);
|
|
||||||
popupmenuElement.setAttribute('style', 'display:none;');
|
|
||||||
};
|
|
||||||
|
|
||||||
ejectMenuItem.appendChild(ejectLinkItem);
|
|
||||||
popupmenuElement.appendChild(ejectMenuItem);
|
|
||||||
|
|
||||||
var paddingSpan = document.createElement('span');
|
|
||||||
paddingSpan.className = 'popupmenuPadding';
|
|
||||||
popupmenuElement.appendChild(paddingSpan);
|
|
||||||
APP.translation.translateElement(
|
|
||||||
$("#" + popupmenuElement.id + " > li > a > div"));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -313,31 +364,6 @@ RemoteVideo.prototype.hideConnectionIndicator = function () {
|
||||||
this.connectionIndicator.hide();
|
this.connectionIndicator.hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the remote video menu.
|
|
||||||
*
|
|
||||||
* @param id the id indicating the video for which we're adding a menu.
|
|
||||||
* @param isMuted indicates the current mute state
|
|
||||||
*/
|
|
||||||
RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted) {
|
|
||||||
var muteMenuItem = $(`#remote_popupmenu_${this.id}>li>a.mutelink`);
|
|
||||||
|
|
||||||
var mutedIndicator = "<i class='icon-mic-disabled'></i>";
|
|
||||||
|
|
||||||
if (muteMenuItem.length) {
|
|
||||||
var muteLink = muteMenuItem.get(0);
|
|
||||||
|
|
||||||
if (isMuted) {
|
|
||||||
muteLink.innerHTML = mutedIndicator + ' Muted';
|
|
||||||
muteLink.className = 'mutelink disabled';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
muteLink.innerHTML = mutedIndicator + ' Mute';
|
|
||||||
muteLink.className = 'mutelink';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the display name for the given video span id.
|
* Sets the display name for the given video span id.
|
||||||
*/
|
*/
|
||||||
|
@ -388,6 +414,7 @@ RemoteVideo.prototype.setDisplayName = function(displayName, key) {
|
||||||
RemoteVideo.prototype.removeRemoteVideoMenu = function() {
|
RemoteVideo.prototype.removeRemoteVideoMenu = function() {
|
||||||
var menuSpan = $('#' + this.videoSpanId + '>span.remotevideomenu');
|
var menuSpan = $('#' + this.videoSpanId + '>span.remotevideomenu');
|
||||||
if (menuSpan.length) {
|
if (menuSpan.length) {
|
||||||
|
this.popover.forceHide();
|
||||||
menuSpan.remove();
|
menuSpan.remove();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue