abstract out remoteVideos management
This commit is contained in:
parent
3400925f99
commit
b375b14696
|
@ -88,7 +88,7 @@ function setupChat() {
|
|||
function setupToolbars() {
|
||||
Toolbar.init(eventEmitter);
|
||||
Toolbar.setupButtonsFromConfig();
|
||||
BottomToolbar.init(eventEmitter);
|
||||
BottomToolbar.setupListeners(eventEmitter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,6 +246,8 @@ UI.start = function () {
|
|||
|
||||
registerListeners();
|
||||
|
||||
BottomToolbar.init();
|
||||
|
||||
VideoLayout.init(eventEmitter);
|
||||
if (!interfaceConfig.filmStripOnly) {
|
||||
VideoLayout.initLargeVideo(PanelToggler.isVisible());
|
||||
|
@ -277,8 +279,7 @@ UI.start = function () {
|
|||
$("#header").css("display", "none");
|
||||
$("#bottomToolbar").css("display", "none");
|
||||
$("#downloadlog").css("display", "none");
|
||||
$("#remoteVideos").css("padding", "0px 0px 18px 0px");
|
||||
$("#remoteVideos").css("right", "0px");
|
||||
BottomToolbar.setupFilmStripOnly();
|
||||
messageHandler.disableNotifications();
|
||||
$('body').popover("disable");
|
||||
JitsiPopover.enabled = false;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* jshint -W101 */
|
||||
|
||||
import CanvasUtil from './CanvasUtils';
|
||||
import BottomToolbar from '../toolbars/BottomToolbar';
|
||||
|
||||
const LOCAL_LEVEL = 'local';
|
||||
|
||||
|
@ -126,7 +127,7 @@ const AudioLevels = {
|
|||
* Updates the audio level canvas for the given id. If the canvas
|
||||
* didn't exist we create it.
|
||||
*/
|
||||
updateAudioLevelCanvas (id, VideoLayout) {
|
||||
updateAudioLevelCanvas (id, thumbWidth, thumbHeight) {
|
||||
let videoSpanId = 'localVideoContainer';
|
||||
if (id) {
|
||||
videoSpanId = `participant_${id}`;
|
||||
|
@ -145,24 +146,19 @@ const AudioLevels = {
|
|||
|
||||
let audioLevelCanvas = $(`#${videoSpanId}>canvas`);
|
||||
|
||||
let videoSpaceWidth = $('#remoteVideos').width();
|
||||
let thumbnailSize = VideoLayout.calculateThumbnailSize(videoSpaceWidth);
|
||||
let thumbnailWidth = thumbnailSize[0];
|
||||
let thumbnailHeight = thumbnailSize[1];
|
||||
|
||||
if (!audioLevelCanvas || audioLevelCanvas.length === 0) {
|
||||
|
||||
audioLevelCanvas = document.createElement('canvas');
|
||||
audioLevelCanvas.className = "audiolevel";
|
||||
audioLevelCanvas.style.bottom = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||
audioLevelCanvas.style.left = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbnailWidth, thumbnailHeight);
|
||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||
|
||||
videoSpan.appendChild(audioLevelCanvas);
|
||||
} else {
|
||||
audioLevelCanvas = audioLevelCanvas.get(0);
|
||||
|
||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbnailWidth, thumbnailHeight);
|
||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -223,31 +219,16 @@ const AudioLevels = {
|
|||
ASDrawContext.fill();
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates that the remote video has been resized.
|
||||
*/
|
||||
onRemoteVideoResized (width, height) {
|
||||
let resized = false;
|
||||
updateCanvasSize (thumbWidth, thumbHeight) {
|
||||
let canvasWidth = thumbWidth + interfaceConfig.CANVAS_EXTRA;
|
||||
let canvasHeight = thumbHeight + interfaceConfig.CANVAS_EXTRA;
|
||||
|
||||
$('#remoteVideos>span>canvas').each(function() {
|
||||
let canvas = $(this).get(0);
|
||||
if (canvas.width !== width + interfaceConfig.CANVAS_EXTRA) {
|
||||
canvas.width = width + interfaceConfig.CANVAS_EXTRA;
|
||||
resized = true;
|
||||
}
|
||||
BottomToolbar.getThumbs().children('canvas').width(canvasWidth).height(canvasHeight);
|
||||
|
||||
if (canvas.height !== height + interfaceConfig.CANVAS_EXTRA) {
|
||||
canvas.height = height + interfaceConfig.CANVAS_EXTRA;
|
||||
resized = true;
|
||||
}
|
||||
Object.keys(audioLevelCanvasCache).forEach(function (id) {
|
||||
audioLevelCanvasCache[id].width = canvasWidth;
|
||||
audioLevelCanvasCache[id].height = canvasHeight;
|
||||
});
|
||||
|
||||
if (resized) {
|
||||
Object.keys(audioLevelCanvasCache).forEach(function (id) {
|
||||
audioLevelCanvasCache[id].width = width + interfaceConfig.CANVAS_EXTRA;
|
||||
audioLevelCanvasCache[id].height = height + interfaceConfig.CANVAS_EXTRA;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import VideoLayout from "../videolayout/VideoLayout";
|
|||
import LargeContainer from '../videolayout/LargeContainer';
|
||||
import UIUtil from "../util/UIUtil";
|
||||
import SidePanelToggler from "../side_pannels/SidePanelToggler";
|
||||
import BottomToolbar from '../toolbars/BottomToolbar';
|
||||
|
||||
const options = $.param({
|
||||
showControns: true,
|
||||
|
@ -88,9 +89,7 @@ class Etherpad extends LargeContainer {
|
|||
}
|
||||
|
||||
resize (containerWidth, containerHeight, animate) {
|
||||
let remoteVideos = $('#remoteVideos');
|
||||
|
||||
let height = containerHeight - remoteVideos.outerHeight();
|
||||
let height = containerHeight - BottomToolbar.getFilmStripHeight();
|
||||
let width = containerWidth;
|
||||
|
||||
$(this.iframe).width(width).height(height);
|
||||
|
|
|
@ -9,6 +9,7 @@ import UIEvents from '../../../service/UI/UIEvents';
|
|||
import messageHandler from '../util/MessageHandler';
|
||||
import ToolbarToggler from "../toolbars/ToolbarToggler";
|
||||
import SidePanelToggler from "../side_pannels/SidePanelToggler";
|
||||
import BottomToolbar from '../toolbars/BottomToolbar';
|
||||
|
||||
const defaultPreziLink = "http://prezi.com/wz7vhjycl7e6/my-prezi";
|
||||
const alphanumRegex = /^[a-z0-9-_\/&\?=;]+$/i;
|
||||
|
@ -244,8 +245,7 @@ class PreziContainer extends LargeContainer {
|
|||
}
|
||||
|
||||
resize (containerWidth, containerHeight) {
|
||||
let remoteVideos = $('#remoteVideos');
|
||||
let height = containerHeight - remoteVideos.outerHeight();
|
||||
let height = containerHeight - BottomToolbar.getFilmStripHeight();
|
||||
|
||||
let width = containerWidth;
|
||||
|
||||
|
|
|
@ -10,7 +10,12 @@ const defaultBottomToolbarButtons = {
|
|||
};
|
||||
|
||||
const BottomToolbar = {
|
||||
init (emitter) {
|
||||
init () {
|
||||
this.filmStrip = $('#remoteVideos');
|
||||
this.toolbar = $('#bottomToolbar');
|
||||
},
|
||||
|
||||
setupListeners (emitter) {
|
||||
UIUtil.hideDisabledButtons(defaultBottomToolbarButtons);
|
||||
|
||||
const buttonHandlers = {
|
||||
|
@ -34,14 +39,69 @@ const BottomToolbar = {
|
|||
},
|
||||
|
||||
toggleFilmStrip () {
|
||||
$("#remoteVideos").toggleClass("hidden");
|
||||
this.filmStrip.toggleClass("hidden");
|
||||
},
|
||||
|
||||
onRemoteVideoResized (width, height) {
|
||||
let toolbar = $('#bottomToolbar');
|
||||
let bottom = (height - toolbar.outerHeight())/2 + 18;
|
||||
isFilmStripVisible () {
|
||||
return !this.filmStrip.hasClass('hidden');
|
||||
},
|
||||
|
||||
toolbar.css({bottom});
|
||||
setupFilmStripOnly () {
|
||||
this.filmStrip.css({
|
||||
padding: "0px 0px 18px 0px",
|
||||
right: 0
|
||||
});
|
||||
},
|
||||
|
||||
getFilmStripHeight () {
|
||||
if (this.isFilmStripVisible()) {
|
||||
return this.filmStrip.outerHeight();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
|
||||
getFilmStripWidth () {
|
||||
return this.filmStrip.width();
|
||||
},
|
||||
|
||||
resizeThumbnails (thumbWidth, thumbHeight, animate = false) {
|
||||
return new Promise(resolve => {
|
||||
this.filmStrip.animate({
|
||||
// adds 2 px because of small video 1px border
|
||||
height: thumbHeight + 2
|
||||
}, {
|
||||
queue: false,
|
||||
duration: animate ? 500 : 0
|
||||
});
|
||||
|
||||
this.getThumbs().animate({
|
||||
height: thumbHeight,
|
||||
width: thumbWidth
|
||||
}, {
|
||||
queue: false,
|
||||
duration: animate ? 500 : 0,
|
||||
complete: resolve
|
||||
});
|
||||
|
||||
if (!animate) {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
resizeToolbar (thumbWidth, thumbHeight) {
|
||||
let bottom = (thumbHeight - this.toolbar.outerHeight())/2 + 18;
|
||||
this.toolbar.css({bottom});
|
||||
},
|
||||
|
||||
getThumbs (visible = false) {
|
||||
let selector = 'span';
|
||||
if (visible) {
|
||||
selector += ':visible';
|
||||
}
|
||||
|
||||
return this.filmStrip.children(selector);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* global APP, config, $, interfaceConfig */
|
||||
|
||||
import UIUtil from '../util/UIUtil';
|
||||
import BottomToolbar from './BottomToolbar';
|
||||
|
||||
let toolbarTimeoutObject;
|
||||
let toolbarTimeout = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
|
||||
|
@ -47,7 +48,7 @@ function hideToolbar() {
|
|||
} else {
|
||||
header.hide("slide", { direction: "up", duration: 300});
|
||||
$('#subject').animate({top: "-=40"}, 300);
|
||||
if ($("#remoteVideos").hasClass("hidden")) {
|
||||
if (!BottomToolbar.isFilmStripVisible()) {
|
||||
bottomToolbar.hide(
|
||||
"slide", {direction: "right", duration: 300}
|
||||
);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import UIUtil from "../util/UIUtil";
|
||||
import UIEvents from "../../../service/UI/UIEvents";
|
||||
import LargeContainer from './LargeContainer';
|
||||
import BottomToolbar from '../toolbars/BottomToolbar';
|
||||
|
||||
const RTCBrowserType = require("../../RTC/RTCBrowserType");
|
||||
|
||||
|
@ -34,10 +35,7 @@ function getDesktopVideoSize(videoWidth,
|
|||
let availableWidth = Math.max(videoWidth, videoSpaceWidth);
|
||||
let availableHeight = Math.max(videoHeight, videoSpaceHeight);
|
||||
|
||||
let filmstrip = $("#remoteVideos");
|
||||
|
||||
if (!filmstrip.hasClass("hidden"))
|
||||
videoSpaceHeight -= filmstrip.outerHeight();
|
||||
videoSpaceHeight -= BottomToolbar.getFilmStripHeight();
|
||||
|
||||
if (availableWidth / aspectRatio >= videoSpaceHeight) {
|
||||
availableHeight = videoSpaceHeight;
|
||||
|
|
|
@ -34,7 +34,8 @@ RemoteVideo.prototype.addRemoteVideoContainer = function() {
|
|||
if (APP.conference.isModerator) {
|
||||
this.addRemoteVideoMenu();
|
||||
}
|
||||
AudioLevels.updateAudioLevelCanvas(this.id, this.VideoLayout);
|
||||
let {thumbWidth, thumbHeight} = this.VideoLayout.calculateThumbnailSize();
|
||||
AudioLevels.updateAudioLevelCanvas(this.id, thumbWidth, thumbHeight);
|
||||
|
||||
return this.container;
|
||||
};
|
||||
|
|
|
@ -34,6 +34,8 @@ var eventEmitter = null;
|
|||
*/
|
||||
var focusedVideoResourceJid = null;
|
||||
|
||||
const thumbAspectRatio = 16.0 / 9.0;
|
||||
|
||||
/**
|
||||
* On contact list item clicked.
|
||||
*/
|
||||
|
@ -153,7 +155,8 @@ var VideoLayout = {
|
|||
let localId = APP.conference.localId;
|
||||
this.onVideoTypeChanged(localId, stream.getType());
|
||||
|
||||
AudioLevels.updateAudioLevelCanvas(null, VideoLayout);
|
||||
let {thumbWidth, thumbHeight} = this.calculateThumbnailSize();
|
||||
AudioLevels.updateAudioLevelCanvas(null, thumbWidth, thumbHeight);
|
||||
|
||||
localVideoThumbnail.changeVideo(stream);
|
||||
|
||||
|
@ -215,9 +218,11 @@ var VideoLayout = {
|
|||
electLastVisibleVideo () {
|
||||
// pick the last visible video in the row
|
||||
// if nobody else is left, this picks the local video
|
||||
let pick = $('#remoteVideos>span[id!="mixedstream"]:visible:last');
|
||||
if (pick.length) {
|
||||
let id = getPeerContainerResourceId(pick[0]);
|
||||
let thumbs = BottomToolbar.getThumbs(true).filter('id!="mixedstream"');
|
||||
|
||||
let lastVisible = thumbs.filter(':visible:last');
|
||||
if (lastVisible.length) {
|
||||
let id = getPeerContainerResourceId(lastVisible[0]);
|
||||
if (remoteVideos[id]) {
|
||||
console.info("electLastVisibleVideo: " + id);
|
||||
return id;
|
||||
|
@ -227,9 +232,9 @@ var VideoLayout = {
|
|||
}
|
||||
|
||||
console.info("Last visible video no longer exists");
|
||||
pick = $('#remoteVideos>span[id!="mixedstream"]');
|
||||
if (pick.length) {
|
||||
let id = getPeerContainerResourceId(pick[0]);
|
||||
thumbs = BottomToolbar.getThumbs();
|
||||
if (thumbs.length) {
|
||||
let id = getPeerContainerResourceId(thumbs[0]);
|
||||
if (remoteVideos[id]) {
|
||||
console.info("electLastVisibleVideo: " + id);
|
||||
return id;
|
||||
|
@ -332,7 +337,7 @@ var VideoLayout = {
|
|||
|
||||
// In case this is not currently in the last n we don't show it.
|
||||
if (localLastNCount && localLastNCount > 0 &&
|
||||
$('#remoteVideos>span').length >= localLastNCount + 2) {
|
||||
BottomToolbar.getThumbs().length >= localLastNCount + 2) {
|
||||
remoteVideo.showPeerContainer('hide');
|
||||
} else {
|
||||
VideoLayout.resizeThumbnails();
|
||||
|
@ -419,67 +424,53 @@ var VideoLayout = {
|
|||
* Resizes thumbnails.
|
||||
*/
|
||||
resizeThumbnails (animate = false) {
|
||||
let videoSpaceWidth = $('#remoteVideos').width();
|
||||
let {thumbWidth, thumbHeight} = this.calculateThumbnailSize();
|
||||
|
||||
let [width, height] = this.calculateThumbnailSize(videoSpaceWidth);
|
||||
$('.userAvatar').css('left', (thumbWidth - thumbHeight) / 2);
|
||||
|
||||
$('.userAvatar').css('left', (width - height) / 2);
|
||||
|
||||
$('#remoteVideos').animate({
|
||||
// adds 2 px because of small video 1px border
|
||||
height: height + 2
|
||||
}, {
|
||||
queue: false,
|
||||
duration: animate ? 500 : 0
|
||||
});
|
||||
|
||||
$('#remoteVideos>span').animate({
|
||||
height, width
|
||||
}, {
|
||||
queue: false,
|
||||
duration: animate ? 500 : 0,
|
||||
complete: function () {
|
||||
BottomToolbar.onRemoteVideoResized(width, height);
|
||||
AudioLevels.onRemoteVideoResized(width, height);
|
||||
}
|
||||
BottomToolbar.resizeThumbnails(thumbWidth, thumbHeight, animate).then(function () {
|
||||
BottomToolbar.resizeToolbar(thumbWidth, thumbHeight);
|
||||
AudioLevels.updateCanvasSize(thumbWidth, thumbHeight);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the thumbnail size.
|
||||
*
|
||||
* @param videoSpaceWidth the width of the video space
|
||||
*/
|
||||
calculateThumbnailSize (videoSpaceWidth) {
|
||||
calculateThumbnailSize () {
|
||||
let videoSpaceWidth = BottomToolbar.getFilmStripWidth();
|
||||
// Calculate the available height, which is the inner window height
|
||||
// minus 39px for the header minus 2px for the delimiter lines on the
|
||||
// top and bottom of the large video, minus the 36px space inside the
|
||||
// remoteVideos container used for highlighting shadow.
|
||||
var availableHeight = 100;
|
||||
let availableHeight = 100;
|
||||
|
||||
var numvids = $('#remoteVideos>span:visible').length;
|
||||
let numvids = BottomToolbar.getThumbs().length;
|
||||
if (localLastNCount && localLastNCount > 0) {
|
||||
numvids = Math.min(localLastNCount + 1, numvids);
|
||||
}
|
||||
|
||||
// Remove the 3px borders arround videos and border around the remote
|
||||
// videos area and the 4 pixels between the local video and the others
|
||||
//TODO: Find out where the 4 pixels come from and remove them
|
||||
var availableWinWidth = videoSpaceWidth - 2 * 3 * numvids - 70 - 4;
|
||||
// Remove the 3px borders arround videos and border around the remote
|
||||
// videos area and the 4 pixels between the local video and the others
|
||||
//TODO: Find out where the 4 pixels come from and remove them
|
||||
let availableWinWidth = videoSpaceWidth - 2 * 3 * numvids - 70 - 4;
|
||||
|
||||
var availableWidth = availableWinWidth / numvids;
|
||||
var aspectRatio = 16.0 / 9.0;
|
||||
var maxHeight = Math.min(160, availableHeight);
|
||||
availableHeight
|
||||
= Math.min( maxHeight,
|
||||
availableWidth / aspectRatio,
|
||||
window.innerHeight - 18);
|
||||
let availableWidth = availableWinWidth / numvids;
|
||||
let maxHeight = Math.min(160, availableHeight);
|
||||
availableHeight
|
||||
= Math.min( maxHeight,
|
||||
availableWidth / thumbAspectRatio,
|
||||
window.innerHeight - 18);
|
||||
|
||||
if (availableHeight < availableWidth / aspectRatio) {
|
||||
availableWidth = Math.floor(availableHeight * aspectRatio);
|
||||
}
|
||||
if (availableHeight < availableWidth / thumbAspectRatio) {
|
||||
availableWidth = Math.floor(availableHeight * thumbAspectRatio);
|
||||
}
|
||||
|
||||
return [availableWidth, availableHeight];
|
||||
return {
|
||||
thumbWidth: availableWidth,
|
||||
thumbHeight: availableHeight
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -623,7 +614,7 @@ var VideoLayout = {
|
|||
var updateLargeVideo = false;
|
||||
|
||||
// Handle LastN/local LastN changes.
|
||||
$('#remoteVideos>span').each(function( index, element ) {
|
||||
BottomToolbar.getThumbs().each(function( index, element ) {
|
||||
var resourceJid = getPeerContainerResourceId(element);
|
||||
|
||||
// We do not want to process any logic for our own(local) video
|
||||
|
|
Loading…
Reference in New Issue