Merge branch 'video-fadein-fix' of https://github.com/isymchych/jitsi-meet into jitsi-meet-new
This commit is contained in:
commit
e707eb9a79
|
@ -1,7 +1,8 @@
|
||||||
/* global Strophe, APP, MD5, config, interfaceConfig */
|
/* global MD5, config, interfaceConfig */
|
||||||
var users = {};
|
|
||||||
|
|
||||||
var Avatar = {
|
let users = {};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the user's avatar in the settings menu(if local user), contact list
|
* Sets the user's avatar in the settings menu(if local user), contact list
|
||||||
|
@ -16,48 +17,46 @@ var Avatar = {
|
||||||
}
|
}
|
||||||
users[id] = email;
|
users[id] = email;
|
||||||
}
|
}
|
||||||
var avatarUrl = this.getAvatarUrl(id);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL of the image for the avatar of a particular user,
|
* Returns the URL of the image for the avatar of a particular user,
|
||||||
+ identified by its jid
|
* identified by its id.
|
||||||
* @param jid
|
* @param {string} userId user id
|
||||||
*/
|
*/
|
||||||
getAvatarUrl: function (jid) {
|
getAvatarUrl: function (userId) {
|
||||||
if (config.disableThirdPartyRequests) {
|
if (config.disableThirdPartyRequests) {
|
||||||
return 'images/avatar2.png';
|
return 'images/avatar2.png';
|
||||||
} else {
|
}
|
||||||
if (!jid) {
|
|
||||||
console.error("Get avatar - jid is undefined");
|
if (!userId) {
|
||||||
|
console.error("Get avatar - id is undefined");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var id = users[jid];
|
|
||||||
|
let avatarId = users[userId];
|
||||||
|
|
||||||
// If the ID looks like an email, we'll use gravatar.
|
// If the ID looks like an email, we'll use gravatar.
|
||||||
// Otherwise, it's a random avatar, and we'll use the configured
|
// Otherwise, it's a random avatar, and we'll use the configured
|
||||||
// URL.
|
// URL.
|
||||||
var random = !id || id.indexOf('@') < 0;
|
let random = !avatarId || avatarId.indexOf('@') < 0;
|
||||||
|
|
||||||
if (!id) {
|
if (!avatarId) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"No avatar stored yet for " + jid + " - using JID as ID");
|
`No avatar stored yet for ${userId} - using ID as avatar ID`);
|
||||||
id = jid;
|
avatarId = userId;
|
||||||
}
|
}
|
||||||
id = MD5.hexdigest(id.trim().toLowerCase());
|
avatarId = MD5.hexdigest(avatarId.trim().toLowerCase());
|
||||||
|
|
||||||
// Default to using gravatar.
|
// Default to using gravatar.
|
||||||
var urlPref = 'https://www.gravatar.com/avatar/';
|
let urlPref = 'https://www.gravatar.com/avatar/';
|
||||||
var urlSuf = "?d=wavatar&size=100";
|
let urlSuf = "?d=wavatar&size=100";
|
||||||
|
|
||||||
if (random && interfaceConfig.RANDOM_AVATAR_URL_PREFIX) {
|
if (random && interfaceConfig.RANDOM_AVATAR_URL_PREFIX) {
|
||||||
urlPref = interfaceConfig.RANDOM_AVATAR_URL_PREFIX;
|
urlPref = interfaceConfig.RANDOM_AVATAR_URL_PREFIX;
|
||||||
urlSuf = interfaceConfig.RANDOM_AVATAR_URL_SUFFIX;
|
urlSuf = interfaceConfig.RANDOM_AVATAR_URL_SUFFIX;
|
||||||
}
|
}
|
||||||
|
|
||||||
return urlPref + id + urlSuf;
|
return urlPref + avatarId + urlSuf;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = Avatar;
|
|
||||||
|
|
|
@ -6,19 +6,22 @@ import UIEvents from "../../../service/UI/UIEvents";
|
||||||
import LargeContainer from './LargeContainer';
|
import LargeContainer from './LargeContainer';
|
||||||
import BottomToolbar from '../toolbars/BottomToolbar';
|
import BottomToolbar from '../toolbars/BottomToolbar';
|
||||||
import Avatar from "../avatar/Avatar";
|
import Avatar from "../avatar/Avatar";
|
||||||
|
import {createDeferred} from '../../util/helpers';
|
||||||
|
|
||||||
const RTCBrowserType = require("../../RTC/RTCBrowserType");
|
const RTCBrowserType = require("../../RTC/RTCBrowserType");
|
||||||
|
|
||||||
const avatarSize = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE;
|
const avatarSize = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE;
|
||||||
|
const FADE_DURATION_MS = 300;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get stream id.
|
* Get stream id.
|
||||||
* @param {JitsiTrack?} stream
|
* @param {JitsiTrack?} stream
|
||||||
*/
|
*/
|
||||||
function getStreamId(stream) {
|
function getStreamOwnerId(stream) {
|
||||||
if(!stream)
|
if (!stream) {
|
||||||
return;
|
return;
|
||||||
if (stream.isLocal()) {
|
}
|
||||||
|
if (stream.isLocal()) { // local stream doesn't have method "getParticipantId"
|
||||||
return APP.conference.localId;
|
return APP.conference.localId;
|
||||||
} else {
|
} else {
|
||||||
return stream.getParticipantId();
|
return stream.getParticipantId();
|
||||||
|
@ -161,9 +164,7 @@ class VideoContainer extends LargeContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
get id () {
|
get id () {
|
||||||
if (this.stream) {
|
return getStreamOwnerId(this.stream);
|
||||||
return getStreamId(this.stream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor (onPlay) {
|
constructor (onPlay) {
|
||||||
|
@ -306,20 +307,20 @@ class VideoContainer extends LargeContainer {
|
||||||
show () {
|
show () {
|
||||||
let $wrapper = this.$wrapper;
|
let $wrapper = this.$wrapper;
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
$wrapper.fadeIn(300, function () {
|
|
||||||
$wrapper.css({visibility: 'visible'});
|
$wrapper.css({visibility: 'visible'});
|
||||||
|
$wrapper.fadeIn(FADE_DURATION_MS, function () {
|
||||||
$('.watermark').css({visibility: 'visible'});
|
$('.watermark').css({visibility: 'visible'});
|
||||||
});
|
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hide () {
|
hide () {
|
||||||
|
|
||||||
let $wrapper = this.$wrapper;
|
let $wrapper = this.$wrapper;
|
||||||
|
|
||||||
|
let id = this.id;
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
$wrapper.fadeOut(300, function () {
|
$wrapper.fadeOut(id ? FADE_DURATION_MS : 1, function () {
|
||||||
$wrapper.css({visibility: 'hidden'});
|
$wrapper.css({visibility: 'hidden'});
|
||||||
$('.watermark').css({visibility: 'hidden'});
|
$('.watermark').css({visibility: 'hidden'});
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -397,6 +398,45 @@ export default class LargeVideoManager {
|
||||||
return this.videoContainer.id;
|
return this.videoContainer.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduleLargeVideoUpdate () {
|
||||||
|
if (this.updateInProcess || !this.newStreamData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateInProcess = true;
|
||||||
|
|
||||||
|
let container = this.getContainer(this.state);
|
||||||
|
|
||||||
|
container.hide().then(() => {
|
||||||
|
let {id, stream, videoType, resolve} = this.newStreamData;
|
||||||
|
this.newStreamData = null;
|
||||||
|
|
||||||
|
console.info("hover in %s", id);
|
||||||
|
this.state = VideoContainerType;
|
||||||
|
this.videoContainer.setStream(stream, videoType);
|
||||||
|
|
||||||
|
// change the avatar url on large
|
||||||
|
this.updateAvatar(Avatar.getAvatarUrl(id));
|
||||||
|
|
||||||
|
let isVideoMuted = stream.isMuted();
|
||||||
|
|
||||||
|
// show the avatar on large if needed
|
||||||
|
this.videoContainer.showAvatar(isVideoMuted);
|
||||||
|
|
||||||
|
// do not show stream if video is muted
|
||||||
|
let promise = isVideoMuted ? Promise.resolve() : this.videoContainer.show();
|
||||||
|
|
||||||
|
// resolve updateLargeVideo promise after everything is done
|
||||||
|
promise.then(resolve);
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}).then(() => {
|
||||||
|
// after everything is done check again if there are any pending new streams.
|
||||||
|
this.updateInProcess = false;
|
||||||
|
this.scheduleLargeVideoUpdate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update large video.
|
* Update large video.
|
||||||
* Switches to large video even if previously other container was visible.
|
* Switches to large video even if previously other container was visible.
|
||||||
|
@ -404,28 +444,21 @@ export default class LargeVideoManager {
|
||||||
* @param {string?} videoType new video type
|
* @param {string?} videoType new video type
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
updateLargeVideo (smallVideo, videoType, largeVideoUpdatedCallBack) {
|
updateLargeVideo (stream, videoType) {
|
||||||
let id = getStreamId(smallVideo.stream);
|
let id = getStreamOwnerId(stream);
|
||||||
|
|
||||||
let container = this.getContainer(this.state);
|
if (this.newStreamData) {
|
||||||
|
this.newStreamData.reject();
|
||||||
|
}
|
||||||
|
|
||||||
container.hide().then(() => {
|
this.newStreamData = createDeferred();
|
||||||
console.info("hover in %s", id);
|
this.newStreamData.id = id;
|
||||||
this.state = VideoContainerType;
|
this.newStreamData.stream = stream;
|
||||||
this.videoContainer.setStream(smallVideo.stream, videoType);
|
this.newStreamData.videoType = videoType;
|
||||||
|
|
||||||
// change the avatar url on large
|
this.scheduleLargeVideoUpdate();
|
||||||
this.updateAvatar(Avatar.getAvatarUrl(smallVideo.id));
|
|
||||||
|
|
||||||
var isVideoMuted = smallVideo.stream.isMuted()
|
return this.newStreamData.promise;
|
||||||
// show the avatar on large if needed
|
|
||||||
this.videoContainer.showAvatar(isVideoMuted);
|
|
||||||
|
|
||||||
if (!isVideoMuted)
|
|
||||||
this.videoContainer.show();
|
|
||||||
|
|
||||||
largeVideoUpdatedCallBack();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -486,7 +519,6 @@ export default class LargeVideoManager {
|
||||||
* @param {boolean} show
|
* @param {boolean} show
|
||||||
*/
|
*/
|
||||||
showAvatar (show) {
|
showAvatar (show) {
|
||||||
show ? this.videoContainer.hide() : this.videoContainer.show();
|
|
||||||
this.videoContainer.showAvatar(show);
|
this.videoContainer.showAvatar(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,16 +574,11 @@ export default class LargeVideoManager {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
let container = this.getContainer(type);
|
|
||||||
|
|
||||||
if (this.state) {
|
|
||||||
let oldContainer = this.containers[this.state];
|
let oldContainer = this.containers[this.state];
|
||||||
if (oldContainer) {
|
|
||||||
oldContainer.hide();
|
oldContainer.hide();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state = type;
|
this.state = type;
|
||||||
|
let container = this.getContainer(type);
|
||||||
|
|
||||||
return container.show();
|
return container.show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -990,13 +990,14 @@ var VideoLayout = {
|
||||||
|
|
||||||
let videoType = this.getRemoteVideoType(id);
|
let videoType = this.getRemoteVideoType(id);
|
||||||
largeVideo.updateLargeVideo(
|
largeVideo.updateLargeVideo(
|
||||||
smallVideo,
|
smallVideo.stream,
|
||||||
videoType,
|
videoType
|
||||||
// LargeVideoUpdatedCallBack
|
).then(function() {
|
||||||
function() {
|
|
||||||
// update current small video and the old one
|
// update current small video and the old one
|
||||||
smallVideo.updateView();
|
smallVideo.updateView();
|
||||||
oldSmallVideo && oldSmallVideo.updateView();
|
oldSmallVideo && oldSmallVideo.updateView();
|
||||||
|
}, function () {
|
||||||
|
// use clicked other video during update, nothing to do.
|
||||||
});
|
});
|
||||||
|
|
||||||
} else if (currentId) {
|
} else if (currentId) {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Create deferred object.
|
||||||
|
* @returns {{promise, resolve, reject}}
|
||||||
|
*/
|
||||||
|
export function createDeferred () {
|
||||||
|
let deferred = {};
|
||||||
|
|
||||||
|
deferred.promise = new Promise(function (resolve, reject) {
|
||||||
|
deferred.resolve = resolve;
|
||||||
|
deferred.reject = reject;
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred;
|
||||||
|
}
|
Loading…
Reference in New Issue