added some documentation (jsdocs)
This commit is contained in:
parent
a0355ea080
commit
6b98fd52ea
|
@ -17,6 +17,9 @@ const ConferenceErrors = JitsiMeetJS.errors.conference;
|
||||||
|
|
||||||
let room, connection, localTracks, localAudio, localVideo, roomLocker;
|
let room, connection, localTracks, localAudio, localVideo, roomLocker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Known custom conference commands.
|
||||||
|
*/
|
||||||
const Commands = {
|
const Commands = {
|
||||||
CONNECTION_QUALITY: "stats",
|
CONNECTION_QUALITY: "stats",
|
||||||
EMAIL: "email",
|
EMAIL: "email",
|
||||||
|
@ -26,6 +29,10 @@ const Commands = {
|
||||||
STOP_PREZI: "stop-prezi"
|
STOP_PREZI: "stop-prezi"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open Connection. When authentication failed it shows auth dialog.
|
||||||
|
* @returns Promise<JitsiConnection>
|
||||||
|
*/
|
||||||
function connect() {
|
function connect() {
|
||||||
return openConnection({retry: true}).catch(function (err) {
|
return openConnection({retry: true}).catch(function (err) {
|
||||||
if (err === ConnectionErrors.PASSWORD_REQUIRED) {
|
if (err === ConnectionErrors.PASSWORD_REQUIRED) {
|
||||||
|
@ -37,8 +44,14 @@ function connect() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const addTrack = (track) => {
|
/**
|
||||||
|
* Add local track to the conference and shares
|
||||||
|
* video type with other users if its video track.
|
||||||
|
* @param {JitsiLocalTrack} track local track
|
||||||
|
*/
|
||||||
|
function addTrack (track) {
|
||||||
room.addTrack(track);
|
room.addTrack(track);
|
||||||
|
|
||||||
if (track.isAudioTrack()) {
|
if (track.isAudioTrack()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -50,25 +63,35 @@ const addTrack = (track) => {
|
||||||
xmlns: 'http://jitsi.org/jitmeet/video'
|
xmlns: 'http://jitsi.org/jitmeet/video'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
// share email with other users
|
/**
|
||||||
const sendEmail = (email) => {
|
* Share email with other users.
|
||||||
|
* @param {string} email new email
|
||||||
|
*/
|
||||||
|
function sendEmail (email) {
|
||||||
room.sendCommand(Commands.EMAIL, {
|
room.sendCommand(Commands.EMAIL, {
|
||||||
value: email,
|
value: email,
|
||||||
attributes: {
|
attributes: {
|
||||||
id: room.myUserId()
|
id: room.myUserId()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
const unload = () => {
|
* Leave the conference and close connection.
|
||||||
|
*/
|
||||||
|
function unload () {
|
||||||
room.leave();
|
room.leave();
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
};
|
}
|
||||||
|
|
||||||
const getDisplayName = (id) => {
|
/**
|
||||||
|
* Get user nickname by user id.
|
||||||
|
* @param {string} id user id
|
||||||
|
* @returns {string?} user nickname or undefined if user is unknown.
|
||||||
|
*/
|
||||||
|
function getDisplayName (id) {
|
||||||
if (APP.conference.isLocalId(id)) {
|
if (APP.conference.isLocalId(id)) {
|
||||||
return APP.settings.getDisplayName();
|
return APP.settings.getDisplayName();
|
||||||
}
|
}
|
||||||
|
@ -77,7 +100,7 @@ const getDisplayName = (id) => {
|
||||||
if (participant && participant.getDisplayName()) {
|
if (participant && participant.getDisplayName()) {
|
||||||
return participant.getDisplayName();
|
return participant.getDisplayName();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
class ConferenceConnector {
|
class ConferenceConnector {
|
||||||
constructor(resolve, reject) {
|
constructor(resolve, reject) {
|
||||||
|
@ -151,6 +174,12 @@ export default {
|
||||||
isModerator: false,
|
isModerator: false,
|
||||||
audioMuted: false,
|
audioMuted: false,
|
||||||
videoMuted: false,
|
videoMuted: false,
|
||||||
|
/**
|
||||||
|
* Open new connection and join to the conference.
|
||||||
|
* @param {object} options
|
||||||
|
* @param {string} roomName name of the conference
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
init(options) {
|
init(options) {
|
||||||
this.roomName = options.roomName;
|
this.roomName = options.roomName;
|
||||||
JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.TRACE);
|
JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.TRACE);
|
||||||
|
@ -173,6 +202,12 @@ export default {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Create local tracks of specified types.
|
||||||
|
* If we cannot obtain required tracks it will return empty array.
|
||||||
|
* @param {string[]} devices required track types ('audio', 'video' etc.)
|
||||||
|
* @returns {Promise<JitsiLocalTrack[]>}
|
||||||
|
*/
|
||||||
createLocalTracks (...devices) {
|
createLocalTracks (...devices) {
|
||||||
return JitsiMeetJS.createLocalTracks({
|
return JitsiMeetJS.createLocalTracks({
|
||||||
// copy array to avoid mutations inside library
|
// copy array to avoid mutations inside library
|
||||||
|
@ -184,6 +219,11 @@ export default {
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check if id is id of the local user.
|
||||||
|
* @param {string} id id to check
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
isLocalId (id) {
|
isLocalId (id) {
|
||||||
return this.localId === id;
|
return this.localId === id;
|
||||||
},
|
},
|
||||||
|
@ -217,12 +257,24 @@ export default {
|
||||||
toggleVideoMuted () {
|
toggleVideoMuted () {
|
||||||
this.muteVideo(!this.videoMuted);
|
this.muteVideo(!this.videoMuted);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Retrieve list of conference participants (without local user).
|
||||||
|
* @returns {JitsiParticipant[]}
|
||||||
|
*/
|
||||||
listMembers () {
|
listMembers () {
|
||||||
return room.getParticipants();
|
return room.getParticipants();
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Retrieve list of ids of conference participants (without local user).
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
listMembersIds () {
|
listMembersIds () {
|
||||||
return room.getParticipants().map(p => p.getId());
|
return room.getParticipants().map(p => p.getId());
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check if SIP is supported.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
sipGatewayEnabled () {
|
sipGatewayEnabled () {
|
||||||
return room.isSIPCallingSupported();
|
return room.isSIPCallingSupported();
|
||||||
},
|
},
|
||||||
|
@ -279,7 +331,7 @@ export default {
|
||||||
/**
|
/**
|
||||||
* Will check for number of remote particiapnts that have at least one
|
* Will check for number of remote particiapnts that have at least one
|
||||||
* remote track.
|
* remote track.
|
||||||
* @return boolean whether we have enough participants with remote streams
|
* @return {boolean} whether we have enough participants with remote streams
|
||||||
*/
|
*/
|
||||||
checkEnoughParticipants (number) {
|
checkEnoughParticipants (number) {
|
||||||
var participants = this._room.getParticipants();
|
var participants = this._room.getParticipants();
|
||||||
|
@ -336,6 +388,9 @@ export default {
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Setup interaction between conference and UI.
|
||||||
|
*/
|
||||||
_setupListeners () {
|
_setupListeners () {
|
||||||
// add local streams when joined to the conference
|
// add local streams when joined to the conference
|
||||||
room.on(ConferenceEvents.CONFERENCE_JOINED, () => {
|
room.on(ConferenceEvents.CONFERENCE_JOINED, () => {
|
||||||
|
|
|
@ -5,6 +5,13 @@ import LoginDialog from './modules/UI/authentication/LoginDialog';
|
||||||
const ConnectionEvents = JitsiMeetJS.events.connection;
|
const ConnectionEvents = JitsiMeetJS.events.connection;
|
||||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to open connection using provided credentials.
|
||||||
|
* @param {string} [id]
|
||||||
|
* @param {string} [password]
|
||||||
|
* @returns {Promise<JitsiConnection>} connection if
|
||||||
|
* everything is ok, else error.
|
||||||
|
*/
|
||||||
function connect(id, password) {
|
function connect(id, password) {
|
||||||
let connection = new JitsiMeetJS.JitsiConnection(null, null, config);
|
let connection = new JitsiMeetJS.JitsiConnection(null, null, config);
|
||||||
|
|
||||||
|
@ -42,6 +49,12 @@ function connect(id, password) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Authentication Dialog and try to connect with new credentials.
|
||||||
|
* If failed to connect because of PASSWORD_REQUIRED error
|
||||||
|
* then ask for password again.
|
||||||
|
* @returns {Promise<JitsiConnection>}
|
||||||
|
*/
|
||||||
function requestAuth() {
|
function requestAuth() {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
let authDialog = LoginDialog.showAuthDialog(
|
let authDialog = LoginDialog.showAuthDialog(
|
||||||
|
@ -62,6 +75,18 @@ function requestAuth() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open JitsiConnection using provided credentials.
|
||||||
|
* If retry option is true it will show auth dialog on PASSWORD_REQUIRED error.
|
||||||
|
*
|
||||||
|
* @param {object} options
|
||||||
|
* @param {string} [options.id]
|
||||||
|
* @param {string} [options.password]
|
||||||
|
* @param {boolean} [retry] if we should show auth dialog
|
||||||
|
* on PASSWORD_REQUIRED error.
|
||||||
|
*
|
||||||
|
* @returns {Promise<JitsiConnection>}
|
||||||
|
*/
|
||||||
export function openConnection({id, password, retry}) {
|
export function openConnection({id, password, retry}) {
|
||||||
return connect(id, password).catch(function (err) {
|
return connect(id, password).catch(function (err) {
|
||||||
if (!retry) {
|
if (!retry) {
|
||||||
|
|
178
modules/UI/UI.js
178
modules/UI/UI.js
|
@ -31,6 +31,9 @@ UI.eventEmitter = eventEmitter;
|
||||||
let preziManager;
|
let preziManager;
|
||||||
let etherpadManager;
|
let etherpadManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt user for nickname.
|
||||||
|
*/
|
||||||
function promptDisplayName() {
|
function promptDisplayName() {
|
||||||
let nickRequiredMsg = APP.translation.translateString("dialog.displayNameRequired");
|
let nickRequiredMsg = APP.translation.translateString("dialog.displayNameRequired");
|
||||||
let defaultNickMsg = APP.translation.translateString(
|
let defaultNickMsg = APP.translation.translateString(
|
||||||
|
@ -76,6 +79,9 @@ function promptDisplayName() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize chat.
|
||||||
|
*/
|
||||||
function setupChat() {
|
function setupChat() {
|
||||||
Chat.init(eventEmitter);
|
Chat.init(eventEmitter);
|
||||||
$("#toggle_smileys").click(function() {
|
$("#toggle_smileys").click(function() {
|
||||||
|
@ -83,6 +89,9 @@ function setupChat() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize toolbars.
|
||||||
|
*/
|
||||||
function setupToolbars() {
|
function setupToolbars() {
|
||||||
Toolbar.init(eventEmitter);
|
Toolbar.init(eventEmitter);
|
||||||
Toolbar.setupButtonsFromConfig();
|
Toolbar.setupButtonsFromConfig();
|
||||||
|
@ -113,6 +122,9 @@ function toggleFullScreen () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that server has shut down.
|
||||||
|
*/
|
||||||
UI.notifyGracefulShudown = function () {
|
UI.notifyGracefulShudown = function () {
|
||||||
messageHandler.openMessageDialog(
|
messageHandler.openMessageDialog(
|
||||||
'dialog.serviceUnavailable',
|
'dialog.serviceUnavailable',
|
||||||
|
@ -120,6 +132,9 @@ UI.notifyGracefulShudown = function () {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that reservation error happened.
|
||||||
|
*/
|
||||||
UI.notifyReservationError = function (code, msg) {
|
UI.notifyReservationError = function (code, msg) {
|
||||||
var title = APP.translation.generateTranslationHTML(
|
var title = APP.translation.generateTranslationHTML(
|
||||||
"dialog.reservationError");
|
"dialog.reservationError");
|
||||||
|
@ -135,14 +150,25 @@ UI.notifyReservationError = function (code, msg) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that he has been kicked from the server.
|
||||||
|
*/
|
||||||
UI.notifyKicked = function () {
|
UI.notifyKicked = function () {
|
||||||
messageHandler.openMessageDialog("dialog.sessTerminated", "dialog.kickMessage");
|
messageHandler.openMessageDialog("dialog.sessTerminated", "dialog.kickMessage");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that Jitsi Videobridge is not accessible.
|
||||||
|
*/
|
||||||
UI.notifyBridgeDown = function () {
|
UI.notifyBridgeDown = function () {
|
||||||
messageHandler.showError("dialog.error", "dialog.bridgeUnavailable");
|
messageHandler.showError("dialog.error", "dialog.bridgeUnavailable");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change nickname for the user.
|
||||||
|
* @param {string} id user id
|
||||||
|
* @param {string} displayName new nickname
|
||||||
|
*/
|
||||||
UI.changeDisplayName = function (id, displayName) {
|
UI.changeDisplayName = function (id, displayName) {
|
||||||
ContactList.onDisplayNameChange(id, displayName);
|
ContactList.onDisplayNameChange(id, displayName);
|
||||||
SettingsMenu.onDisplayNameChange(id, displayName);
|
SettingsMenu.onDisplayNameChange(id, displayName);
|
||||||
|
@ -153,6 +179,9 @@ UI.changeDisplayName = function (id, displayName) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intitialize conference UI.
|
||||||
|
*/
|
||||||
UI.initConference = function () {
|
UI.initConference = function () {
|
||||||
var id = APP.conference.localId;
|
var id = APP.conference.localId;
|
||||||
Toolbar.updateRoomUrl(window.location.href);
|
Toolbar.updateRoomUrl(window.location.href);
|
||||||
|
@ -186,6 +215,9 @@ UI.mucJoined = function () {
|
||||||
VideoLayout.mucJoined();
|
VideoLayout.mucJoined();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup some UI event listeners.
|
||||||
|
*/
|
||||||
function registerListeners() {
|
function registerListeners() {
|
||||||
UI.addListener(UIEvents.EMAIL_CHANGED, function (email) {
|
UI.addListener(UIEvents.EMAIL_CHANGED, function (email) {
|
||||||
UI.setUserAvatar(APP.conference.localId, email);
|
UI.setUserAvatar(APP.conference.localId, email);
|
||||||
|
@ -214,6 +246,9 @@ function registerListeners() {
|
||||||
UI.addListener(UIEvents.TOGGLE_FILM_STRIP, UI.toggleFilmStrip);
|
UI.addListener(UIEvents.TOGGLE_FILM_STRIP, UI.toggleFilmStrip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup some DOM event listeners.
|
||||||
|
*/
|
||||||
function bindEvents() {
|
function bindEvents() {
|
||||||
function onResize() {
|
function onResize() {
|
||||||
PanelToggler.resizeChat();
|
PanelToggler.resizeChat();
|
||||||
|
@ -341,6 +376,10 @@ UI.start = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show local stream on UI.
|
||||||
|
* @param {JitsiTrack} track stream to show
|
||||||
|
*/
|
||||||
UI.addLocalStream = function (track) {
|
UI.addLocalStream = function (track) {
|
||||||
switch (track.getType()) {
|
switch (track.getType()) {
|
||||||
case 'audio':
|
case 'audio':
|
||||||
|
@ -356,18 +395,30 @@ UI.addLocalStream = function (track) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
UI.addRemoteStream = function (stream) {
|
/**
|
||||||
VideoLayout.onRemoteStreamAdded(stream);
|
* Show remote stream on UI.
|
||||||
|
* @param {JitsiTrack} track stream to show
|
||||||
|
*/
|
||||||
|
UI.addRemoteStream = function (track) {
|
||||||
|
VideoLayout.onRemoteStreamAdded(track);
|
||||||
};
|
};
|
||||||
|
|
||||||
function chatAddError(errorMessage, originalText) {
|
function chatAddError(errorMessage, originalText) {
|
||||||
return Chat.chatAddError(errorMessage, originalText);
|
return Chat.chatAddError(errorMessage, originalText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update chat subject.
|
||||||
|
* @param {string} subject new chat subject
|
||||||
|
*/
|
||||||
UI.setSubject = function (subject) {
|
UI.setSubject = function (subject) {
|
||||||
Chat.setSubject(subject);
|
Chat.setSubject(subject);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup and show Etherpad.
|
||||||
|
* @param {string} name etherpad id
|
||||||
|
*/
|
||||||
UI.initEtherpad = function (name) {
|
UI.initEtherpad = function (name) {
|
||||||
if (etherpadManager || !config.etherpad_base || !name) {
|
if (etherpadManager || !config.etherpad_base || !name) {
|
||||||
return;
|
return;
|
||||||
|
@ -377,6 +428,11 @@ UI.initEtherpad = function (name) {
|
||||||
Toolbar.showEtherpadButton();
|
Toolbar.showEtherpadButton();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show user on UI.
|
||||||
|
* @param {string} id user id
|
||||||
|
* @param {string} displayName user nickname
|
||||||
|
*/
|
||||||
UI.addUser = function (id, displayName) {
|
UI.addUser = function (id, displayName) {
|
||||||
ContactList.addContact(id);
|
ContactList.addContact(id);
|
||||||
|
|
||||||
|
@ -395,6 +451,11 @@ UI.addUser = function (id, displayName) {
|
||||||
VideoLayout.addParticipantContainer(id);
|
VideoLayout.addParticipantContainer(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove user from UI.
|
||||||
|
* @param {string} id user id
|
||||||
|
* @param {string} displayName user nickname
|
||||||
|
*/
|
||||||
UI.removeUser = function (id, displayName) {
|
UI.removeUser = function (id, displayName) {
|
||||||
ContactList.removeContact(id);
|
ContactList.removeContact(id);
|
||||||
|
|
||||||
|
@ -415,10 +476,19 @@ UI.removeUser = function (id, displayName) {
|
||||||
// VideoLayout.setPresenceStatus(Strophe.getResourceFromJid(jid), info.status);
|
// VideoLayout.setPresenceStatus(Strophe.getResourceFromJid(jid), info.status);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update videotype for specified user.
|
||||||
|
* @param {string} id user id
|
||||||
|
* @param {string} newVideoType new videotype
|
||||||
|
*/
|
||||||
UI.onPeerVideoTypeChanged = (id, newVideoType) => {
|
UI.onPeerVideoTypeChanged = (id, newVideoType) => {
|
||||||
VideoLayout.onVideoTypeChanged(id, newVideoType);
|
VideoLayout.onVideoTypeChanged(id, newVideoType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update local user role and show notification if user is moderator.
|
||||||
|
* @param {boolean} isModerator if local user is moderator or not
|
||||||
|
*/
|
||||||
UI.updateLocalRole = function (isModerator) {
|
UI.updateLocalRole = function (isModerator) {
|
||||||
VideoLayout.showModeratorIndicator();
|
VideoLayout.showModeratorIndicator();
|
||||||
|
|
||||||
|
@ -462,22 +532,38 @@ UI.updateUserRole = function (user) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles smileys in the chat.
|
||||||
|
*/
|
||||||
UI.toggleSmileys = function () {
|
UI.toggleSmileys = function () {
|
||||||
Chat.toggleSmileys();
|
Chat.toggleSmileys();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current settings.
|
||||||
|
* @returns {object} settings
|
||||||
|
*/
|
||||||
UI.getSettings = function () {
|
UI.getSettings = function () {
|
||||||
return Settings.getSettings();
|
return Settings.getSettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles film strip.
|
||||||
|
*/
|
||||||
UI.toggleFilmStrip = function () {
|
UI.toggleFilmStrip = function () {
|
||||||
BottomToolbar.toggleFilmStrip();
|
BottomToolbar.toggleFilmStrip();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles chat panel.
|
||||||
|
*/
|
||||||
UI.toggleChat = function () {
|
UI.toggleChat = function () {
|
||||||
PanelToggler.toggleChat();
|
PanelToggler.toggleChat();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles contact list panel.
|
||||||
|
*/
|
||||||
UI.toggleContactList = function () {
|
UI.toggleContactList = function () {
|
||||||
PanelToggler.toggleContactList();
|
PanelToggler.toggleContactList();
|
||||||
};
|
};
|
||||||
|
@ -499,6 +585,7 @@ UI.connectionIndicatorShowMore = function(jid) {
|
||||||
return VideoLayout.showMore(jid);
|
return VideoLayout.showMore(jid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FIXME check if someone user this
|
||||||
UI.showLoginPopup = function(callback) {
|
UI.showLoginPopup = function(callback) {
|
||||||
console.log('password is required');
|
console.log('password is required');
|
||||||
var message = '<h2 data-i18n="dialog.passwordRequired">';
|
var message = '<h2 data-i18n="dialog.passwordRequired">';
|
||||||
|
@ -569,6 +656,11 @@ UI.dockToolbar = function (isDock) {
|
||||||
ToolbarToggler.dockToolbar(isDock);
|
ToolbarToggler.dockToolbar(isDock);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update user avatar.
|
||||||
|
* @param {string} id user id
|
||||||
|
* @param {stirng} email user email
|
||||||
|
*/
|
||||||
UI.setUserAvatar = function (id, email) {
|
UI.setUserAvatar = function (id, email) {
|
||||||
// update avatar
|
// update avatar
|
||||||
Avatar.setUserAvatar(id, email);
|
Avatar.setUserAvatar(id, email);
|
||||||
|
@ -582,6 +674,10 @@ UI.setUserAvatar = function (id, email) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that connection failed.
|
||||||
|
* @param {string} stropheErrorMsg raw Strophe error message
|
||||||
|
*/
|
||||||
UI.notifyConnectionFailed = function (stropheErrorMsg) {
|
UI.notifyConnectionFailed = function (stropheErrorMsg) {
|
||||||
var title = APP.translation.generateTranslationHTML(
|
var title = APP.translation.generateTranslationHTML(
|
||||||
"dialog.error");
|
"dialog.error");
|
||||||
|
@ -600,6 +696,10 @@ UI.notifyConnectionFailed = function (stropheErrorMsg) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that he need to install Firefox extension to share screen.
|
||||||
|
* @param {stirng} url extension url
|
||||||
|
*/
|
||||||
UI.notifyFirefoxExtensionRequired = function (url) {
|
UI.notifyFirefoxExtensionRequired = function (url) {
|
||||||
messageHandler.openMessageDialog(
|
messageHandler.openMessageDialog(
|
||||||
"dialog.extensionRequired",
|
"dialog.extensionRequired",
|
||||||
|
@ -611,12 +711,19 @@ UI.notifyFirefoxExtensionRequired = function (url) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that he was automatically muted when joned the conference.
|
||||||
|
*/
|
||||||
UI.notifyInitiallyMuted = function () {
|
UI.notifyInitiallyMuted = function () {
|
||||||
messageHandler.notify(
|
messageHandler.notify(
|
||||||
null, "notify.mutedTitle", "connected", "notify.muted", null, {timeOut: 120000}
|
null, "notify.mutedTitle", "connected", "notify.muted", null, {timeOut: 120000}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark user as dominant speaker.
|
||||||
|
* @param {string} id user id
|
||||||
|
*/
|
||||||
UI.markDominantSpeaker = function (id) {
|
UI.markDominantSpeaker = function (id) {
|
||||||
VideoLayout.onDominantSpeakerChanged(id);
|
VideoLayout.onDominantSpeakerChanged(id);
|
||||||
};
|
};
|
||||||
|
@ -625,26 +732,53 @@ UI.handleLastNEndpoints = function (ids) {
|
||||||
VideoLayout.onLastNEndpointsChanged(ids, []);
|
VideoLayout.onLastNEndpointsChanged(ids, []);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update audio level visualization for specified user.
|
||||||
|
* @param {string} id user id
|
||||||
|
* @param {number} lvl audio level
|
||||||
|
*/
|
||||||
UI.setAudioLevel = function (id, lvl) {
|
UI.setAudioLevel = function (id, lvl) {
|
||||||
VideoLayout.setAudioLevel(id, lvl);
|
VideoLayout.setAudioLevel(id, lvl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update state of desktop sharing buttons.
|
||||||
|
* @param {boolean} isSharingScreen if user is currently sharing his screen
|
||||||
|
*/
|
||||||
UI.updateDesktopSharingButtons = function (isSharingScreen) {
|
UI.updateDesktopSharingButtons = function (isSharingScreen) {
|
||||||
Toolbar.changeDesktopSharingButtonState(isSharingScreen);
|
Toolbar.changeDesktopSharingButtonState(isSharingScreen);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide connection quality statistics from UI.
|
||||||
|
*/
|
||||||
UI.hideStats = function () {
|
UI.hideStats = function () {
|
||||||
VideoLayout.hideStats();
|
VideoLayout.hideStats();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update local connection quality statistics.
|
||||||
|
* @param {number} percent
|
||||||
|
* @param {object} stats
|
||||||
|
*/
|
||||||
UI.updateLocalStats = function (percent, stats) {
|
UI.updateLocalStats = function (percent, stats) {
|
||||||
VideoLayout.updateLocalConnectionStats(percent, stats);
|
VideoLayout.updateLocalConnectionStats(percent, stats);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update connection quality statistics for remote user.
|
||||||
|
* @param {string} id user id
|
||||||
|
* @param {number} percent
|
||||||
|
* @param {object} stats
|
||||||
|
*/
|
||||||
UI.updateRemoteStats = function (id, percent, stats) {
|
UI.updateRemoteStats = function (id, percent, stats) {
|
||||||
VideoLayout.updateConnectionStats(id, percent, stats);
|
VideoLayout.updateConnectionStats(id, percent, stats);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark video as interrupted or not.
|
||||||
|
* @param {boolean} interrupted if video is interrupted
|
||||||
|
*/
|
||||||
UI.markVideoInterrupted = function (interrupted) {
|
UI.markVideoInterrupted = function (interrupted) {
|
||||||
if (interrupted) {
|
if (interrupted) {
|
||||||
VideoLayout.onVideoInterrupted();
|
VideoLayout.onVideoInterrupted();
|
||||||
|
@ -653,6 +787,10 @@ UI.markVideoInterrupted = function (interrupted) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark room as locked or not.
|
||||||
|
* @param {boolean} locked if room is locked.
|
||||||
|
*/
|
||||||
UI.markRoomLocked = function (locked) {
|
UI.markRoomLocked = function (locked) {
|
||||||
if (locked) {
|
if (locked) {
|
||||||
Toolbar.lockLockButton();
|
Toolbar.lockLockButton();
|
||||||
|
@ -661,6 +799,13 @@ UI.markRoomLocked = function (locked) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add chat message.
|
||||||
|
* @param {string} from user id
|
||||||
|
* @param {string} displayName user nickname
|
||||||
|
* @param {string} message message text
|
||||||
|
* @param {number} stamp timestamp when message was created
|
||||||
|
*/
|
||||||
UI.addMessage = function (from, displayName, message, stamp) {
|
UI.addMessage = function (from, displayName, message, stamp) {
|
||||||
Chat.updateChatConversation(from, displayName, message, stamp);
|
Chat.updateChatConversation(from, displayName, message, stamp);
|
||||||
};
|
};
|
||||||
|
@ -672,6 +817,10 @@ UI.updateDTMFSupport = function (isDTMFSupported) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invite participants to conference.
|
* Invite participants to conference.
|
||||||
|
* @param {string} roomUrl
|
||||||
|
* @param {string} conferenceName
|
||||||
|
* @param {string} key
|
||||||
|
* @param {string} nick
|
||||||
*/
|
*/
|
||||||
UI.inviteParticipants = function (roomUrl, conferenceName, key, nick) {
|
UI.inviteParticipants = function (roomUrl, conferenceName, key, nick) {
|
||||||
let keyText = "";
|
let keyText = "";
|
||||||
|
@ -710,6 +859,10 @@ UI.inviteParticipants = function (roomUrl, conferenceName, key, nick) {
|
||||||
window.open(`mailto:?subject=${subject}&body=${body}`, '_blank');
|
window.open(`mailto:?subject=${subject}&body=${body}`, '_blank');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show user feedback dialog if its required or just show "thank you" dialog.
|
||||||
|
* @returns {Promise} when dialog is closed.
|
||||||
|
*/
|
||||||
UI.requestFeedback = function () {
|
UI.requestFeedback = function () {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
if (Feedback.isEnabled()) {
|
if (Feedback.isEnabled()) {
|
||||||
|
@ -736,6 +889,10 @@ UI.requestFeedback = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request recording token from the user.
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
UI.requestRecordingToken = function () {
|
UI.requestRecordingToken = function () {
|
||||||
let msg = APP.translation.generateTranslationHTML("dialog.recordingToken");
|
let msg = APP.translation.generateTranslationHTML("dialog.recordingToken");
|
||||||
let token = APP.translation.translateString("dialog.token");
|
let token = APP.translation.translateString("dialog.token");
|
||||||
|
@ -769,6 +926,11 @@ UI.notifyTokenAuthFailed = function () {
|
||||||
messageHandler.showError("dialog.error", "dialog.tokenAuthFailed");
|
messageHandler.showError("dialog.error", "dialog.tokenAuthFailed");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates auth info on the UI.
|
||||||
|
* @param {boolean} isAuthEnabled if authentication is enabled
|
||||||
|
* @param {string} [login] current login
|
||||||
|
*/
|
||||||
UI.updateAuthInfo = function (isAuthEnabled, login) {
|
UI.updateAuthInfo = function (isAuthEnabled, login) {
|
||||||
let loggedIn = !!login;
|
let loggedIn = !!login;
|
||||||
|
|
||||||
|
@ -782,10 +944,20 @@ UI.updateAuthInfo = function (isAuthEnabled, login) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Prezi from the user.
|
||||||
|
* @param {string} userId user id
|
||||||
|
* @param {string} url Prezi url
|
||||||
|
* @param {number} slide slide to show
|
||||||
|
*/
|
||||||
UI.showPrezi = function (userId, url, slide) {
|
UI.showPrezi = function (userId, url, slide) {
|
||||||
preziManager.showPrezi(userId, url, slide);
|
preziManager.showPrezi(userId, url, slide);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop showing Prezi from the user.
|
||||||
|
* @param {string} userId user id
|
||||||
|
*/
|
||||||
UI.stopPrezi = function (userId) {
|
UI.stopPrezi = function (userId) {
|
||||||
if (preziManager.isSharing(userId)) {
|
if (preziManager.isSharing(userId)) {
|
||||||
preziManager.removePrezi(userId);
|
preziManager.removePrezi(userId);
|
||||||
|
@ -798,7 +970,7 @@ UI.onStartMutedChanged = function () {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the id of the current video shown on large.
|
* Returns the id of the current video shown on large.
|
||||||
* Currently used by tests (troture).
|
* Currently used by tests (torture).
|
||||||
*/
|
*/
|
||||||
UI.getLargeVideoID = function () {
|
UI.getLargeVideoID = function () {
|
||||||
return VideoLayout.getLargeVideoID();
|
return VideoLayout.getLargeVideoID();
|
||||||
|
|
|
@ -10,6 +10,13 @@ const ConferenceEvents = JitsiMeetJS.events.conference;
|
||||||
let externalAuthWindow;
|
let externalAuthWindow;
|
||||||
let authRequiredDialog;
|
let authRequiredDialog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate using external service or just focus
|
||||||
|
* external auth window if there is one already.
|
||||||
|
*
|
||||||
|
* @param {JitsiConference} room
|
||||||
|
* @param {string} [lockPassword] password to use if the conference is locked
|
||||||
|
*/
|
||||||
function doExternalAuth (room, lockPassword) {
|
function doExternalAuth (room, lockPassword) {
|
||||||
if (externalAuthWindow) {
|
if (externalAuthWindow) {
|
||||||
externalAuthWindow.focus();
|
externalAuthWindow.focus();
|
||||||
|
@ -32,6 +39,11 @@ function doExternalAuth (room, lockPassword) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate on the server.
|
||||||
|
* @param {JitsiConference} room
|
||||||
|
* @param {string} [lockPassword] password to use if the conference is locked
|
||||||
|
*/
|
||||||
function doXmppAuth (room, lockPassword) {
|
function doXmppAuth (room, lockPassword) {
|
||||||
let loginDialog = LoginDialog.showAuthDialog(function (id, password) {
|
let loginDialog = LoginDialog.showAuthDialog(function (id, password) {
|
||||||
// auth "on the fly":
|
// auth "on the fly":
|
||||||
|
@ -83,6 +95,12 @@ function doXmppAuth (room, lockPassword) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate for the conference.
|
||||||
|
* Uses external service for auth if conference supports that.
|
||||||
|
* @param {JitsiConference} room
|
||||||
|
* @param {string} [lockPassword] password to use if the conference is locked
|
||||||
|
*/
|
||||||
function authenticate (room, lockPassword) {
|
function authenticate (room, lockPassword) {
|
||||||
if (room.isExternalAuthEnabled()) {
|
if (room.isExternalAuthEnabled()) {
|
||||||
doExternalAuth(room, lockPassword);
|
doExternalAuth(room, lockPassword);
|
||||||
|
@ -91,6 +109,9 @@ function authenticate (room, lockPassword) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that authentication is required to create the conference.
|
||||||
|
*/
|
||||||
function requireAuth(roomName) {
|
function requireAuth(roomName) {
|
||||||
if (authRequiredDialog) {
|
if (authRequiredDialog) {
|
||||||
return;
|
return;
|
||||||
|
@ -101,6 +122,9 @@ function requireAuth(roomName) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close auth-related dialogs if there are any.
|
||||||
|
*/
|
||||||
function closeAuth() {
|
function closeAuth() {
|
||||||
if (externalAuthWindow) {
|
if (externalAuthWindow) {
|
||||||
externalAuthWindow.close();
|
externalAuthWindow.close();
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
var messageHandler = require('../util/MessageHandler');
|
var messageHandler = require('../util/MessageHandler');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build html for "password required" dialog.
|
||||||
|
* @returns {string} html string
|
||||||
|
*/
|
||||||
function getPasswordInputHtml() {
|
function getPasswordInputHtml() {
|
||||||
let placeholder = config.hosts.authdomain
|
let placeholder = config.hosts.authdomain
|
||||||
? "user identity"
|
? "user identity"
|
||||||
|
@ -13,11 +17,16 @@ function getPasswordInputHtml() {
|
||||||
<h2 data-i18n="dialog.passwordRequired">${passRequiredMsg}</h2>
|
<h2 data-i18n="dialog.passwordRequired">${passRequiredMsg}</h2>
|
||||||
<input name="username" type="text" placeholder=${placeholder} autofocus>
|
<input name="username" type="text" placeholder=${placeholder} autofocus>
|
||||||
<input name="password" type="password"
|
<input name="password" type="password"
|
||||||
data-i18n="[placeholder]dialog.userPassword"
|
data-i18n="[placeholder]dialog.userPassword"
|
||||||
placeholder="user password">
|
placeholder="user password">
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert provided id to jid if it's not jid yet.
|
||||||
|
* @param {string} id user id or jid
|
||||||
|
* @returns {string} jid
|
||||||
|
*/
|
||||||
function toJid(id) {
|
function toJid(id) {
|
||||||
if (id.indexOf("@") >= 0) {
|
if (id.indexOf("@") >= 0) {
|
||||||
return id;
|
return id;
|
||||||
|
@ -33,6 +42,10 @@ function toJid(id) {
|
||||||
return jid;
|
return jid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate cancel button config for the dialog.
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
function cancelButton() {
|
function cancelButton() {
|
||||||
return {
|
return {
|
||||||
title: APP.translation.generateTranslationHTML("dialog.Cancel"),
|
title: APP.translation.generateTranslationHTML("dialog.Cancel"),
|
||||||
|
@ -40,7 +53,18 @@ function cancelButton() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function Dialog(successCallback, cancelCallback) {
|
/**
|
||||||
|
* Auth dialog for JitsiConnection which supports retries.
|
||||||
|
* If no cancelCallback provided then there will be
|
||||||
|
* no cancel button on the dialog.
|
||||||
|
*
|
||||||
|
* @class LoginDialog
|
||||||
|
* @constructor
|
||||||
|
*
|
||||||
|
* @param {function(jid, password)} successCallback
|
||||||
|
* @param {function} [cancelCallback] callback to invoke if user canceled.
|
||||||
|
*/
|
||||||
|
function LoginDialog(successCallback, cancelCallback) {
|
||||||
let loginButtons = [{
|
let loginButtons = [{
|
||||||
title: APP.translation.generateTranslationHTML("dialog.Ok"),
|
title: APP.translation.generateTranslationHTML("dialog.Ok"),
|
||||||
value: true
|
value: true
|
||||||
|
@ -118,6 +142,10 @@ function Dialog(successCallback, cancelCallback) {
|
||||||
connDialog.goToState('finished');
|
connDialog.goToState('finished');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show message as connection status.
|
||||||
|
* @param {string} message
|
||||||
|
*/
|
||||||
this.displayConnectionStatus = function (message) {
|
this.displayConnectionStatus = function (message) {
|
||||||
let connectingState = connDialog.getState('connecting');
|
let connectingState = connDialog.getState('connecting');
|
||||||
|
|
||||||
|
@ -133,12 +161,26 @@ function Dialog(successCallback, cancelCallback) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoginDialog = {
|
export default {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show new auth dialog for JitsiConnection.
|
||||||
|
*
|
||||||
|
* @param {function(jid, password)} successCallback
|
||||||
|
* @param {function} [cancelCallback] callback to invoke if user canceled.
|
||||||
|
*
|
||||||
|
* @returns {LoginDialog}
|
||||||
|
*/
|
||||||
showAuthDialog: function (successCallback, cancelCallback) {
|
showAuthDialog: function (successCallback, cancelCallback) {
|
||||||
return new Dialog(successCallback, cancelCallback);
|
return new LoginDialog(successCallback, cancelCallback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show notification that external auth is required (using provided url).
|
||||||
|
* @param {string} url URL to use for external auth.
|
||||||
|
* @param {function} callback callback to invoke when auth popup is closed.
|
||||||
|
* @returns auth dialog
|
||||||
|
*/
|
||||||
showExternalAuthDialog: function (url, callback) {
|
showExternalAuthDialog: function (url, callback) {
|
||||||
var dialog = messageHandler.openCenteredPopup(
|
var dialog = messageHandler.openCenteredPopup(
|
||||||
url, 910, 660,
|
url, 910, 660,
|
||||||
|
@ -153,6 +195,14 @@ const LoginDialog = {
|
||||||
return dialog;
|
return dialog;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show notification that authentication is required
|
||||||
|
* to create the conference, so he should authenticate or wait for a host.
|
||||||
|
* @param {string} roomName name of the conference
|
||||||
|
* @param {function} onAuthNow callback to invoke if
|
||||||
|
* user want to authenticate.
|
||||||
|
* @returns dialog
|
||||||
|
*/
|
||||||
showAuthRequiredDialog: function (roomName, onAuthNow) {
|
showAuthRequiredDialog: function (roomName, onAuthNow) {
|
||||||
var title = APP.translation.generateTranslationHTML(
|
var title = APP.translation.generateTranslationHTML(
|
||||||
"dialog.WaitingForHost"
|
"dialog.WaitingForHost"
|
||||||
|
@ -184,5 +234,3 @@ const LoginDialog = {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LoginDialog;
|
|
||||||
|
|
|
@ -4,6 +4,10 @@ import UIUtil from '../util/UIUtil';
|
||||||
//FIXME:
|
//FIXME:
|
||||||
import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
|
import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show dialog which asks user for new password for the conference.
|
||||||
|
* @returns {Promise<string>} password or nothing if user canceled
|
||||||
|
*/
|
||||||
function askForNewPassword () {
|
function askForNewPassword () {
|
||||||
let passMsg = APP.translation.generateTranslationHTML("dialog.passwordMsg");
|
let passMsg = APP.translation.generateTranslationHTML("dialog.passwordMsg");
|
||||||
let yourPassMsg = APP.translation.translateString("dialog.yourPassword");
|
let yourPassMsg = APP.translation.translateString("dialog.yourPassword");
|
||||||
|
@ -30,6 +34,10 @@ function askForNewPassword () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show dialog which asks for required conference password.
|
||||||
|
* @returns {Promise<string>} password or nothing if user canceled
|
||||||
|
*/
|
||||||
function askForPassword () {
|
function askForPassword () {
|
||||||
let passRequiredMsg = APP.translation.translateString(
|
let passRequiredMsg = APP.translation.translateString(
|
||||||
"dialog.passwordRequired"
|
"dialog.passwordRequired"
|
||||||
|
@ -58,6 +66,10 @@ function askForPassword () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show dialog which asks if user want remove password from the conference.
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
function askToUnlock () {
|
function askToUnlock () {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
messageHandler.openTwoButtonDialog(
|
messageHandler.openTwoButtonDialog(
|
||||||
|
@ -74,18 +86,32 @@ function askToUnlock () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function notifyPasswordNotSupported (err) {
|
/**
|
||||||
console.warn('setting password failed', err);
|
* Show notification that user cannot set password for the conference
|
||||||
|
* because server doesn't support that.
|
||||||
|
*/
|
||||||
|
function notifyPasswordNotSupported () {
|
||||||
|
console.warn('room passwords not supported');
|
||||||
messageHandler.showError("dialog.warning", "dialog.passwordNotSupported");
|
messageHandler.showError("dialog.warning", "dialog.passwordNotSupported");
|
||||||
}
|
}
|
||||||
|
|
||||||
function notifyPasswordFailed() {
|
/**
|
||||||
console.warn('room passwords not supported');
|
* Show notification that setting password for the conference failed.
|
||||||
|
* @param {Error} err error
|
||||||
|
*/
|
||||||
|
function notifyPasswordFailed(err) {
|
||||||
|
console.warn('setting password failed', err);
|
||||||
messageHandler.showError("dialog.lockTitle", "dialog.lockMessage");
|
messageHandler.showError("dialog.lockTitle", "dialog.lockMessage");
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConferenceErrors = JitsiMeetJS.errors.conference;
|
const ConferenceErrors = JitsiMeetJS.errors.conference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new RoomLocker for the conference.
|
||||||
|
* It allows to set or remove password for the conference,
|
||||||
|
* or ask for required password.
|
||||||
|
* @returns {RoomLocker}
|
||||||
|
*/
|
||||||
export default function createRoomLocker (room) {
|
export default function createRoomLocker (room) {
|
||||||
let password;
|
let password;
|
||||||
|
|
||||||
|
@ -103,6 +129,9 @@ export default function createRoomLocker (room) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class RoomLocker
|
||||||
|
*/
|
||||||
return {
|
return {
|
||||||
get isLocked () {
|
get isLocked () {
|
||||||
return !!password;
|
return !!password;
|
||||||
|
@ -112,6 +141,10 @@ export default function createRoomLocker (room) {
|
||||||
return password;
|
return password;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to remove password from the conference (asks user first).
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
askToUnlock () {
|
askToUnlock () {
|
||||||
return askToUnlock().then(function () {
|
return askToUnlock().then(function () {
|
||||||
return lock();
|
return lock();
|
||||||
|
@ -120,6 +153,11 @@ export default function createRoomLocker (room) {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to set password for the conference.
|
||||||
|
* It asks user for new password and locks the room.
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
askToLock () {
|
askToLock () {
|
||||||
return askForNewPassword().then(function (newPass) {
|
return askForNewPassword().then(function (newPass) {
|
||||||
return lock(newPass);
|
return lock(newPass);
|
||||||
|
@ -128,12 +166,18 @@ export default function createRoomLocker (room) {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks user for required conference password.
|
||||||
|
*/
|
||||||
requirePassword () {
|
requirePassword () {
|
||||||
return askForPassword().then(function (newPass) {
|
return askForPassword().then(function (newPass) {
|
||||||
password = newPass;
|
password = newPass;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show notification that to set/remove password user must be moderator.
|
||||||
|
*/
|
||||||
notifyModeratorRequired () {
|
notifyModeratorRequired () {
|
||||||
if (password) {
|
if (password) {
|
||||||
messageHandler.openMessageDialog(null, "dialog.passwordError");
|
messageHandler.openMessageDialog(null, "dialog.passwordError");
|
||||||
|
|
|
@ -6,6 +6,9 @@ import UIUtil from "../util/UIUtil";
|
||||||
import SidePanelToggler from "../side_pannels/SidePanelToggler";
|
import SidePanelToggler from "../side_pannels/SidePanelToggler";
|
||||||
import BottomToolbar from '../toolbars/BottomToolbar';
|
import BottomToolbar from '../toolbars/BottomToolbar';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Etherpad options.
|
||||||
|
*/
|
||||||
const options = $.param({
|
const options = $.param({
|
||||||
showControns: true,
|
showControns: true,
|
||||||
showChat: false,
|
showChat: false,
|
||||||
|
@ -40,11 +43,20 @@ function bubbleIframeMouseMove(iframe){
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Etherpad frame width.
|
||||||
|
*/
|
||||||
const DEFAULT_WIDTH = 640;
|
const DEFAULT_WIDTH = 640;
|
||||||
|
/**
|
||||||
|
* Default Etherpad frame height.
|
||||||
|
*/
|
||||||
const DEFAULT_HEIGHT = 480;
|
const DEFAULT_HEIGHT = 480;
|
||||||
|
|
||||||
const EtherpadContainerType = "etherpad";
|
const EtherpadContainerType = "etherpad";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for Etherpad iframe.
|
||||||
|
*/
|
||||||
class Etherpad extends LargeContainer {
|
class Etherpad extends LargeContainer {
|
||||||
constructor (domain, name) {
|
constructor (domain, name) {
|
||||||
super();
|
super();
|
||||||
|
@ -123,6 +135,9 @@ class Etherpad extends LargeContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager of the Etherpad frame.
|
||||||
|
*/
|
||||||
export default class EtherpadManager {
|
export default class EtherpadManager {
|
||||||
constructor (domain, name) {
|
constructor (domain, name) {
|
||||||
if (!domain || !name) {
|
if (!domain || !name) {
|
||||||
|
@ -138,6 +153,9 @@ export default class EtherpadManager {
|
||||||
return !!this.etherpad;
|
return !!this.etherpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new Etherpad frame.
|
||||||
|
*/
|
||||||
openEtherpad () {
|
openEtherpad () {
|
||||||
this.etherpad = new Etherpad(this.domain, this.name);
|
this.etherpad = new Etherpad(this.domain, this.name);
|
||||||
VideoLayout.addLargeVideoContainer(
|
VideoLayout.addLargeVideoContainer(
|
||||||
|
@ -146,6 +164,10 @@ export default class EtherpadManager {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle Etherpad frame visibility.
|
||||||
|
* Open new Etherpad frame if there is no Etherpad frame yet.
|
||||||
|
*/
|
||||||
toggleEtherpad () {
|
toggleEtherpad () {
|
||||||
if (!this.isOpen) {
|
if (!this.isOpen) {
|
||||||
this.openEtherpad();
|
this.openEtherpad();
|
||||||
|
|
|
@ -11,17 +11,31 @@ import ToolbarToggler from "../toolbars/ToolbarToggler";
|
||||||
import SidePanelToggler from "../side_pannels/SidePanelToggler";
|
import SidePanelToggler from "../side_pannels/SidePanelToggler";
|
||||||
import BottomToolbar from '../toolbars/BottomToolbar';
|
import BottomToolbar from '../toolbars/BottomToolbar';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example of Prezi link.
|
||||||
|
*/
|
||||||
const defaultPreziLink = "http://prezi.com/wz7vhjycl7e6/my-prezi";
|
const defaultPreziLink = "http://prezi.com/wz7vhjycl7e6/my-prezi";
|
||||||
const alphanumRegex = /^[a-z0-9-_\/&\?=;]+$/i;
|
const alphanumRegex = /^[a-z0-9-_\/&\?=;]+$/i;
|
||||||
|
/**
|
||||||
|
* Default aspect ratio for Prezi frame.
|
||||||
|
*/
|
||||||
const aspectRatio = 16.0 / 9.0;
|
const aspectRatio = 16.0 / 9.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Prezi frame width.
|
||||||
|
*/
|
||||||
const DEFAULT_WIDTH = 640;
|
const DEFAULT_WIDTH = 640;
|
||||||
|
/**
|
||||||
|
* Default Prezi frame height.
|
||||||
|
*/
|
||||||
const DEFAULT_HEIGHT = 480;
|
const DEFAULT_HEIGHT = 480;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the given string is an alphanumeric string.
|
* Indicates if the given string is an alphanumeric string.
|
||||||
* Note that some special characters are also allowed (-, _ , /, &, ?, =, ;) for the
|
* Note that some special characters are also allowed (-, _ , /, &, ?, =, ;) for the
|
||||||
* purpose of checking URIs.
|
* purpose of checking URIs.
|
||||||
|
* @param {string} unsafeText string to check
|
||||||
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
function isAlphanumeric(unsafeText) {
|
function isAlphanumeric(unsafeText) {
|
||||||
return alphanumRegex.test(unsafeText);
|
return alphanumRegex.test(unsafeText);
|
||||||
|
@ -29,12 +43,19 @@ function isAlphanumeric(unsafeText) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the presentation id from the given url.
|
* Returns the presentation id from the given url.
|
||||||
|
* @param {string} url Prezi link
|
||||||
|
* @returns {string} presentation id
|
||||||
*/
|
*/
|
||||||
function getPresentationId (url) {
|
function getPresentationId (url) {
|
||||||
let presId = url.substring(url.indexOf("prezi.com/") + 10);
|
let presId = url.substring(url.indexOf("prezi.com/") + 10);
|
||||||
return presId.substring(0, presId.indexOf('/'));
|
return presId.substring(0, presId.indexOf('/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if given string is Prezi url.
|
||||||
|
* @param {string} url string to check.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
function isPreziLink(url) {
|
function isPreziLink(url) {
|
||||||
if (url.indexOf('http://prezi.com/') !== 0 && url.indexOf('https://prezi.com/') !== 0) {
|
if (url.indexOf('http://prezi.com/') !== 0 && url.indexOf('https://prezi.com/') !== 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -48,6 +69,9 @@ function isPreziLink(url) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify user that other user if already sharing Prezi.
|
||||||
|
*/
|
||||||
function notifyOtherIsSharingPrezi() {
|
function notifyOtherIsSharingPrezi() {
|
||||||
messageHandler.openMessageDialog(
|
messageHandler.openMessageDialog(
|
||||||
"dialog.sharePreziTitle",
|
"dialog.sharePreziTitle",
|
||||||
|
@ -55,6 +79,9 @@ function notifyOtherIsSharingPrezi() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask user if he want to close Prezi he's sharing.
|
||||||
|
*/
|
||||||
function proposeToClosePrezi() {
|
function proposeToClosePrezi() {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
messageHandler.openTwoButtonDialog(
|
messageHandler.openTwoButtonDialog(
|
||||||
|
@ -76,6 +103,10 @@ function proposeToClosePrezi() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask user for Prezi url to share with others.
|
||||||
|
* Dialog validates client input to allow only Prezi urls.
|
||||||
|
*/
|
||||||
function requestPreziLink() {
|
function requestPreziLink() {
|
||||||
const title = APP.translation.generateTranslationHTML("dialog.sharePreziTitle");
|
const title = APP.translation.generateTranslationHTML("dialog.sharePreziTitle");
|
||||||
const cancelButton = APP.translation.generateTranslationHTML("dialog.Cancel");
|
const cancelButton = APP.translation.generateTranslationHTML("dialog.Cancel");
|
||||||
|
@ -154,6 +185,9 @@ function requestPreziLink() {
|
||||||
|
|
||||||
export const PreziContainerType = "prezi";
|
export const PreziContainerType = "prezi";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for Prezi iframe.
|
||||||
|
*/
|
||||||
class PreziContainer extends LargeContainer {
|
class PreziContainer extends LargeContainer {
|
||||||
|
|
||||||
constructor ({preziId, isMy, slide, onSlideChanged}) {
|
constructor ({preziId, isMy, slide, onSlideChanged}) {
|
||||||
|
@ -187,6 +221,10 @@ class PreziContainer extends LargeContainer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change Prezi slide.
|
||||||
|
* @param {number} slide slide to show
|
||||||
|
*/
|
||||||
goToSlide (slide) {
|
goToSlide (slide) {
|
||||||
if (this.preziPlayer.getCurrentStep() === slide) {
|
if (this.preziPlayer.getCurrentStep() === slide) {
|
||||||
return;
|
return;
|
||||||
|
@ -204,6 +242,10 @@ class PreziContainer extends LargeContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show or hide "reload presentation" button.
|
||||||
|
* @param {boolean} show
|
||||||
|
*/
|
||||||
showReloadBtn (show) {
|
showReloadBtn (show) {
|
||||||
this.reloadBtn.css('display', show ? 'inline-block' : 'none');
|
this.reloadBtn.css('display', show ? 'inline-block' : 'none');
|
||||||
}
|
}
|
||||||
|
@ -256,6 +298,9 @@ class PreziContainer extends LargeContainer {
|
||||||
this.$iframe.width(width).height(height);
|
this.$iframe.width(width).height(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Prezi frame.
|
||||||
|
*/
|
||||||
close () {
|
close () {
|
||||||
this.showReloadBtn(false);
|
this.showReloadBtn(false);
|
||||||
this.preziPlayer.destroy();
|
this.preziPlayer.destroy();
|
||||||
|
@ -263,6 +308,9 @@ class PreziContainer extends LargeContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager of Prezi frames.
|
||||||
|
*/
|
||||||
export default class PreziManager {
|
export default class PreziManager {
|
||||||
constructor (emitter) {
|
constructor (emitter) {
|
||||||
this.emitter = emitter;
|
this.emitter = emitter;
|
||||||
|
@ -282,6 +330,10 @@ export default class PreziManager {
|
||||||
return this.userId === APP.conference.localId;
|
return this.userId === APP.conference.localId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user is currently sharing.
|
||||||
|
* @param {string} id user id to check for
|
||||||
|
*/
|
||||||
isSharing (id) {
|
isSharing (id) {
|
||||||
return this.userId === id;
|
return this.userId === id;
|
||||||
}
|
}
|
||||||
|
@ -302,6 +354,9 @@ export default class PreziManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload current Prezi frame.
|
||||||
|
*/
|
||||||
reloadPresentation () {
|
reloadPresentation () {
|
||||||
if (!this.prezi) {
|
if (!this.prezi) {
|
||||||
return;
|
return;
|
||||||
|
@ -310,6 +365,12 @@ export default class PreziManager {
|
||||||
iframe.src = iframe.src;
|
iframe.src = iframe.src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Prezi. Create new Prezi if there is no Prezi yet.
|
||||||
|
* @param {string} id owner id
|
||||||
|
* @param {string} url Prezi url
|
||||||
|
* @param {number} slide slide to show
|
||||||
|
*/
|
||||||
showPrezi (id, url, slide) {
|
showPrezi (id, url, slide) {
|
||||||
if (!this.isPresenting) {
|
if (!this.isPresenting) {
|
||||||
this.createPrezi(id, url, slide);
|
this.createPrezi(id, url, slide);
|
||||||
|
@ -324,6 +385,12 @@ export default class PreziManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new Prezi frame..
|
||||||
|
* @param {string} id owner id
|
||||||
|
* @param {string} url Prezi url
|
||||||
|
* @param {number} slide slide to show
|
||||||
|
*/
|
||||||
createPrezi (id, url, slide) {
|
createPrezi (id, url, slide) {
|
||||||
console.log("presentation added", url);
|
console.log("presentation added", url);
|
||||||
|
|
||||||
|
@ -354,6 +421,10 @@ export default class PreziManager {
|
||||||
VideoLayout.showLargeVideoContainer(PreziContainerType, true);
|
VideoLayout.showLargeVideoContainer(PreziContainerType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Prezi.
|
||||||
|
* @param {string} id owner id
|
||||||
|
*/
|
||||||
removePrezi (id) {
|
removePrezi (id) {
|
||||||
if (this.userId !== id) {
|
if (this.userId !== id) {
|
||||||
throw new Error(`cannot close presentation from ${this.userId} instead of ${id}`);
|
throw new Error(`cannot close presentation from ${this.userId} instead of ${id}`);
|
||||||
|
|
|
@ -1,24 +1,41 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all Large containers which we can show.
|
||||||
|
*/
|
||||||
export default class LargeContainer {
|
export default class LargeContainer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Show this container.
|
||||||
* @returns Promise
|
* @returns Promise
|
||||||
*/
|
*/
|
||||||
show () {
|
show () {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Hide this container.
|
||||||
* @returns Promise
|
* @returns Promise
|
||||||
*/
|
*/
|
||||||
hide () {
|
hide () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize this container.
|
||||||
|
* @param {number} containerWidth available width
|
||||||
|
* @param {number} containerHeight available height
|
||||||
|
* @param {boolean} animate if container should animate it's resize process
|
||||||
|
*/
|
||||||
resize (containerWidth, containerHeight, animate) {
|
resize (containerWidth, containerHeight, animate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for "hover in" events.
|
||||||
|
*/
|
||||||
onHoverIn (e) {
|
onHoverIn (e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for "hover out" events.
|
||||||
|
*/
|
||||||
onHoverOut (e) {
|
onHoverOut (e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,10 @@ const RTCBrowserType = require("../../RTC/RTCBrowserType");
|
||||||
|
|
||||||
const avatarSize = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE;
|
const avatarSize = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get stream id.
|
||||||
|
* @param {JitsiTrack?} stream
|
||||||
|
*/
|
||||||
function getStreamId(stream) {
|
function getStreamId(stream) {
|
||||||
if(!stream)
|
if(!stream)
|
||||||
return;
|
return;
|
||||||
|
@ -147,6 +151,9 @@ function getDesktopVideoPosition(videoWidth,
|
||||||
|
|
||||||
export const VideoContainerType = "video";
|
export const VideoContainerType = "video";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for user video.
|
||||||
|
*/
|
||||||
class VideoContainer extends LargeContainer {
|
class VideoContainer extends LargeContainer {
|
||||||
// FIXME: With Temasys we have to re-select everytime
|
// FIXME: With Temasys we have to re-select everytime
|
||||||
get $video () {
|
get $video () {
|
||||||
|
@ -174,6 +181,10 @@ class VideoContainer extends LargeContainer {
|
||||||
this.$video.on('play', onPlay);
|
this.$video.on('play', onPlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get size of video element.
|
||||||
|
* @returns {{width, height}}
|
||||||
|
*/
|
||||||
getStreamSize () {
|
getStreamSize () {
|
||||||
let video = this.$video[0];
|
let video = this.$video[0];
|
||||||
return {
|
return {
|
||||||
|
@ -182,6 +193,12 @@ class VideoContainer extends LargeContainer {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate optimal video size for specified container size.
|
||||||
|
* @param {number} containerWidth container width
|
||||||
|
* @param {number} containerHeight container height
|
||||||
|
* @returns {{availableWidth, availableHeight}}
|
||||||
|
*/
|
||||||
getVideoSize (containerWidth, containerHeight) {
|
getVideoSize (containerWidth, containerHeight) {
|
||||||
let { width, height } = this.getStreamSize();
|
let { width, height } = this.getStreamSize();
|
||||||
if (this.stream && this.isScreenSharing()) {
|
if (this.stream && this.isScreenSharing()) {
|
||||||
|
@ -197,6 +214,15 @@ class VideoContainer extends LargeContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate optimal video position (offset for top left corner)
|
||||||
|
* for specified video size and container size.
|
||||||
|
* @param {number} width video width
|
||||||
|
* @param {number} height video height
|
||||||
|
* @param {number} containerWidth container width
|
||||||
|
* @param {number} containerHeight container height
|
||||||
|
* @returns {{horizontalIndent, verticalIndent}}
|
||||||
|
*/
|
||||||
getVideoPosition (width, height, containerWidth, containerHeight) {
|
getVideoPosition (width, height, containerWidth, containerHeight) {
|
||||||
if (this.stream && this.isScreenSharing()) {
|
if (this.stream && this.isScreenSharing()) {
|
||||||
return getDesktopVideoPosition( width,
|
return getDesktopVideoPosition( width,
|
||||||
|
@ -238,6 +264,11 @@ class VideoContainer extends LargeContainer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update video stream.
|
||||||
|
* @param {JitsiTrack?} stream new stream
|
||||||
|
* @param {string} videoType video type
|
||||||
|
*/
|
||||||
setStream (stream, videoType) {
|
setStream (stream, videoType) {
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.videoType = videoType;
|
this.videoType = videoType;
|
||||||
|
@ -250,10 +281,18 @@ class VideoContainer extends LargeContainer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if current video stream is screen sharing.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
isScreenSharing () {
|
isScreenSharing () {
|
||||||
return this.videoType === 'desktop';
|
return this.videoType === 'desktop';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show or hide user avatar.
|
||||||
|
* @param {boolean} show
|
||||||
|
*/
|
||||||
showAvatar (show) {
|
showAvatar (show) {
|
||||||
this.$avatar.css("visibility", show ? "visible" : "hidden");
|
this.$avatar.css("visibility", show ? "visible" : "hidden");
|
||||||
}
|
}
|
||||||
|
@ -289,7 +328,9 @@ class VideoContainer extends LargeContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager for all Large containers.
|
||||||
|
*/
|
||||||
export default class LargeVideoManager {
|
export default class LargeVideoManager {
|
||||||
constructor () {
|
constructor () {
|
||||||
this.containers = {};
|
this.containers = {};
|
||||||
|
@ -356,6 +397,13 @@ export default class LargeVideoManager {
|
||||||
return this.videoContainer.id;
|
return this.videoContainer.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update large video.
|
||||||
|
* Switches to large video even if previously other container was visible.
|
||||||
|
* @param {JitsiTrack?} stream new stream
|
||||||
|
* @param {string?} videoType new video type
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
updateLargeVideo (smallVideo, videoType, largeVideoUpdatedCallBack) {
|
updateLargeVideo (smallVideo, videoType, largeVideoUpdatedCallBack) {
|
||||||
let id = getStreamId(smallVideo.stream);
|
let id = getStreamId(smallVideo.stream);
|
||||||
|
|
||||||
|
@ -380,16 +428,29 @@ export default class LargeVideoManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update container size optionally taking side bar size into account.
|
||||||
|
* @param {boolean} isSideBarVisible if side bar is visible.
|
||||||
|
*/
|
||||||
updateContainerSize (isSideBarVisible) {
|
updateContainerSize (isSideBarVisible) {
|
||||||
this.width = UIUtil.getAvailableVideoWidth(isSideBarVisible);
|
this.width = UIUtil.getAvailableVideoWidth(isSideBarVisible);
|
||||||
this.height = window.innerHeight;
|
this.height = window.innerHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize Large container of specified type.
|
||||||
|
* @param {string} type type of container which should be resized.
|
||||||
|
* @param {boolean} [animate=false] if resize process should be animated.
|
||||||
|
*/
|
||||||
resizeContainer (type, animate = false) {
|
resizeContainer (type, animate = false) {
|
||||||
let container = this.getContainer(type);
|
let container = this.getContainer(type);
|
||||||
container.resize(this.width, this.height, animate);
|
container.resize(this.width, this.height, animate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize all Large containers.
|
||||||
|
* @param {boolean} animate if resize process should be animated.
|
||||||
|
*/
|
||||||
resize (animate) {
|
resize (animate) {
|
||||||
// resize all containers
|
// resize all containers
|
||||||
Object.keys(this.containers)
|
Object.keys(this.containers)
|
||||||
|
@ -420,11 +481,20 @@ export default class LargeVideoManager {
|
||||||
$("#dominantSpeakerAvatar").attr('src', avatarUrl);
|
$("#dominantSpeakerAvatar").attr('src', avatarUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show avatar on Large video container or not.
|
||||||
|
* @param {boolean} show
|
||||||
|
*/
|
||||||
showAvatar (show) {
|
showAvatar (show) {
|
||||||
show ? this.videoContainer.hide() : this.videoContainer.show();
|
show ? this.videoContainer.hide() : this.videoContainer.show();
|
||||||
this.videoContainer.showAvatar(show);
|
this.videoContainer.showAvatar(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add container of specified type.
|
||||||
|
* @param {string} type container type
|
||||||
|
* @param {LargeContainer} container container to add.
|
||||||
|
*/
|
||||||
addContainer (type, container) {
|
addContainer (type, container) {
|
||||||
if (this.containers[type]) {
|
if (this.containers[type]) {
|
||||||
throw new Error(`container of type ${type} already exist`);
|
throw new Error(`container of type ${type} already exist`);
|
||||||
|
@ -434,6 +504,11 @@ export default class LargeVideoManager {
|
||||||
this.resizeContainer(type);
|
this.resizeContainer(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Large container of specified type.
|
||||||
|
* @param {string} type container type.
|
||||||
|
* @returns {LargeContainer}
|
||||||
|
*/
|
||||||
getContainer (type) {
|
getContainer (type) {
|
||||||
let container = this.containers[type];
|
let container = this.containers[type];
|
||||||
|
|
||||||
|
@ -444,6 +519,10 @@ export default class LargeVideoManager {
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove Large container of specified type.
|
||||||
|
* @param {string} type container type.
|
||||||
|
*/
|
||||||
removeContainer (type) {
|
removeContainer (type) {
|
||||||
if (!this.containers[type]) {
|
if (!this.containers[type]) {
|
||||||
throw new Error(`container of type ${type} doesn't exist`);
|
throw new Error(`container of type ${type} doesn't exist`);
|
||||||
|
@ -452,6 +531,12 @@ export default class LargeVideoManager {
|
||||||
delete this.containers[type];
|
delete this.containers[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Large container of specified type.
|
||||||
|
* Does nothing if such container is already visible.
|
||||||
|
* @param {string} type container type.
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
showContainer (type) {
|
showContainer (type) {
|
||||||
if (this.state === type) {
|
if (this.state === type) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
|
|
@ -997,7 +997,7 @@ var VideoLayout = {
|
||||||
// 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();
|
||||||
});
|
});
|
||||||
|
|
||||||
} else if (currentId) {
|
} else if (currentId) {
|
||||||
let currentSmallVideo = this.getSmallVideo(currentId);
|
let currentSmallVideo = this.getSmallVideo(currentId);
|
||||||
|
|
Loading…
Reference in New Issue