Merge pull request #878 from jitsi/video-thumbnail-redesign
Video thumbnails redesign
This commit is contained in:
commit
9b25467080
|
@ -16,7 +16,7 @@
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-variant: normal;
|
font-variant: normal;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
line-height: 0.75em;
|
line-height: 1.22em;
|
||||||
font-size: 1.22em;
|
font-size: 1.22em;
|
||||||
|
|
||||||
/* Better Font Rendering =========== */
|
/* Better Font Rendering =========== */
|
||||||
|
|
|
@ -36,6 +36,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin circle($diameter) {
|
||||||
|
width: $diameter;
|
||||||
|
height: $diameter;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin absoluteAligning($sizeX, $sizeY) {
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
position: absolute;
|
||||||
|
@include transform(translate(-#{$sizeX / 2}, -#{$sizeY / 2}))
|
||||||
|
}
|
||||||
|
|
||||||
@mixin transform($func) {
|
@mixin transform($func) {
|
||||||
-moz-transform: $func;
|
-moz-transform: $func;
|
||||||
-ms-transform: $func;
|
-ms-transform: $func;
|
||||||
|
|
|
@ -10,6 +10,11 @@ $hangupFontSize: 2em;
|
||||||
*/
|
*/
|
||||||
$defaultToolbarSize: 50px;
|
$defaultToolbarSize: 50px;
|
||||||
|
|
||||||
|
// Video layout.
|
||||||
|
$thumbnailIndicatorSize: 23px;
|
||||||
|
$thumbnailIndicatorBorder: 0px;
|
||||||
|
$thumbnailVideoMargin: 2px;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Color variables.
|
* Color variables.
|
||||||
*/
|
*/
|
||||||
|
@ -17,13 +22,29 @@ $defaultColor: #F1F1F1;
|
||||||
$defaultSemiDarkColor: #ACACAC;
|
$defaultSemiDarkColor: #ACACAC;
|
||||||
$defaultDarkColor: #4F4F4F;
|
$defaultDarkColor: #4F4F4F;
|
||||||
$defaultBackground: #474747;
|
$defaultBackground: #474747;
|
||||||
|
|
||||||
|
// Toolbar
|
||||||
$toolbarSelectBackground: rgba(0, 0, 0, .6);
|
$toolbarSelectBackground: rgba(0, 0, 0, .6);
|
||||||
|
|
||||||
|
// Main controls
|
||||||
$inputBackground: rgba(132, 132, 132, .5);
|
$inputBackground: rgba(132, 132, 132, .5);
|
||||||
$inputSemiBackground: rgba(132, 132, 132, .8);
|
$inputSemiBackground: rgba(132, 132, 132, .8);
|
||||||
$inputLightBackground: #EBEBEB;
|
$inputLightBackground: #EBEBEB;
|
||||||
$inputBorderColor: #EBEBEB;
|
$inputBorderColor: #EBEBEB;
|
||||||
$buttonBackground: #44A5FF;
|
$buttonBackground: #44A5FF;
|
||||||
|
|
||||||
|
// Video layout.
|
||||||
|
$videoThumbnailHovered: #44A5FF;
|
||||||
|
$videoThumbnailSelected: #165ecc;
|
||||||
|
$participantNameColor: #fff;
|
||||||
|
$thumbnailPictogramColor: #fff;
|
||||||
|
$dominantSpeakerBg: #165ecc;
|
||||||
|
$raiseHandBg: #D6D61E;
|
||||||
|
|
||||||
|
$rateStarDefault: #ccc;
|
||||||
|
$rateStarActivity: #165ecc;
|
||||||
|
$rateStarLabelColor: #333;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Misc.
|
* Misc.
|
||||||
*/
|
*/
|
||||||
|
@ -34,8 +55,4 @@ $defaultWatermarkLink: '../images/watermark.png';
|
||||||
* Z-indexes. TODO: Replace this by a function.
|
* Z-indexes. TODO: Replace this by a function.
|
||||||
*/
|
*/
|
||||||
$toolbarZ: 900;
|
$toolbarZ: 900;
|
||||||
$overlayZ: 800;
|
$overlayZ: 800;
|
||||||
|
|
||||||
$rateStarDefault: #ccc;
|
|
||||||
$rateStarActivity: #f6c342;
|
|
||||||
$rateStarLabelColor: #333;
|
|
|
@ -13,17 +13,17 @@
|
||||||
display: -ms-flexbox;
|
display: -ms-flexbox;
|
||||||
display: -webkit-flex;
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row-reverse;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
justify-content: flex-end;
|
justify-content: flex-start;
|
||||||
|
|
||||||
position:absolute;
|
position:absolute;
|
||||||
text-align:right;
|
text-align:right;
|
||||||
height:196px;
|
height:196px;
|
||||||
padding: 18px;
|
padding: 10px 10px 10px 5px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 20px;
|
right: 0;
|
||||||
width:auto;
|
width:auto;
|
||||||
border:1px solid transparent;
|
border:1px solid transparent;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
|
@ -43,10 +43,23 @@
|
||||||
|
|
||||||
#remoteVideos .videocontainer {
|
#remoteVideos .videocontainer {
|
||||||
display: none;
|
display: none;
|
||||||
|
position: relative;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
border-radius:1px;
|
border-radius:1px;
|
||||||
border: 1px solid #212425;
|
margin: 0 $thumbnailVideoMargin;
|
||||||
|
border: 1px solid $defaultDarkColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.videocontainer__toolbar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 25px;
|
||||||
|
max-height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#remoteVideos .videocontainer.videoContainerFocused {
|
#remoteVideos .videocontainer.videoContainerFocused {
|
||||||
|
@ -58,18 +71,13 @@
|
||||||
-webkit-animation-iteration-count: 1;
|
-webkit-animation-iteration-count: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#remoteVideos .videocontainer:hover {
|
|
||||||
border: 1px solid #c1c1c1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#remoteVideos .videocontainer.videoContainerFocused {
|
#remoteVideos .videocontainer.videoContainerFocused {
|
||||||
box-shadow: inset 0 0 28px #006d91;
|
border: 1px solid $videoThumbnailSelected;
|
||||||
border: 1px solid #006d91;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#remoteVideos .videocontainer:hover,
|
||||||
#remoteVideos .videocontainer.videoContainerFocused:hover {
|
#remoteVideos .videocontainer.videoContainerFocused:hover {
|
||||||
box-shadow: inset 0 0 5px #c1c1c1, 0 0 10px #c1c1c1, inset 0 0 60px #006d91;
|
border: 1px solid $videoThumbnailHovered;
|
||||||
border: 1px solid #c1c1c1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#localVideoWrapper {
|
#localVideoWrapper {
|
||||||
|
@ -145,11 +153,11 @@
|
||||||
#remoteVideos .videocontainer>div.remotevideomenu {
|
#remoteVideos .videocontainer>div.remotevideomenu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
top: 0;
|
bottom: 0;
|
||||||
left: 0;
|
right: 0;
|
||||||
padding: 5px 0px;
|
padding: 5px 0px;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
font-size: 11pt;
|
font-size: 9pt;
|
||||||
text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
|
text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
|
||||||
border: 0px;
|
border: 0px;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
@ -166,22 +174,28 @@
|
||||||
|
|
||||||
.videocontainer>span.displayname,
|
.videocontainer>span.displayname,
|
||||||
.videocontainer>input.displayname {
|
.videocontainer>input.displayname {
|
||||||
display: none;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: #FFFFFF;
|
bottom: 4px;
|
||||||
background: rgba(0,0,0,.7);
|
left: 25%;
|
||||||
|
color: $participantNameColor;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
width: 70%;
|
width: 50%;
|
||||||
height: 20%;
|
font-size: 12px;
|
||||||
left: 15%;
|
font-weight: 100;
|
||||||
top: 40%;
|
letter-spacing: 1px;
|
||||||
padding: 5px;
|
|
||||||
font-size: 11pt;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
border-radius:3px;
|
}
|
||||||
|
|
||||||
|
.videocontainer>input.displayname {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.videocontainer>span.status {
|
.videocontainer>span.status {
|
||||||
|
@ -291,7 +305,8 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
top: 0;
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
padding: 8px 5px;
|
padding: 8px 5px;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
|
@ -305,8 +320,7 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
top: 0;
|
bottom: 0;
|
||||||
right: 0;
|
|
||||||
padding: 8px 5px;
|
padding: 8px 5px;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
|
@ -316,24 +330,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.videocontainer>span.indicator {
|
.videocontainer>span.indicator {
|
||||||
bottom: 0px;
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
width: 25px;
|
@include circle($thumbnailIndicatorSize);
|
||||||
height: 25px;
|
box-sizing: border-box;
|
||||||
|
line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 50%;
|
background: $dominantSpeakerBg;
|
||||||
background: #21B9FC;
|
margin: 7px;
|
||||||
margin: 5px;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
color: $thumbnailPictogramColor;
|
||||||
color: #FFFFFF;
|
font-size: 8pt;
|
||||||
font-size: 11pt;
|
border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor;
|
||||||
border: 0px;
|
}
|
||||||
|
|
||||||
|
.videocontainer>#raisehandindicator {
|
||||||
|
background: $raiseHandBg;
|
||||||
}
|
}
|
||||||
|
|
||||||
#indicatoricon {
|
#indicatoricon {
|
||||||
padding-top: 5px;
|
width: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
|
||||||
|
height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
|
||||||
|
line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
#reloadPresentation {
|
#reloadPresentation {
|
||||||
|
@ -395,10 +415,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.userAvatar {
|
.userAvatar {
|
||||||
height: 100%;
|
@include circle(60px);
|
||||||
position: absolute;
|
@include absoluteAligning(60px, 60px);
|
||||||
left: 0;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sharedVideoAvatar {
|
.sharedVideoAvatar {
|
||||||
|
|
|
@ -238,12 +238,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="remoteVideos">
|
<div id="remoteVideos">
|
||||||
<span id="localVideoContainer" class="videocontainer">
|
<span id="localVideoContainer" class="videocontainer videocontainer_small">
|
||||||
<span id="localVideoWrapper">
|
<span id="localVideoWrapper">
|
||||||
<!--<video id="localVideo" autoplay muted></video> - is now per stream generated -->
|
<!--<video id="localVideo" autoplay muted></video> - is now per stream generated -->
|
||||||
</span>
|
</span>
|
||||||
<audio id="localAudio" autoplay muted></audio>
|
<audio id="localAudio" autoplay muted></audio>
|
||||||
<span class="focusindicator"></span>
|
<span class="focusindicator"></span>
|
||||||
|
<div class="videocontainer__toolbar"></div>
|
||||||
</span>
|
</span>
|
||||||
<audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
|
<audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
|
||||||
<audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>
|
<audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>
|
||||||
|
|
|
@ -34,5 +34,9 @@ var interfaceConfig = {
|
||||||
filmStripOnly: false,
|
filmStripOnly: false,
|
||||||
RANDOM_AVATAR_URL_PREFIX: false,
|
RANDOM_AVATAR_URL_PREFIX: false,
|
||||||
RANDOM_AVATAR_URL_SUFFIX: false,
|
RANDOM_AVATAR_URL_SUFFIX: false,
|
||||||
FILM_STRIP_MAX_HEIGHT: 120
|
FILM_STRIP_MAX_HEIGHT: 120,
|
||||||
};
|
LOCAL_THUMBNAIL_RATIO_WIDTH: 16,
|
||||||
|
LOCAL_THUMBNAIL_RATIO_HEIGHT: 9,
|
||||||
|
REMOTE_THUMBNAIL_RATIO_WIDTH: 1,
|
||||||
|
REMOTE_THUMBNAIL_RATIO_HEIGHT: 1
|
||||||
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* global $, APP, config, interfaceConfig, JitsiMeetJS */
|
/* global $, APP, config, interfaceConfig, JitsiMeetJS */
|
||||||
import UIEvents from "../../service/UI/UIEvents";
|
import UIEvents from "../../service/UI/UIEvents";
|
||||||
|
import UIUtil from "./util/UIUtil";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the html for the overall feedback window.
|
* Constructs the html for the overall feedback window.
|
||||||
|
|
|
@ -10,7 +10,7 @@ let ASDrawContext = null;
|
||||||
let audioLevelCanvasCache = {};
|
let audioLevelCanvasCache = {};
|
||||||
let dominantSpeakerAudioElement = null;
|
let dominantSpeakerAudioElement = null;
|
||||||
|
|
||||||
function initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
|
function _initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
|
||||||
let ASRadius = dominantSpeakerAvatarSize / 2;
|
let ASRadius = dominantSpeakerAvatarSize / 2;
|
||||||
let ASCenter = (dominantSpeakerAvatarSize + ASRadius) / 2;
|
let ASCenter = (dominantSpeakerAvatarSize + ASRadius) / 2;
|
||||||
|
|
||||||
|
@ -28,7 +28,9 @@ function initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
|
||||||
/**
|
/**
|
||||||
* Resizes the given audio level canvas to match the given thumbnail size.
|
* Resizes the given audio level canvas to match the given thumbnail size.
|
||||||
*/
|
*/
|
||||||
function resizeAudioLevelCanvas(audioLevelCanvas, thumbnailWidth, thumbnailHeight) {
|
function _resizeAudioLevelCanvas( audioLevelCanvas,
|
||||||
|
thumbnailWidth,
|
||||||
|
thumbnailHeight) {
|
||||||
audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
|
audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
|
||||||
audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
|
audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
|
||||||
}
|
}
|
||||||
|
@ -138,18 +140,18 @@ const AudioLevels = {
|
||||||
dominantSpeakerAudioElement.height = dominantSpeakerHeight;
|
dominantSpeakerAudioElement.height = dominantSpeakerHeight;
|
||||||
|
|
||||||
let dominantSpeakerAvatar = $("#dominantSpeakerAvatar");
|
let dominantSpeakerAvatar = $("#dominantSpeakerAvatar");
|
||||||
initDominantSpeakerAudioLevels(dominantSpeakerAvatar.width());
|
_initDominantSpeakerAudioLevels(dominantSpeakerAvatar.width());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the audio level canvas for the given id. If the canvas
|
* Updates the audio level canvas for the given id. If the canvas
|
||||||
* didn't exist we create it.
|
* didn't exist we create it.
|
||||||
*/
|
*/
|
||||||
updateAudioLevelCanvas (id, thumbWidth, thumbHeight) {
|
createAudioLevelCanvas (id, thumbWidth, thumbHeight) {
|
||||||
let videoSpanId = 'localVideoContainer';
|
|
||||||
if (id) {
|
let videoSpanId = (id === "local")
|
||||||
videoSpanId = `participant_${id}`;
|
? "localVideoContainer"
|
||||||
}
|
: `participant_${id}`;
|
||||||
|
|
||||||
let videoSpan = document.getElementById(videoSpanId);
|
let videoSpan = document.getElementById(videoSpanId);
|
||||||
|
|
||||||
|
@ -172,13 +174,13 @@ const AudioLevels = {
|
||||||
= `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
= `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||||
audioLevelCanvas.style.left
|
audioLevelCanvas.style.left
|
||||||
= `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
= `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
_resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||||
|
|
||||||
videoSpan.appendChild(audioLevelCanvas);
|
videoSpan.appendChild(audioLevelCanvas);
|
||||||
} else {
|
} else {
|
||||||
audioLevelCanvas = audioLevelCanvas.get(0);
|
audioLevelCanvas = audioLevelCanvas.get(0);
|
||||||
|
|
||||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
_resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -242,19 +244,29 @@ const AudioLevels = {
|
||||||
ASDrawContext.fill();
|
ASDrawContext.fill();
|
||||||
},
|
},
|
||||||
|
|
||||||
updateCanvasSize (thumbWidth, thumbHeight) {
|
updateCanvasSize (localVideo, remoteVideo) {
|
||||||
let canvasWidth = thumbWidth + interfaceConfig.CANVAS_EXTRA;
|
let localCanvasWidth
|
||||||
let canvasHeight = thumbHeight + interfaceConfig.CANVAS_EXTRA;
|
= localVideo.thumbWidth + interfaceConfig.CANVAS_EXTRA;
|
||||||
|
let localCanvasHeight
|
||||||
|
= localVideo.thumbHeight + interfaceConfig.CANVAS_EXTRA;
|
||||||
|
let remoteCanvasWidth
|
||||||
|
= remoteVideo.thumbWidth + interfaceConfig.CANVAS_EXTRA;
|
||||||
|
let remoteCanvasHeight
|
||||||
|
= remoteVideo.thumbHeight + interfaceConfig.CANVAS_EXTRA;
|
||||||
|
|
||||||
FilmStrip.getThumbs().children('canvas').each(function () {
|
let { remoteThumbs, localThumb } = FilmStrip.getThumbs();
|
||||||
$(this).attr('width', canvasWidth);
|
|
||||||
$(this).attr('height', canvasHeight);
|
remoteThumbs.children('canvas').each(function () {
|
||||||
|
$(this).attr('width', remoteCanvasWidth);
|
||||||
|
$(this).attr('height', remoteCanvasHeight);
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(audioLevelCanvasCache).forEach(function (id) {
|
if(localThumb) {
|
||||||
audioLevelCanvasCache[id].width = canvasWidth;
|
localThumb.children('canvas').each(function () {
|
||||||
audioLevelCanvasCache[id].height = canvasHeight;
|
$(this).attr('width', localCanvasWidth);
|
||||||
});
|
$(this).attr('height', localCanvasHeight);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import SideContainerToggler from "../side_pannels/SideContainerToggler";
|
||||||
let roomUrl = null;
|
let roomUrl = null;
|
||||||
let emitter = null;
|
let emitter = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the invite link dialog.
|
* Opens the invite link dialog.
|
||||||
*/
|
*/
|
||||||
|
@ -766,4 +765,4 @@ const Toolbar = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Toolbar;
|
export default Toolbar;
|
|
@ -3,8 +3,6 @@
|
||||||
import UIEvents from "../../../service/UI/UIEvents";
|
import UIEvents from "../../../service/UI/UIEvents";
|
||||||
import UIUtil from "../util/UIUtil";
|
import UIUtil from "../util/UIUtil";
|
||||||
|
|
||||||
const thumbAspectRatio = 1 / 1;
|
|
||||||
|
|
||||||
const FilmStrip = {
|
const FilmStrip = {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -66,13 +64,52 @@ const FilmStrip = {
|
||||||
- parseInt(this.filmStrip.css('paddingRight'), 10);
|
- parseInt(this.filmStrip.css('paddingRight'), 10);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
calculateThumbnailSize() {
|
||||||
* Calculates the thumbnail size.
|
let availableSizes = this.calculateAvailableSize();
|
||||||
*/
|
let width = availableSizes.availableWidth;
|
||||||
calculateThumbnailSize () {
|
let height = availableSizes.availableHeight;
|
||||||
let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
|
|
||||||
|
|
||||||
let numvids = this.getThumbs(true).length;
|
return this.calculateThumbnailSizeFromAvailable(width, height);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes local and remote thumbnail ratios
|
||||||
|
*/
|
||||||
|
normalizeThumbnailRatio () {
|
||||||
|
let remoteHeightRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_HEIGHT;
|
||||||
|
let remoteWidthRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_WIDTH;
|
||||||
|
|
||||||
|
let localHeightRatio = interfaceConfig.LOCAL_THUMBNAIL_RATIO_HEIGHT;
|
||||||
|
let localWidthRatio = interfaceConfig.LOCAL_THUMBNAIL_RATIO_WIDTH;
|
||||||
|
|
||||||
|
let commonHeightRatio = remoteHeightRatio * localHeightRatio;
|
||||||
|
|
||||||
|
let localRatioCoefficient = localWidthRatio / localHeightRatio;
|
||||||
|
let remoteRatioCoefficient = remoteWidthRatio / remoteHeightRatio;
|
||||||
|
|
||||||
|
remoteWidthRatio = commonHeightRatio * remoteRatioCoefficient;
|
||||||
|
remoteHeightRatio = commonHeightRatio;
|
||||||
|
|
||||||
|
localWidthRatio = commonHeightRatio * localRatioCoefficient;
|
||||||
|
localHeightRatio = commonHeightRatio;
|
||||||
|
|
||||||
|
let localRatio = {
|
||||||
|
widthRatio: localWidthRatio,
|
||||||
|
heightRatio: localHeightRatio
|
||||||
|
};
|
||||||
|
|
||||||
|
let remoteRatio = {
|
||||||
|
widthRatio: remoteWidthRatio,
|
||||||
|
heightRatio: remoteHeightRatio
|
||||||
|
};
|
||||||
|
|
||||||
|
return { localRatio, remoteRatio };
|
||||||
|
},
|
||||||
|
|
||||||
|
calculateAvailableSize() {
|
||||||
|
let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
|
||||||
|
let thumbs = this.getThumbs(true);
|
||||||
|
let numvids = thumbs.remoteThumbs.length;
|
||||||
|
|
||||||
let localVideoContainer = $("#localVideoContainer");
|
let localVideoContainer = $("#localVideoContainer");
|
||||||
|
|
||||||
|
@ -92,11 +129,10 @@ const FilmStrip = {
|
||||||
|
|
||||||
let availableWidth = videoAreaAvailableWidth;
|
let availableWidth = videoAreaAvailableWidth;
|
||||||
|
|
||||||
// If the number of videos is 0 or undefined we don't need to calculate
|
// If local thumb is not hidden
|
||||||
// further.
|
if(thumbs.localThumb) {
|
||||||
if (numvids)
|
|
||||||
availableWidth = Math.floor(
|
availableWidth = Math.floor(
|
||||||
(videoAreaAvailableWidth - numvids * (
|
(videoAreaAvailableWidth - (
|
||||||
UIUtil.parseCssInt(
|
UIUtil.parseCssInt(
|
||||||
localVideoContainer.css('borderLeftWidth'), 10)
|
localVideoContainer.css('borderLeftWidth'), 10)
|
||||||
+ UIUtil.parseCssInt(
|
+ UIUtil.parseCssInt(
|
||||||
|
@ -109,36 +145,90 @@ const FilmStrip = {
|
||||||
localVideoContainer.css('marginLeft'), 10)
|
localVideoContainer.css('marginLeft'), 10)
|
||||||
+ UIUtil.parseCssInt(
|
+ UIUtil.parseCssInt(
|
||||||
localVideoContainer.css('marginRight'), 10)))
|
localVideoContainer.css('marginRight'), 10)))
|
||||||
/ numvids);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the number of videos is 0 or undefined we don't need to calculate
|
||||||
|
// further.
|
||||||
|
if (numvids) {
|
||||||
|
let remoteVideoContainer = thumbs.remoteThumbs.eq(0);
|
||||||
|
availableWidth = Math.floor(
|
||||||
|
(videoAreaAvailableWidth - numvids * (
|
||||||
|
UIUtil.parseCssInt(
|
||||||
|
remoteVideoContainer.css('borderLeftWidth'), 10)
|
||||||
|
+ UIUtil.parseCssInt(
|
||||||
|
remoteVideoContainer.css('borderRightWidth'), 10)
|
||||||
|
+ UIUtil.parseCssInt(
|
||||||
|
remoteVideoContainer.css('paddingLeft'), 10)
|
||||||
|
+ UIUtil.parseCssInt(
|
||||||
|
remoteVideoContainer.css('paddingRight'), 10)
|
||||||
|
+ UIUtil.parseCssInt(
|
||||||
|
remoteVideoContainer.css('marginLeft'), 10)
|
||||||
|
+ UIUtil.parseCssInt(
|
||||||
|
remoteVideoContainer.css('marginRight'), 10)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let maxHeight
|
let maxHeight
|
||||||
// If the MAX_HEIGHT property hasn't been specified
|
// If the MAX_HEIGHT property hasn't been specified
|
||||||
// we have the static value.
|
// we have the static value.
|
||||||
= Math.min( interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120,
|
= Math.min(interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120,
|
||||||
availableHeight);
|
availableHeight);
|
||||||
|
|
||||||
availableHeight
|
availableHeight
|
||||||
= Math.min( maxHeight, window.innerHeight - 18);
|
= Math.min(maxHeight, window.innerHeight - 18);
|
||||||
|
|
||||||
if (availableHeight < availableWidth) {
|
return { availableWidth, availableHeight };
|
||||||
availableWidth = availableHeight;
|
},
|
||||||
|
|
||||||
|
calculateThumbnailSizeFromAvailable(availableWidth, availableHeight) {
|
||||||
|
let { localRatio, remoteRatio } = this.normalizeThumbnailRatio();
|
||||||
|
let { remoteThumbs } = this.getThumbs(true);
|
||||||
|
let remoteProportion = remoteRatio.widthRatio * remoteThumbs.length;
|
||||||
|
let widthProportion = remoteProportion + localRatio.widthRatio;
|
||||||
|
|
||||||
|
let heightUnit = availableHeight / localRatio.heightRatio;
|
||||||
|
let widthUnit = availableWidth / widthProportion;
|
||||||
|
|
||||||
|
if (heightUnit < widthUnit) {
|
||||||
|
widthUnit = heightUnit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
availableHeight = availableWidth;
|
heightUnit = widthUnit;
|
||||||
|
|
||||||
|
let localVideo = {
|
||||||
|
thumbWidth: widthUnit * localRatio.widthRatio,
|
||||||
|
thumbHeight: heightUnit * localRatio.heightRatio
|
||||||
|
};
|
||||||
|
let remoteVideo = {
|
||||||
|
thumbWidth: widthUnit * remoteRatio.widthRatio,
|
||||||
|
thumbHeight: widthUnit * remoteRatio.heightRatio
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
thumbWidth: availableWidth,
|
localVideo,
|
||||||
thumbHeight: availableHeight
|
remoteVideo
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
resizeThumbnails (thumbWidth, thumbHeight,
|
resizeThumbnails (local, remote,
|
||||||
animate = false, forceUpdate = false) {
|
animate = false, forceUpdate = false) {
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
this.getThumbs(!forceUpdate).animate({
|
let thumbs = this.getThumbs(!forceUpdate);
|
||||||
height: thumbHeight,
|
|
||||||
width: thumbWidth
|
thumbs.localThumb.animate({
|
||||||
|
height: local.thumbHeight,
|
||||||
|
width: local.thumbWidth
|
||||||
|
}, {
|
||||||
|
queue: false,
|
||||||
|
duration: animate ? 500 : 0,
|
||||||
|
complete: resolve
|
||||||
|
});
|
||||||
|
|
||||||
|
thumbs.remoteThumbs.animate({
|
||||||
|
height: remote.thumbHeight,
|
||||||
|
width: remote.thumbWidth
|
||||||
}, {
|
}, {
|
||||||
queue: false,
|
queue: false,
|
||||||
duration: animate ? 500 : 0,
|
duration: animate ? 500 : 0,
|
||||||
|
@ -147,7 +237,7 @@ const FilmStrip = {
|
||||||
|
|
||||||
this.filmStrip.animate({
|
this.filmStrip.animate({
|
||||||
// adds 2 px because of small video 1px border
|
// adds 2 px because of small video 1px border
|
||||||
height: thumbHeight + 2
|
height: remote.thumbHeight + 2
|
||||||
}, {
|
}, {
|
||||||
queue: false,
|
queue: false,
|
||||||
duration: animate ? 500 : 0
|
duration: animate ? 500 : 0
|
||||||
|
@ -165,13 +255,19 @@ const FilmStrip = {
|
||||||
selector += ':visible';
|
selector += ':visible';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let localThumb = $("#localVideoContainer");
|
||||||
|
let remoteThumbs = this.filmStrip.children(selector)
|
||||||
|
.not("#localVideoContainer");
|
||||||
|
|
||||||
// Exclude the local video container if it has been hidden.
|
// Exclude the local video container if it has been hidden.
|
||||||
if ($("#localVideoContainer").hasClass("hidden"))
|
if (localThumb.hasClass("hidden")) {
|
||||||
return this.filmStrip.children(selector)
|
return { remoteThumbs };
|
||||||
.not("#localVideoContainer");
|
} else {
|
||||||
else
|
return { remoteThumbs, localThumb };
|
||||||
return this.filmStrip.children(selector);
|
}
|
||||||
}
|
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FilmStrip;
|
export default FilmStrip;
|
||||||
|
|
|
@ -11,7 +11,6 @@ function LocalVideo(VideoLayout, emitter) {
|
||||||
this.videoSpanId = "localVideoContainer";
|
this.videoSpanId = "localVideoContainer";
|
||||||
this.container = $("#localVideoContainer").get(0);
|
this.container = $("#localVideoContainer").get(0);
|
||||||
this.localVideoId = null;
|
this.localVideoId = null;
|
||||||
this.bindHoverHandler();
|
|
||||||
if(config.enableLocalVideoFlip)
|
if(config.enableLocalVideoFlip)
|
||||||
this._buildContextMenu();
|
this._buildContextMenu();
|
||||||
this.isLocal = true;
|
this.isLocal = true;
|
||||||
|
@ -44,7 +43,7 @@ function createEditDisplayNameButton() {
|
||||||
editButton.className = 'displayname';
|
editButton.className = 'displayname';
|
||||||
UIUtil.setTooltip(editButton,
|
UIUtil.setTooltip(editButton,
|
||||||
"videothumbnail.editnickname",
|
"videothumbnail.editnickname",
|
||||||
"top");
|
"left");
|
||||||
editButton.innerHTML = '<i class="icon-edit"></i>';
|
editButton.innerHTML = '<i class="icon-edit"></i>';
|
||||||
|
|
||||||
return editButton;
|
return editButton;
|
||||||
|
@ -72,7 +71,7 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
|
||||||
if (displayName && displayName.length > 0) {
|
if (displayName && displayName.length > 0) {
|
||||||
meHTML = APP.translation.generateTranslationHTML("me");
|
meHTML = APP.translation.generateTranslationHTML("me");
|
||||||
$('#localDisplayName').html(
|
$('#localDisplayName').html(
|
||||||
UIUtil.escapeHtml(displayName) + ' (' + meHTML + ')'
|
`${UIUtil.escapeHtml(displayName)} (${meHTML})`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$('#localDisplayName').html(defaultLocalDisplayName);
|
$('#localDisplayName').html(defaultLocalDisplayName);
|
||||||
|
@ -80,11 +79,9 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
|
||||||
}
|
}
|
||||||
this.updateView();
|
this.updateView();
|
||||||
} else {
|
} else {
|
||||||
var editButton = createEditDisplayNameButton();
|
|
||||||
|
|
||||||
nameSpan = document.createElement('span');
|
nameSpan = document.createElement('span');
|
||||||
nameSpan.className = 'displayname';
|
nameSpan.className = 'displayname';
|
||||||
$('#' + this.videoSpanId)[0].appendChild(nameSpan);
|
document.getElementById(this.videoSpanId).appendChild(nameSpan);
|
||||||
|
|
||||||
|
|
||||||
if (displayName && displayName.length > 0) {
|
if (displayName && displayName.length > 0) {
|
||||||
|
@ -97,7 +94,6 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
|
||||||
|
|
||||||
|
|
||||||
nameSpan.id = 'localDisplayName';
|
nameSpan.id = 'localDisplayName';
|
||||||
this.container.appendChild(editButton);
|
|
||||||
//translates popover of edit button
|
//translates popover of edit button
|
||||||
APP.translation.translateElement($("a.displayname"));
|
APP.translation.translateElement($("a.displayname"));
|
||||||
|
|
||||||
|
@ -124,21 +120,23 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
|
||||||
var self = this;
|
var self = this;
|
||||||
$('#localVideoContainer .displayname')
|
$('#localVideoContainer .displayname')
|
||||||
.bind("click", function (e) {
|
.bind("click", function (e) {
|
||||||
|
let $editDisplayName = $('#editDisplayName');
|
||||||
|
let $localDisplayName = $('#localDisplayName');
|
||||||
|
|
||||||
var editDisplayName = $('#editDisplayName');
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
$('#localDisplayName').hide();
|
$localDisplayName.hide();
|
||||||
editDisplayName.show();
|
$editDisplayName.show();
|
||||||
editDisplayName.focus();
|
$editDisplayName.focus();
|
||||||
editDisplayName.select();
|
$editDisplayName.select();
|
||||||
|
|
||||||
editDisplayName.one("focusout", function (e) {
|
$editDisplayName.one("focusout", function (e) {
|
||||||
self.emitter.emit(UIEvents.NICKNAME_CHANGED, this.value);
|
self.emitter.emit(UIEvents.NICKNAME_CHANGED, this.value);
|
||||||
$('#editDisplayName').hide();
|
$editDisplayName.hide();
|
||||||
|
$localDisplayName.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
editDisplayName.on('keydown', function (e) {
|
$editDisplayName.on('keydown', function (e) {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$('#editDisplayName').hide();
|
$('#editDisplayName').hide();
|
||||||
|
|
|
@ -17,7 +17,6 @@ function RemoteVideo(id, VideoLayout, emitter) {
|
||||||
this.addRemoteVideoContainer();
|
this.addRemoteVideoContainer();
|
||||||
this.connectionIndicator = new ConnectionIndicator(this, id);
|
this.connectionIndicator = new ConnectionIndicator(this, id);
|
||||||
this.setDisplayName();
|
this.setDisplayName();
|
||||||
this.bindHoverHandler();
|
|
||||||
this.flipX = false;
|
this.flipX = false;
|
||||||
this.isLocal = false;
|
this.isLocal = false;
|
||||||
this.isMuted = false;
|
this.isMuted = false;
|
||||||
|
@ -34,8 +33,10 @@ RemoteVideo.prototype.addRemoteVideoContainer = function() {
|
||||||
if (APP.conference.isModerator) {
|
if (APP.conference.isModerator) {
|
||||||
this.addRemoteVideoMenu();
|
this.addRemoteVideoMenu();
|
||||||
}
|
}
|
||||||
let {thumbWidth, thumbHeight} = this.VideoLayout.resizeThumbnails();
|
|
||||||
AudioLevels.updateAudioLevelCanvas(this.id, thumbWidth, thumbHeight);
|
let { remoteVideo } = this.VideoLayout.resizeThumbnails();
|
||||||
|
let { thumbHeight, thumbWidth } = remoteVideo;
|
||||||
|
AudioLevels.createAudioLevelCanvas(this.id, thumbWidth, thumbHeight);
|
||||||
|
|
||||||
return this.container;
|
return this.container;
|
||||||
};
|
};
|
||||||
|
@ -427,12 +428,16 @@ RemoteVideo.prototype.removeRemoteVideoMenu = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
RemoteVideo.createContainer = function (spanId) {
|
RemoteVideo.createContainer = function (spanId) {
|
||||||
var container = document.createElement('span');
|
let container = document.createElement('span');
|
||||||
container.id = spanId;
|
container.id = spanId;
|
||||||
container.className = 'videocontainer';
|
container.className = 'videocontainer';
|
||||||
|
|
||||||
|
let toolbar = document.createElement('div');
|
||||||
|
toolbar.className = "videocontainer__toolbar";
|
||||||
|
container.appendChild(toolbar);
|
||||||
|
|
||||||
var remotes = document.getElementById('remoteVideos');
|
var remotes = document.getElementById('remoteVideos');
|
||||||
return remotes.appendChild(container);
|
return remotes.appendChild(container);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default RemoteVideo;
|
export default RemoteVideo;
|
||||||
|
|
|
@ -171,26 +171,6 @@ SmallVideo.getStreamElementID = function (stream) {
|
||||||
return (isVideo ? 'remoteVideo_' : 'remoteAudio_') + stream.getId();
|
return (isVideo ? 'remoteVideo_' : 'remoteAudio_') + stream.getId();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures hoverIn/hoverOut handlers.
|
|
||||||
*/
|
|
||||||
SmallVideo.prototype.bindHoverHandler = function () {
|
|
||||||
// Add hover handler
|
|
||||||
var self = this;
|
|
||||||
$(this.container).hover(
|
|
||||||
function () {
|
|
||||||
self.showDisplayName(true);
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
// If the video has been "pinned" by the user we want to
|
|
||||||
// keep the display name on place.
|
|
||||||
if (!self.VideoLayout.isLargeVideoVisible() ||
|
|
||||||
!self.VideoLayout.isCurrentlyOnLarge(self.id))
|
|
||||||
self.showDisplayName(false);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the data for the indicator
|
* Updates the data for the indicator
|
||||||
* @param id the id of the indicator
|
* @param id the id of the indicator
|
||||||
|
@ -219,6 +199,7 @@ SmallVideo.prototype.showAudioIndicator = function(isMuted) {
|
||||||
if (audioMutedSpan.length > 0) {
|
if (audioMutedSpan.length > 0) {
|
||||||
audioMutedSpan.popover('hide');
|
audioMutedSpan.popover('hide');
|
||||||
audioMutedSpan.remove();
|
audioMutedSpan.remove();
|
||||||
|
this.updateIconPositions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -230,12 +211,14 @@ SmallVideo.prototype.showAudioIndicator = function(isMuted) {
|
||||||
"top");
|
"top");
|
||||||
|
|
||||||
this.container.appendChild(audioMutedSpan);
|
this.container.appendChild(audioMutedSpan);
|
||||||
APP.translation.translateElement($('#' + this.videoSpanId + " > span"));
|
APP.translation
|
||||||
|
.translateElement($('#' + this.videoSpanId + " > span"));
|
||||||
var mutedIndicator = document.createElement('i');
|
var mutedIndicator = document.createElement('i');
|
||||||
mutedIndicator.className = 'icon-mic-disabled';
|
mutedIndicator.className = 'icon-mic-disabled';
|
||||||
audioMutedSpan.appendChild(mutedIndicator);
|
audioMutedSpan.appendChild(mutedIndicator);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateIconPositions();
|
this.updateIconPositions();
|
||||||
}
|
}
|
||||||
this.isMuted = isMuted;
|
this.isMuted = isMuted;
|
||||||
|
@ -254,6 +237,7 @@ SmallVideo.prototype.setMutedView = function(isMuted) {
|
||||||
if (isMuted === false) {
|
if (isMuted === false) {
|
||||||
if (videoMutedSpan.length > 0) {
|
if (videoMutedSpan.length > 0) {
|
||||||
videoMutedSpan.remove();
|
videoMutedSpan.remove();
|
||||||
|
this.updateIconPositions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -270,7 +254,8 @@ SmallVideo.prototype.setMutedView = function(isMuted) {
|
||||||
"top");
|
"top");
|
||||||
videoMutedSpan.appendChild(mutedIndicator);
|
videoMutedSpan.appendChild(mutedIndicator);
|
||||||
//translate texts for muted indicator
|
//translate texts for muted indicator
|
||||||
APP.translation.translateElement($('#' + this.videoSpanId + " > span > i"));
|
APP.translation
|
||||||
|
.translateElement($('#' + this.videoSpanId + " > span > i"));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateIconPositions();
|
this.updateIconPositions();
|
||||||
|
@ -278,13 +263,18 @@ SmallVideo.prototype.setMutedView = function(isMuted) {
|
||||||
};
|
};
|
||||||
|
|
||||||
SmallVideo.prototype.updateIconPositions = function () {
|
SmallVideo.prototype.updateIconPositions = function () {
|
||||||
var audioMutedSpan = $('#' + this.videoSpanId + '>span.audioMuted');
|
let audioMutedSpan = $('#' + this.videoSpanId + '>span.audioMuted');
|
||||||
var connectionIndicator = $('#' + this.videoSpanId + '>div.connectionindicator');
|
let videoMutedSpan = $('#' + this.videoSpanId + '>span.videoMuted');
|
||||||
var videoMutedSpan = $('#' + this.videoSpanId + '>span.videoMuted');
|
audioMutedSpan.css({left: "0px"});
|
||||||
|
videoMutedSpan.css({left: (audioMutedSpan.length > 0? 25 : 0) + "px"});
|
||||||
|
|
||||||
|
var connectionIndicator
|
||||||
|
= $('#' + this.videoSpanId + '>div.connectionindicator');
|
||||||
if(connectionIndicator.length > 0 &&
|
if(connectionIndicator.length > 0 &&
|
||||||
connectionIndicator[0].style.display != "none") {
|
connectionIndicator[0].style.display != "none") {
|
||||||
audioMutedSpan.css({right: "23px"});
|
audioMutedSpan.css({right: "23px"});
|
||||||
videoMutedSpan.css({right: ((audioMutedSpan.length > 0? 23 : 0) + 30) + "px"});
|
videoMutedSpan.css({right:
|
||||||
|
((audioMutedSpan.length > 0? 23 : 0) + 30) + "px"});
|
||||||
} else {
|
} else {
|
||||||
audioMutedSpan.css({right: "0px"});
|
audioMutedSpan.css({right: "0px"});
|
||||||
videoMutedSpan.css({right: (audioMutedSpan.length > 0? 30 : 0) + "px"});
|
videoMutedSpan.css({right: (audioMutedSpan.length > 0? 30 : 0) + "px"});
|
||||||
|
@ -317,7 +307,8 @@ SmallVideo.prototype.createModeratorIndicatorElement = function () {
|
||||||
"top");
|
"top");
|
||||||
|
|
||||||
//translates text in focus indicators
|
//translates text in focus indicators
|
||||||
APP.translation.translateElement($('#' + this.videoSpanId + ' .focusindicator'));
|
APP.translation
|
||||||
|
.translateElement($('#' + this.videoSpanId + ' .focusindicator'));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -406,8 +397,6 @@ SmallVideo.prototype.updateView = function () {
|
||||||
setVisibility(video, showVideo);
|
setVisibility(video, showVideo);
|
||||||
}
|
}
|
||||||
setVisibility(avatar, showAvatar);
|
setVisibility(avatar, showAvatar);
|
||||||
|
|
||||||
this.showDisplayName(!showVideo && !showAvatar);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SmallVideo.prototype.avatarChanged = function (avatarUrl) {
|
SmallVideo.prototype.avatarChanged = function (avatarUrl) {
|
||||||
|
@ -465,9 +454,8 @@ SmallVideo.prototype.showRaisedHandIndicator = function (show) {
|
||||||
var indicatorSpanId = "raisehandindicator";
|
var indicatorSpanId = "raisehandindicator";
|
||||||
var indicatorSpan = this.getIndicatorSpan(indicatorSpanId);
|
var indicatorSpan = this.getIndicatorSpan(indicatorSpanId);
|
||||||
|
|
||||||
indicatorSpan.style.background = "#D6D61E";
|
|
||||||
indicatorSpan.innerHTML
|
indicatorSpan.innerHTML
|
||||||
= "<i id='indicatoricon' class='fa fa-hand-paper-o'></i>";
|
= "<i id='indicatoricon' class='icon-raised-hand'></i>";
|
||||||
|
|
||||||
// adds a tooltip
|
// adds a tooltip
|
||||||
UIUtil.setTooltip(indicatorSpan, "raisedHand", "left");
|
UIUtil.setTooltip(indicatorSpan, "raisedHand", "left");
|
||||||
|
|
|
@ -105,8 +105,9 @@ var VideoLayout = {
|
||||||
localVideoThumbnail.setVideoType(VIDEO_CONTAINER_TYPE);
|
localVideoThumbnail.setVideoType(VIDEO_CONTAINER_TYPE);
|
||||||
// if we do not resize the thumbs here, if there is no video device
|
// if we do not resize the thumbs here, if there is no video device
|
||||||
// the local video thumb maybe one pixel
|
// the local video thumb maybe one pixel
|
||||||
let {thumbWidth, thumbHeight} = this.resizeThumbnails(false, true);
|
let { localVideo } = this.resizeThumbnails(false, true);
|
||||||
AudioLevels.updateAudioLevelCanvas(null, thumbWidth, thumbHeight);
|
AudioLevels.createAudioLevelCanvas(
|
||||||
|
"local", localVideo.thumbWidth, localVideo.thumbHeight);
|
||||||
|
|
||||||
emitter.addListener(UIEvents.CONTACT_CLICKED, onContactClicked);
|
emitter.addListener(UIEvents.CONTACT_CLICKED, onContactClicked);
|
||||||
this.lastNCount = config.channelLastN;
|
this.lastNCount = config.channelLastN;
|
||||||
|
@ -254,7 +255,8 @@ var VideoLayout = {
|
||||||
electLastVisibleVideo () {
|
electLastVisibleVideo () {
|
||||||
// pick the last visible video in the row
|
// pick the last visible video in the row
|
||||||
// if nobody else is left, this picks the local video
|
// if nobody else is left, this picks the local video
|
||||||
let thumbs = FilmStrip.getThumbs(true).filter('[id!="mixedstream"]');
|
let remoteThumbs = FilmStrip.getThumbs(true).remoteThumbs;
|
||||||
|
let thumbs = remoteThumbs.filter('[id!="mixedstream"]');
|
||||||
|
|
||||||
let lastVisible = thumbs.filter(':visible:last');
|
let lastVisible = thumbs.filter(':visible:last');
|
||||||
if (lastVisible.length) {
|
if (lastVisible.length) {
|
||||||
|
@ -268,7 +270,7 @@ var VideoLayout = {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info("Last visible video no longer exists");
|
console.info("Last visible video no longer exists");
|
||||||
thumbs = FilmStrip.getThumbs();
|
thumbs = FilmStrip.getThumbs().remoteThumbs;
|
||||||
if (thumbs.length) {
|
if (thumbs.length) {
|
||||||
let id = getPeerContainerResourceId(thumbs[0]);
|
let id = getPeerContainerResourceId(thumbs[0]);
|
||||||
if (remoteVideos[id]) {
|
if (remoteVideos[id]) {
|
||||||
|
@ -401,7 +403,7 @@ var VideoLayout = {
|
||||||
|
|
||||||
// In case this is not currently in the last n we don't show it.
|
// In case this is not currently in the last n we don't show it.
|
||||||
if (localLastNCount && localLastNCount > 0 &&
|
if (localLastNCount && localLastNCount > 0 &&
|
||||||
FilmStrip.getThumbs().length >= localLastNCount + 2) {
|
FilmStrip.getThumbs().remoteThumbs.length >= localLastNCount + 2) {
|
||||||
remoteVideo.showPeerContainer('hide');
|
remoteVideo.showPeerContainer('hide');
|
||||||
} else {
|
} else {
|
||||||
VideoLayout.resizeThumbnails(false, true);
|
VideoLayout.resizeThumbnails(false, true);
|
||||||
|
@ -486,19 +488,19 @@ var VideoLayout = {
|
||||||
forceUpdate = false,
|
forceUpdate = false,
|
||||||
onComplete = null) {
|
onComplete = null) {
|
||||||
|
|
||||||
let {thumbWidth, thumbHeight}
|
let { localVideo, remoteVideo }
|
||||||
= FilmStrip.calculateThumbnailSize();
|
= FilmStrip.calculateThumbnailSize();
|
||||||
|
|
||||||
$('.userAvatar').css('left', (thumbWidth - thumbHeight) / 2);
|
let {thumbWidth, thumbHeight} = remoteVideo;
|
||||||
|
|
||||||
FilmStrip.resizeThumbnails(thumbWidth, thumbHeight,
|
FilmStrip.resizeThumbnails(localVideo, remoteVideo,
|
||||||
animate, forceUpdate)
|
animate, forceUpdate)
|
||||||
.then(function () {
|
.then(function () {
|
||||||
AudioLevels.updateCanvasSize(thumbWidth, thumbHeight);
|
AudioLevels.updateCanvasSize(localVideo, remoteVideo);
|
||||||
if (onComplete && typeof onComplete === "function")
|
if (onComplete && typeof onComplete === "function")
|
||||||
onComplete();
|
onComplete();
|
||||||
});
|
});
|
||||||
return {thumbWidth, thumbHeight};
|
return { localVideo, remoteVideo };
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -656,7 +658,7 @@ var VideoLayout = {
|
||||||
var updateLargeVideo = false;
|
var updateLargeVideo = false;
|
||||||
|
|
||||||
// Handle LastN/local LastN changes.
|
// Handle LastN/local LastN changes.
|
||||||
FilmStrip.getThumbs().each(( index, element ) => {
|
FilmStrip.getThumbs().remoteThumbs.each(( index, element ) => {
|
||||||
var resourceJid = getPeerContainerResourceId(element);
|
var resourceJid = getPeerContainerResourceId(element);
|
||||||
var smallVideo = remoteVideos[resourceJid];
|
var smallVideo = remoteVideos[resourceJid];
|
||||||
|
|
||||||
|
|
10
package.json
10
package.json
|
@ -21,18 +21,18 @@
|
||||||
"bootstrap": "3.1.1",
|
"bootstrap": "3.1.1",
|
||||||
"events": "*",
|
"events": "*",
|
||||||
"i18next-client": "1.7.7",
|
"i18next-client": "1.7.7",
|
||||||
"jquery": "~2.1.1",
|
|
||||||
"jQuery-Impromptu": "git+https://github.com/trentrichardson/jQuery-Impromptu.git#v6.0.0",
|
"jQuery-Impromptu": "git+https://github.com/trentrichardson/jQuery-Impromptu.git#v6.0.0",
|
||||||
"lib-jitsi-meet": "git+https://github.com/jitsi/lib-jitsi-meet.git",
|
"jquery": "~2.1.1",
|
||||||
"jquery-contextmenu": "*",
|
"jquery-contextmenu": "*",
|
||||||
"jquery-ui": "1.10.5",
|
"jquery-ui": "1.10.5",
|
||||||
"jssha": "1.5.0",
|
"jssha": "1.5.0",
|
||||||
|
"jws": "*",
|
||||||
|
"lib-jitsi-meet": "git+https://github.com/jitsi/lib-jitsi-meet.git",
|
||||||
|
"postis": "^2.2.0",
|
||||||
"retry": "0.6.1",
|
"retry": "0.6.1",
|
||||||
"strophe": "^1.2.2",
|
"strophe": "^1.2.2",
|
||||||
"strophejs-plugins": "^0.0.6",
|
"strophejs-plugins": "^0.0.6",
|
||||||
"toastr": "^2.0.3",
|
"toastr": "^2.0.3"
|
||||||
"postis": "^2.2.0",
|
|
||||||
"jws": "*"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-polyfill": "*",
|
"babel-polyfill": "*",
|
||||||
|
|
Loading…
Reference in New Issue