Creates UI module.
This commit is contained in:
parent
4a991f7187
commit
69b0e2ad32
4
Makefile
4
Makefile
|
@ -20,3 +20,7 @@ clean:
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
@mkdir -p $(DEPLOY_DIR) && cp $(OUTPUT_DIR)/*.bundle.js $(DEPLOY_DIR)
|
@mkdir -p $(DEPLOY_DIR) && cp $(OUTPUT_DIR)/*.bundle.js $(DEPLOY_DIR)
|
||||||
|
scp $(DEPLOY_DIR)/*.bundle.js hristo.jitsi.net:/srv/web/hristo.jitsi.net/$(DEPLOY_DIR)
|
||||||
|
|
||||||
|
dd: debug deploy
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ var APIConnector = (function () {
|
||||||
*/
|
*/
|
||||||
var commands =
|
var commands =
|
||||||
{
|
{
|
||||||
displayName: VideoLayout.inputDisplayNameHandler,
|
displayName: UI.inputDisplayNameHandler,
|
||||||
muteAudio: toggleAudio,
|
muteAudio: toggleAudio,
|
||||||
muteVideo: toggleVideo,
|
muteVideo: toggleVideo,
|
||||||
toggleFilmStrip: BottomToolbar.toggleFilmStrip,
|
toggleFilmStrip: UI.toggleFilmStrip,
|
||||||
toggleChat: BottomToolbar.toggleChat,
|
toggleChat: UI.toggleChat,
|
||||||
toggleContactList: BottomToolbar.toggleContactList
|
toggleContactList: UI.toggleContactList
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
632
app.js
632
app.js
|
@ -2,12 +2,9 @@
|
||||||
/* application specific logic */
|
/* application specific logic */
|
||||||
var connection = null;
|
var connection = null;
|
||||||
var authenticatedUser = false;
|
var authenticatedUser = false;
|
||||||
var authenticationWindow = null;
|
|
||||||
var activecall = null;
|
var activecall = null;
|
||||||
var nickname = null;
|
var nickname = null;
|
||||||
var sharedKey = '';
|
|
||||||
var focusMucJid = null;
|
var focusMucJid = null;
|
||||||
var roomUrl = null;
|
|
||||||
var roomName = null;
|
var roomName = null;
|
||||||
var ssrc2jid = {};
|
var ssrc2jid = {};
|
||||||
var bridgeIsDown = false;
|
var bridgeIsDown = false;
|
||||||
|
@ -59,10 +56,8 @@ var getVideoPosition;
|
||||||
var sessionTerminated = false;
|
var sessionTerminated = false;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
Toolbar.setupButtonsFromConfig();
|
|
||||||
|
|
||||||
RTC.addStreamListener(maybeDoJoin, StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
|
RTC.addStreamListener(maybeDoJoin, StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
|
||||||
RTC.addStreamListener(VideoLayout.onLocalStreamCreated, StreamEventTypes.EVENT_TYPE_LOCAL_CREATED)
|
|
||||||
RTC.start();
|
RTC.start();
|
||||||
|
|
||||||
var jid = document.getElementById('jid').value || config.hosts.anonymousdomain || config.hosts.domain || window.location.hostname;
|
var jid = document.getElementById('jid').value || config.hosts.anonymousdomain || config.hosts.domain || window.location.hostname;
|
||||||
|
@ -77,12 +72,13 @@ function connect(jid, password) {
|
||||||
}
|
}
|
||||||
connection = new Strophe.Connection(document.getElementById('boshURL').value || config.bosh || '/http-bind');
|
connection = new Strophe.Connection(document.getElementById('boshURL').value || config.bosh || '/http-bind');
|
||||||
|
|
||||||
var email = SettingsMenu.getEmail();
|
var settings = UI.getSettings();
|
||||||
var displayName = SettingsMenu.getDisplayName();
|
var email = settings.email;
|
||||||
|
var displayName = settings.displayName;
|
||||||
if(email) {
|
if(email) {
|
||||||
connection.emuc.addEmailToPresence(email);
|
connection.emuc.addEmailToPresence(email);
|
||||||
} else {
|
} else {
|
||||||
connection.emuc.addUserIdToPresence(SettingsMenu.getUID());
|
connection.emuc.addUserIdToPresence(settings.uid);
|
||||||
}
|
}
|
||||||
if(displayName) {
|
if(displayName) {
|
||||||
connection.emuc.addDisplayNameToPresence(displayName);
|
connection.emuc.addDisplayNameToPresence(displayName);
|
||||||
|
@ -143,41 +139,9 @@ function maybeDoJoin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateRoomName() {
|
|
||||||
var roomnode = null;
|
|
||||||
var path = window.location.pathname;
|
|
||||||
|
|
||||||
// determinde the room node from the url
|
|
||||||
// TODO: just the roomnode or the whole bare jid?
|
|
||||||
if (config.getroomnode && typeof config.getroomnode === 'function') {
|
|
||||||
// custom function might be responsible for doing the pushstate
|
|
||||||
roomnode = config.getroomnode(path);
|
|
||||||
} else {
|
|
||||||
/* fall back to default strategy
|
|
||||||
* this is making assumptions about how the URL->room mapping happens.
|
|
||||||
* It currently assumes deployment at root, with a rewrite like the
|
|
||||||
* following one (for nginx):
|
|
||||||
location ~ ^/([a-zA-Z0-9]+)$ {
|
|
||||||
rewrite ^/(.*)$ / break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (path.length > 1) {
|
|
||||||
roomnode = path.substr(1).toLowerCase();
|
|
||||||
} else {
|
|
||||||
var word = RoomNameGenerator.generateRoomWithoutSeparator();
|
|
||||||
roomnode = word.toLowerCase();
|
|
||||||
|
|
||||||
window.history.pushState('VideoChat',
|
|
||||||
'Room: ' + word, window.location.pathname + word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
roomName = roomnode + '@' + config.hosts.muc;
|
|
||||||
}
|
|
||||||
|
|
||||||
function doJoin() {
|
function doJoin() {
|
||||||
if (!roomName) {
|
if (!roomName) {
|
||||||
generateRoomName();
|
UI.generateRoomName();
|
||||||
}
|
}
|
||||||
|
|
||||||
Moderator.allocateConferenceFocus(
|
Moderator.allocateConferenceFocus(
|
||||||
|
@ -244,7 +208,6 @@ function waitForRemoteVideo(selector, ssrc, stream, jid) {
|
||||||
jid2Ssrc[Strophe.getResourceFromJid(jid)] = ssrc;
|
jid2Ssrc[Strophe.getResourceFromJid(jid)] = ssrc;
|
||||||
} else {
|
} else {
|
||||||
console.warn("No ssrc given for jid", jid);
|
console.warn("No ssrc given for jid", jid);
|
||||||
// messageHandler.showError('Warning', 'No ssrc was given for the video.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).trigger('videoactive.jingle', [selector]);
|
$(document).trigger('videoactive.jingle', [selector]);
|
||||||
|
@ -328,43 +291,7 @@ function waitForPresence(data, sid) {
|
||||||
|
|
||||||
RTC.createRemoteStream(data, sid, thessrc);
|
RTC.createRemoteStream(data, sid, thessrc);
|
||||||
|
|
||||||
var container;
|
|
||||||
var remotes = document.getElementById('remoteVideos');
|
|
||||||
|
|
||||||
if (data.peerjid) {
|
|
||||||
VideoLayout.ensurePeerContainerExists(data.peerjid);
|
|
||||||
|
|
||||||
container = document.getElementById(
|
|
||||||
'participant_' + Strophe.getResourceFromJid(data.peerjid));
|
|
||||||
} else {
|
|
||||||
if (data.stream.id !== 'mixedmslabel'
|
|
||||||
// FIXME: default stream is added always with new focus
|
|
||||||
// (to be investigated)
|
|
||||||
&& data.stream.id !== 'default') {
|
|
||||||
console.error('can not associate stream',
|
|
||||||
data.stream.id,
|
|
||||||
'with a participant');
|
|
||||||
// We don't want to add it here since it will cause troubles
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// FIXME: for the mixed ms we dont need a video -- currently
|
|
||||||
container = document.createElement('span');
|
|
||||||
container.id = 'mixedstream';
|
|
||||||
container.className = 'videocontainer';
|
|
||||||
remotes.appendChild(container);
|
|
||||||
Util.playSoundNotification('userJoined');
|
|
||||||
}
|
|
||||||
|
|
||||||
var isVideo = data.stream.getVideoTracks().length > 0;
|
var isVideo = data.stream.getVideoTracks().length > 0;
|
||||||
|
|
||||||
if (container) {
|
|
||||||
VideoLayout.addRemoteStreamElement( container,
|
|
||||||
sid,
|
|
||||||
data.stream,
|
|
||||||
data.peerjid,
|
|
||||||
thessrc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// an attempt to work around https://github.com/jitsi/jitmeet/issues/32
|
// an attempt to work around https://github.com/jitsi/jitmeet/issues/32
|
||||||
if (isVideo &&
|
if (isVideo &&
|
||||||
data.peerjid && sess.peerjid === data.peerjid &&
|
data.peerjid && sess.peerjid === data.peerjid &&
|
||||||
|
@ -393,19 +320,19 @@ function sendKeyframe(pc) {
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.log('triggerKeyframe setLocalDescription failed', error);
|
console.log('triggerKeyframe setLocalDescription failed', error);
|
||||||
messageHandler.showError();
|
UI.messageHandler.showError();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.log('triggerKeyframe createAnswer failed', error);
|
console.log('triggerKeyframe createAnswer failed', error);
|
||||||
messageHandler.showError();
|
UI.messageHandler.showError();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.log('triggerKeyframe setRemoteDescription failed', error);
|
console.log('triggerKeyframe setRemoteDescription failed', error);
|
||||||
messageHandler.showError();
|
UI.messageHandler.showError();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -433,7 +360,7 @@ function muteVideo(pc, unmute) {
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.log('mute SLD error');
|
console.log('mute SLD error');
|
||||||
messageHandler.showError('Error',
|
UI.messageHandler.showError('Error',
|
||||||
'Oops! Something went wrong and we failed to ' +
|
'Oops! Something went wrong and we failed to ' +
|
||||||
'mute! (SLD Failure)');
|
'mute! (SLD Failure)');
|
||||||
}
|
}
|
||||||
|
@ -441,13 +368,13 @@ function muteVideo(pc, unmute) {
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
messageHandler.showError();
|
UI.messageHandler.showError();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.log('muteVideo SRD error');
|
console.log('muteVideo SRD error');
|
||||||
messageHandler.showError('Error',
|
UI.messageHandler.showError('Error',
|
||||||
'Oops! Something went wrong and we failed to stop video!' +
|
'Oops! Something went wrong and we failed to stop video!' +
|
||||||
'(SRD Failure)');
|
'(SRD Failure)');
|
||||||
|
|
||||||
|
@ -455,53 +382,6 @@ function muteVideo(pc, unmute) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for audio levels changed.
|
|
||||||
* @param jid JID of the user
|
|
||||||
* @param audioLevel the audio level value
|
|
||||||
*/
|
|
||||||
function audioLevelUpdated(jid, audioLevel)
|
|
||||||
{
|
|
||||||
var resourceJid;
|
|
||||||
if(jid === statistics.LOCAL_JID)
|
|
||||||
{
|
|
||||||
resourceJid = AudioLevels.LOCAL_LEVEL;
|
|
||||||
if(isAudioMuted())
|
|
||||||
{
|
|
||||||
audioLevel = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resourceJid = Strophe.getResourceFromJid(jid);
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioLevels.updateAudioLevel(resourceJid, audioLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).bind('callincoming.jingle', function (event, sid) {
|
|
||||||
var sess = connection.jingle.sessions[sid];
|
|
||||||
|
|
||||||
// TODO: do we check activecall == null?
|
|
||||||
activecall = sess;
|
|
||||||
|
|
||||||
statistics.onConferenceCreated(sess);
|
|
||||||
RTC.onConferenceCreated(sess);
|
|
||||||
|
|
||||||
// TODO: check affiliation and/or role
|
|
||||||
console.log('emuc data for', sess.peerjid, connection.emuc.members[sess.peerjid]);
|
|
||||||
sess.usedrip = true; // not-so-naive trickle ice
|
|
||||||
sess.sendAnswer();
|
|
||||||
sess.accept();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('conferenceCreated.jingle', function (event, focus)
|
|
||||||
{
|
|
||||||
statistics.onConfereceCreated(getConferenceHandler());
|
|
||||||
RTC.onConfereceCreated(focus);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('setLocalDescription.jingle', function (event, sid) {
|
$(document).bind('setLocalDescription.jingle', function (event, sid) {
|
||||||
// put our ssrcs into presence so other clients can identify our stream
|
// put our ssrcs into presence so other clients can identify our stream
|
||||||
var sess = connection.jingle.sessions[sid];
|
var sess = connection.jingle.sessions[sid];
|
||||||
|
@ -585,115 +465,7 @@ $(document).bind('iceconnectionstatechange.jingle', function (event, sid, sessio
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).bind('joined.muc', function (event, jid, info) {
|
$(document).bind('joined.muc', function (event, jid, info) {
|
||||||
updateRoomUrl(window.location.href);
|
|
||||||
document.getElementById('localNick').appendChild(
|
|
||||||
document.createTextNode(Strophe.getResourceFromJid(jid) + ' (me)')
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add myself to the contact list.
|
|
||||||
ContactList.addContact(jid, SettingsMenu.getEmail() || SettingsMenu.getUID());
|
|
||||||
|
|
||||||
// Once we've joined the muc show the toolbar
|
|
||||||
ToolbarToggler.showToolbar();
|
|
||||||
|
|
||||||
// Show authenticate button if needed
|
|
||||||
Toolbar.showAuthenticateButton(
|
|
||||||
Moderator.isExternalAuthEnabled() && !Moderator.isModerator());
|
|
||||||
|
|
||||||
var displayName = !config.displayJids
|
|
||||||
? info.displayName : Strophe.getResourceFromJid(jid);
|
|
||||||
|
|
||||||
if (displayName)
|
|
||||||
$(document).trigger('displaynamechanged',
|
|
||||||
['localVideoContainer', displayName + ' (me)']);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('entered.muc', function (event, jid, info, pres) {
|
|
||||||
console.log('entered', jid, info);
|
|
||||||
if (info.isFocus)
|
|
||||||
{
|
|
||||||
focusMucJid = jid;
|
|
||||||
console.info("Ignore focus: " + jid +", real JID: " + info.jid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
messageHandler.notify(info.displayName || 'Somebody',
|
|
||||||
'connected',
|
|
||||||
'connected');
|
|
||||||
|
|
||||||
// Add Peer's container
|
|
||||||
var id = $(pres).find('>userID').text();
|
|
||||||
var email = $(pres).find('>email');
|
|
||||||
if(email.length > 0) {
|
|
||||||
id = email.text();
|
|
||||||
}
|
|
||||||
VideoLayout.ensurePeerContainerExists(jid,id);
|
|
||||||
|
|
||||||
if(APIConnector.isEnabled() && APIConnector.isEventEnabled("participantJoined"))
|
|
||||||
{
|
|
||||||
APIConnector.triggerEvent("participantJoined",{jid: jid});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (focus !== null) {
|
|
||||||
// FIXME: this should prepare the video
|
|
||||||
if (focus.confid === null) {
|
|
||||||
console.log('make new conference with', jid);
|
|
||||||
focus.makeConference(Object.keys(connection.emuc.members),
|
|
||||||
function(error) {
|
|
||||||
connection.emuc.addBridgeIsDownToPresence();
|
|
||||||
connection.emuc.sendPresence();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Toolbar.showRecordingButton(true);
|
|
||||||
} else {
|
|
||||||
console.log('invite', jid, 'into conference');
|
|
||||||
focus.addNewParticipant(jid);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('left.muc', function (event, jid) {
|
|
||||||
console.log('left.muc', jid);
|
|
||||||
var displayName = $('#participant_' + Strophe.getResourceFromJid(jid) +
|
|
||||||
'>.displayname').html();
|
|
||||||
messageHandler.notify(displayName || 'Somebody',
|
|
||||||
'disconnected',
|
|
||||||
'disconnected');
|
|
||||||
// Need to call this with a slight delay, otherwise the element couldn't be
|
|
||||||
// found for some reason.
|
|
||||||
// XXX(gp) it works fine without the timeout for me (with Chrome 38).
|
|
||||||
window.setTimeout(function () {
|
|
||||||
var container = document.getElementById(
|
|
||||||
'participant_' + Strophe.getResourceFromJid(jid));
|
|
||||||
if (container) {
|
|
||||||
ContactList.removeContact(jid);
|
|
||||||
VideoLayout.removeConnectionIndicator(jid);
|
|
||||||
// hide here, wait for video to close before removing
|
|
||||||
$(container).hide();
|
|
||||||
VideoLayout.resizeThumbnails();
|
|
||||||
}
|
|
||||||
}, 10);
|
|
||||||
|
|
||||||
if(APIConnector.isEnabled() && APIConnector.isEventEnabled("participantLeft"))
|
|
||||||
{
|
|
||||||
APIConnector.triggerEvent("participantLeft",{jid: jid});
|
|
||||||
}
|
|
||||||
|
|
||||||
delete jid2Ssrc[jid];
|
|
||||||
|
|
||||||
// Unlock large video
|
|
||||||
if (focusedVideoInfo && focusedVideoInfo.jid === jid)
|
|
||||||
{
|
|
||||||
console.info("Focused video owner has left the conference");
|
|
||||||
focusedVideoInfo = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
connection.jingle.terminateByJid(jid);
|
|
||||||
|
|
||||||
if (connection.emuc.getPrezi(jid)) {
|
|
||||||
$(document).trigger('presentationremoved.muc',
|
|
||||||
[jid, connection.emuc.getPrezi(jid)]);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).bind('presence.muc', function (event, jid, info, pres) {
|
$(document).bind('presence.muc', function (event, jid, info, pres) {
|
||||||
|
@ -701,7 +473,7 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
|
||||||
//check if the video bridge is available
|
//check if the video bridge is available
|
||||||
if($(pres).find(">bridgeIsDown").length > 0 && !bridgeIsDown) {
|
if($(pres).find(">bridgeIsDown").length > 0 && !bridgeIsDown) {
|
||||||
bridgeIsDown = true;
|
bridgeIsDown = true;
|
||||||
messageHandler.showError("Error",
|
UI.messageHandler.showError("Error",
|
||||||
"Jitsi Videobridge is currently unavailable. Please try again later!");
|
"Jitsi Videobridge is currently unavailable. Please try again later!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,7 +528,7 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
|
||||||
//check if the video bridge is available
|
//check if the video bridge is available
|
||||||
if($(pres).find(">bridgeIsDown").length > 0 && !bridgeIsDown) {
|
if($(pres).find(">bridgeIsDown").length > 0 && !bridgeIsDown) {
|
||||||
bridgeIsDown = true;
|
bridgeIsDown = true;
|
||||||
messageHandler.showError("Error",
|
UI.messageHandler.showError("Error",
|
||||||
"Jitsi Videobridge is currently unavailable. Please try again later!");
|
"Jitsi Videobridge is currently unavailable. Please try again later!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,14 +537,7 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
|
||||||
if(email.length > 0) {
|
if(email.length > 0) {
|
||||||
id = email.text();
|
id = email.text();
|
||||||
}
|
}
|
||||||
Avatar.setUserAvatar(jid, id);
|
UI.setUserAvatar(jid, id);
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('presence.status.muc', function (event, jid, info, pres) {
|
|
||||||
|
|
||||||
VideoLayout.setPresenceStatus(
|
|
||||||
'participant_' + Strophe.getResourceFromJid(jid), info.status);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -782,80 +547,15 @@ $(document).bind('kicked.muc', function (event, jid) {
|
||||||
sessionTerminated = true;
|
sessionTerminated = true;
|
||||||
disposeConference(false);
|
disposeConference(false);
|
||||||
connection.emuc.doLeave();
|
connection.emuc.doLeave();
|
||||||
messageHandler.openMessageDialog("Session Terminated",
|
UI.messageHandler.openMessageDialog("Session Terminated",
|
||||||
"Ouch! You have been kicked out of the meet!");
|
"Ouch! You have been kicked out of the meet!");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).bind('role.changed.muc', function (event, jid, member, pres) {
|
|
||||||
console.info("Role changed for " + jid + ", new role: " + member.role);
|
|
||||||
|
|
||||||
VideoLayout.showModeratorIndicator();
|
|
||||||
|
|
||||||
if (member.role === 'moderator') {
|
|
||||||
var displayName = member.displayName;
|
|
||||||
if (!displayName) {
|
|
||||||
displayName = 'Somebody';
|
|
||||||
}
|
|
||||||
messageHandler.notify(
|
|
||||||
displayName,
|
|
||||||
'connected',
|
|
||||||
'Moderator rights granted to ' + displayName + '!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
$(document).bind('local.role.changed.muc', function (event, jid, info, pres) {
|
|
||||||
|
|
||||||
console.info("My role changed, new role: " + info.role);
|
|
||||||
var isModerator = Moderator.isModerator();
|
|
||||||
|
|
||||||
VideoLayout.showModeratorIndicator();
|
|
||||||
Toolbar.showAuthenticateButton(
|
|
||||||
Moderator.isExternalAuthEnabled() && !isModerator);
|
|
||||||
|
|
||||||
if (isModerator) {
|
|
||||||
if (authenticationWindow) {
|
|
||||||
authenticationWindow.close();
|
|
||||||
authenticationWindow = null;
|
|
||||||
}
|
|
||||||
messageHandler.notify(
|
|
||||||
'Me', 'connected', 'Moderator rights granted !');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
$(document).bind('passwordrequired.muc', function (event, jid) {
|
|
||||||
console.log('on password required', jid);
|
|
||||||
|
|
||||||
// password is required
|
|
||||||
Toolbar.lockLockButton();
|
|
||||||
|
|
||||||
messageHandler.openTwoButtonDialog(null,
|
|
||||||
'<h2>Password required</h2>' +
|
|
||||||
'<input id="lockKey" type="text" placeholder="password" autofocus>',
|
|
||||||
true,
|
|
||||||
"Ok",
|
|
||||||
function (e, v, m, f) {},
|
|
||||||
function (event) {
|
|
||||||
document.getElementById('lockKey').focus();
|
|
||||||
},
|
|
||||||
function (e, v, m, f) {
|
|
||||||
if (v) {
|
|
||||||
var lockKey = document.getElementById('lockKey');
|
|
||||||
if (lockKey.value !== null) {
|
|
||||||
setSharedKey(lockKey.value);
|
|
||||||
connection.emuc.doJoin(jid, lockKey.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).bind('passwordrequired.main', function (event) {
|
$(document).bind('passwordrequired.main', function (event) {
|
||||||
console.log('password is required');
|
console.log('password is required');
|
||||||
|
|
||||||
messageHandler.openTwoButtonDialog(null,
|
UI.messageHandler.openTwoButtonDialog(null,
|
||||||
'<h2>Password required</h2>' +
|
'<h2>Password required</h2>' +
|
||||||
'<input id="passwordrequired.username" type="text" placeholder="user@domain.net" autofocus>' +
|
'<input id="passwordrequired.username" type="text" placeholder="user@domain.net" autofocus>' +
|
||||||
'<input id="passwordrequired.password" type="password" placeholder="user password">',
|
'<input id="passwordrequired.password" type="password" placeholder="user password">',
|
||||||
|
@ -877,51 +577,6 @@ $(document).bind('passwordrequired.main', function (event) {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).bind('auth_required.moderator', function () {
|
|
||||||
// extract room name from 'room@muc.server.net'
|
|
||||||
var room = roomName.substr(0, roomName.indexOf('@'));
|
|
||||||
|
|
||||||
messageHandler.openDialog(
|
|
||||||
'Stop',
|
|
||||||
'Authentication is required to create room:<br/>' + room,
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
Authenticate: 'authNow',
|
|
||||||
Close: 'close'
|
|
||||||
},
|
|
||||||
function (onSubmitEvent, submitValue) {
|
|
||||||
console.info('On submit: ' + submitValue, submitValue);
|
|
||||||
if (submitValue === 'authNow') {
|
|
||||||
authenticateClicked();
|
|
||||||
} else {
|
|
||||||
Toolbar.showAuthenticateButton(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
function authenticateClicked() {
|
|
||||||
// Get authentication URL
|
|
||||||
Moderator.getAuthUrl(function (url) {
|
|
||||||
// Open popup with authentication URL
|
|
||||||
authenticationWindow = messageHandler.openCenteredPopup(
|
|
||||||
url, 500, 400,
|
|
||||||
function () {
|
|
||||||
// On popup closed - retry room allocation
|
|
||||||
Moderator.allocateConferenceFocus(
|
|
||||||
roomName, doJoinAfterFocus);
|
|
||||||
authenticationWindow = null;
|
|
||||||
});
|
|
||||||
if (!authenticationWindow) {
|
|
||||||
Toolbar.showAuthenticateButton(true);
|
|
||||||
messageHandler.openMessageDialog(
|
|
||||||
null, "Your browser is blocking popup windows from this site." +
|
|
||||||
" Please enable popups in your browser security settings" +
|
|
||||||
" and try again.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if video identified by given src is desktop stream.
|
* Checks if video identified by given src is desktop stream.
|
||||||
* @param videoSrc eg.
|
* @param videoSrc eg.
|
||||||
|
@ -1060,7 +715,7 @@ function setAudioMuted(mute) {
|
||||||
// isMuted is the opposite of audioEnabled
|
// isMuted is the opposite of audioEnabled
|
||||||
connection.emuc.addAudioInfoToPresence(mute);
|
connection.emuc.addAudioInfoToPresence(mute);
|
||||||
connection.emuc.sendPresence();
|
connection.emuc.sendPresence();
|
||||||
VideoLayout.showLocalAudioIndicator(mute);
|
UI.showLocalAudioIndicator(mute);
|
||||||
|
|
||||||
buttonClick("#mute", "icon-microphone icon-mic-disabled");
|
buttonClick("#mute", "icon-microphone icon-mic-disabled");
|
||||||
}
|
}
|
||||||
|
@ -1079,11 +734,6 @@ function isAudioMuted()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts or stops the recording for the conference.
|
|
||||||
function toggleRecording() {
|
|
||||||
Recording.toggleRecording();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of the video horizontal and vertical indents,
|
* Returns an array of the video horizontal and vertical indents,
|
||||||
* so that if fits its parent.
|
* so that if fits its parent.
|
||||||
|
@ -1163,151 +813,17 @@ function getCameraVideoSize(videoWidth,
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
document.title = interfaceConfig.APP_NAME;
|
|
||||||
if(APIConnector.isEnabled())
|
if(APIConnector.isEnabled())
|
||||||
APIConnector.init();
|
APIConnector.init();
|
||||||
|
|
||||||
if(config.enableWelcomePage && window.location.pathname == "/" &&
|
UI.start();
|
||||||
(!window.localStorage.welcomePageDisabled
|
|
||||||
|| window.localStorage.welcomePageDisabled == "false"))
|
|
||||||
{
|
|
||||||
$("#videoconference_page").hide();
|
|
||||||
$("#domain_name").text(
|
|
||||||
window.location.protocol + "//" + window.location.host + "/");
|
|
||||||
$("span[name='appName']").text(interfaceConfig.APP_NAME);
|
|
||||||
|
|
||||||
if (interfaceConfig.SHOW_JITSI_WATERMARK) {
|
|
||||||
var leftWatermarkDiv
|
|
||||||
= $("#welcome_page_header div[class='watermark leftwatermark']");
|
|
||||||
if(leftWatermarkDiv && leftWatermarkDiv.length > 0)
|
|
||||||
{
|
|
||||||
leftWatermarkDiv.css({display: 'block'});
|
|
||||||
leftWatermarkDiv.parent().get(0).href
|
|
||||||
= interfaceConfig.JITSI_WATERMARK_LINK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceConfig.SHOW_BRAND_WATERMARK) {
|
|
||||||
var rightWatermarkDiv
|
|
||||||
= $("#welcome_page_header div[class='watermark rightwatermark']");
|
|
||||||
if(rightWatermarkDiv && rightWatermarkDiv.length > 0) {
|
|
||||||
rightWatermarkDiv.css({display: 'block'});
|
|
||||||
rightWatermarkDiv.parent().get(0).href
|
|
||||||
= interfaceConfig.BRAND_WATERMARK_LINK;
|
|
||||||
rightWatermarkDiv.get(0).style.backgroundImage
|
|
||||||
= "url(images/rightwatermark.png)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceConfig.SHOW_POWERED_BY) {
|
|
||||||
$("#welcome_page_header>a[class='poweredby']")
|
|
||||||
.css({display: 'block'});
|
|
||||||
}
|
|
||||||
|
|
||||||
function enter_room()
|
|
||||||
{
|
|
||||||
var val = $("#enter_room_field").val();
|
|
||||||
if(!val) {
|
|
||||||
val = $("#enter_room_field").attr("room_name");
|
|
||||||
}
|
|
||||||
if (val) {
|
|
||||||
window.location.pathname = "/" + val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#enter_room_button").click(function()
|
|
||||||
{
|
|
||||||
enter_room();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#enter_room_field").keydown(function (event) {
|
|
||||||
if (event.keyCode === 13 /* enter */) {
|
|
||||||
enter_room();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!(interfaceConfig.GENERATE_ROOMNAMES_ON_WELCOME_PAGE === false)){
|
|
||||||
var updateTimeout;
|
|
||||||
var animateTimeout;
|
|
||||||
$("#reload_roomname").click(function () {
|
|
||||||
clearTimeout(updateTimeout);
|
|
||||||
clearTimeout(animateTimeout);
|
|
||||||
update_roomname();
|
|
||||||
});
|
|
||||||
$("#reload_roomname").show();
|
|
||||||
|
|
||||||
function animate(word) {
|
|
||||||
var currentVal = $("#enter_room_field").attr("placeholder");
|
|
||||||
$("#enter_room_field").attr("placeholder", currentVal + word.substr(0, 1));
|
|
||||||
animateTimeout = setTimeout(function() {
|
|
||||||
animate(word.substring(1, word.length))
|
|
||||||
}, 70);
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_roomname()
|
|
||||||
{
|
|
||||||
var word = RoomNameGenerator.generateRoomWithoutSeparator();
|
|
||||||
$("#enter_room_field").attr("room_name", word);
|
|
||||||
$("#enter_room_field").attr("placeholder", "");
|
|
||||||
clearTimeout(animateTimeout);
|
|
||||||
animate(word);
|
|
||||||
updateTimeout = setTimeout(update_roomname, 10000);
|
|
||||||
}
|
|
||||||
update_roomname();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#disable_welcome").click(function () {
|
|
||||||
window.localStorage.welcomePageDisabled
|
|
||||||
= $("#disable_welcome").is(":checked");
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceConfig.SHOW_JITSI_WATERMARK) {
|
|
||||||
var leftWatermarkDiv
|
|
||||||
= $("#largeVideoContainer div[class='watermark leftwatermark']");
|
|
||||||
|
|
||||||
leftWatermarkDiv.css({display: 'block'});
|
|
||||||
leftWatermarkDiv.parent().get(0).href
|
|
||||||
= interfaceConfig.JITSI_WATERMARK_LINK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceConfig.SHOW_BRAND_WATERMARK) {
|
|
||||||
var rightWatermarkDiv
|
|
||||||
= $("#largeVideoContainer div[class='watermark rightwatermark']");
|
|
||||||
|
|
||||||
rightWatermarkDiv.css({display: 'block'});
|
|
||||||
rightWatermarkDiv.parent().get(0).href
|
|
||||||
= interfaceConfig.BRAND_WATERMARK_LINK;
|
|
||||||
rightWatermarkDiv.get(0).style.backgroundImage
|
|
||||||
= "url(images/rightwatermark.png)";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceConfig.SHOW_POWERED_BY) {
|
|
||||||
$("#largeVideoContainer>a[class='poweredby']").css({display: 'block'});
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#welcome_page").hide();
|
|
||||||
Chat.init();
|
|
||||||
|
|
||||||
$('body').popover({ selector: '[data-toggle=popover]',
|
|
||||||
trigger: 'click hover',
|
|
||||||
content: function() {
|
|
||||||
return this.getAttribute("content") +
|
|
||||||
KeyboardShortcut.getShortcut(this.getAttribute("shortcut"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
statistics.addAudioLevelListener(audioLevelUpdated);
|
|
||||||
statistics.addConnectionStatsListener(ConnectionQuality.updateLocalStats);
|
statistics.addConnectionStatsListener(ConnectionQuality.updateLocalStats);
|
||||||
statistics.addRemoteStatsStopListener(ConnectionQuality.stopSendingStats);
|
statistics.addRemoteStatsStopListener(ConnectionQuality.stopSendingStats);
|
||||||
|
statistics.start();
|
||||||
|
|
||||||
Moderator.init();
|
Moderator.init();
|
||||||
|
|
||||||
// Set the defaults for prompt dialogs.
|
|
||||||
jQuery.prompt.setDefaults({persistent: false});
|
|
||||||
|
|
||||||
// Set default desktop sharing method
|
// Set default desktop sharing method
|
||||||
setDesktopSharing(config.desktopSharing);
|
setDesktopSharing(config.desktopSharing);
|
||||||
// Initialize Chrome extension inline installs
|
// Initialize Chrome extension inline installs
|
||||||
|
@ -1318,62 +834,6 @@ $(document).ready(function () {
|
||||||
// By default we use camera
|
// By default we use camera
|
||||||
getVideoSize = getCameraVideoSize;
|
getVideoSize = getCameraVideoSize;
|
||||||
getVideoPosition = getCameraVideoPosition;
|
getVideoPosition = getCameraVideoPosition;
|
||||||
|
|
||||||
VideoLayout.resizeLargeVideoContainer();
|
|
||||||
$(window).resize(function () {
|
|
||||||
VideoLayout.resizeLargeVideoContainer();
|
|
||||||
VideoLayout.positionLarge();
|
|
||||||
});
|
|
||||||
// Listen for large video size updates
|
|
||||||
document.getElementById('largeVideo')
|
|
||||||
.addEventListener('loadedmetadata', function (e) {
|
|
||||||
currentVideoWidth = this.videoWidth;
|
|
||||||
currentVideoHeight = this.videoHeight;
|
|
||||||
VideoLayout.positionLarge(currentVideoWidth, currentVideoHeight);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('largeVideo').volume = 0;
|
|
||||||
|
|
||||||
if (!$('#settings').is(':visible')) {
|
|
||||||
console.log('init');
|
|
||||||
init();
|
|
||||||
} else {
|
|
||||||
loginInfo.onsubmit = function (e) {
|
|
||||||
if (e.preventDefault) e.preventDefault();
|
|
||||||
$('#settings').hide();
|
|
||||||
init();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
toastr.options = {
|
|
||||||
"closeButton": true,
|
|
||||||
"debug": false,
|
|
||||||
"positionClass": "notification-bottom-right",
|
|
||||||
"onclick": null,
|
|
||||||
"showDuration": "300",
|
|
||||||
"hideDuration": "1000",
|
|
||||||
"timeOut": "2000",
|
|
||||||
"extendedTimeOut": "1000",
|
|
||||||
"showEasing": "swing",
|
|
||||||
"hideEasing": "linear",
|
|
||||||
"showMethod": "fadeIn",
|
|
||||||
"hideMethod": "fadeOut",
|
|
||||||
"reposition": function() {
|
|
||||||
if(PanelToggler.isVisible()) {
|
|
||||||
$("#toast-container").addClass("notification-bottom-right-center");
|
|
||||||
} else {
|
|
||||||
$("#toast-container").removeClass("notification-bottom-right-center");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"newestOnTop": false
|
|
||||||
};
|
|
||||||
|
|
||||||
$('#settingsmenu>input').keyup(function(event){
|
|
||||||
if(event.keyCode === 13) {//enter
|
|
||||||
SettingsMenu.update();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$(window).bind('beforeunload', function () {
|
$(window).bind('beforeunload', function () {
|
||||||
|
@ -1404,9 +864,7 @@ $(window).bind('beforeunload', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
function disposeConference(onUnload) {
|
function disposeConference(onUnload) {
|
||||||
|
UI.onDisposeConference(onUnload);
|
||||||
Toolbar.showAuthenticateButton(false);
|
|
||||||
|
|
||||||
var handler = getConferenceHandler();
|
var handler = getConferenceHandler();
|
||||||
if (handler && handler.peerconnection) {
|
if (handler && handler.peerconnection) {
|
||||||
// FIXME: probably removing streams is not required and close() should
|
// FIXME: probably removing streams is not required and close() should
|
||||||
|
@ -1469,37 +927,6 @@ function buttonClick(id, classname) {
|
||||||
$(id).toggleClass(classname); // add the class to the clicked element
|
$(id).toggleClass(classname); // add the class to the clicked element
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Locks / unlocks the room.
|
|
||||||
*/
|
|
||||||
function lockRoom(lock) {
|
|
||||||
if (lock)
|
|
||||||
connection.emuc.lockRoom(sharedKey);
|
|
||||||
else
|
|
||||||
connection.emuc.lockRoom('');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the shared key.
|
|
||||||
*/
|
|
||||||
function setSharedKey(sKey) {
|
|
||||||
sharedKey = sKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the room invite url.
|
|
||||||
*/
|
|
||||||
function updateRoomUrl(newRoomUrl) {
|
|
||||||
roomUrl = newRoomUrl;
|
|
||||||
|
|
||||||
// If the invite dialog has been already opened we update the information.
|
|
||||||
var inviteLink = document.getElementById('inviteLinkRef');
|
|
||||||
if (inviteLink) {
|
|
||||||
inviteLink.value = roomUrl;
|
|
||||||
inviteLink.select();
|
|
||||||
document.getElementById('jqi_state0_buttonInvite').disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warning to the user that the conference window is about to be closed.
|
* Warning to the user that the conference window is about to be closed.
|
||||||
|
@ -1514,19 +941,6 @@ function closePageWarning() {
|
||||||
return "You are about to leave this conversation.";
|
return "You are about to leave this conversation.";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Resizes and repositions videos in full screen mode.
|
|
||||||
*/
|
|
||||||
$(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange',
|
|
||||||
function () {
|
|
||||||
VideoLayout.resizeLargeVideoContainer();
|
|
||||||
VideoLayout.positionLarge();
|
|
||||||
isFullScreen = document.fullScreen ||
|
|
||||||
document.mozFullScreen ||
|
|
||||||
document.webkitIsFullScreen;
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
$(document).bind('error.jingle',
|
$(document).bind('error.jingle',
|
||||||
function (event, session, error)
|
function (event, session, error)
|
||||||
|
@ -1540,7 +954,7 @@ $(document).bind('fatalError.jingle',
|
||||||
{
|
{
|
||||||
sessionTerminated = true;
|
sessionTerminated = true;
|
||||||
connection.emuc.doLeave();
|
connection.emuc.doLeave();
|
||||||
messageHandler.showError( "Sorry",
|
UI.messageHandler.showError( "Sorry",
|
||||||
"Internal application error[setRemoteDescription]");
|
"Internal application error[setRemoteDescription]");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1550,7 +964,7 @@ function callSipButtonClicked()
|
||||||
var defaultNumber
|
var defaultNumber
|
||||||
= config.defaultSipNumber ? config.defaultSipNumber : '';
|
= config.defaultSipNumber ? config.defaultSipNumber : '';
|
||||||
|
|
||||||
messageHandler.openTwoButtonDialog(null,
|
UI.messageHandler.openTwoButtonDialog(null,
|
||||||
'<h2>Enter SIP number</h2>' +
|
'<h2>Enter SIP number</h2>' +
|
||||||
'<input id="sipNumber" type="text"' +
|
'<input id="sipNumber" type="text"' +
|
||||||
' value="' + defaultNumber + '" autofocus>',
|
' value="' + defaultNumber + '" autofocus>',
|
||||||
|
|
343
chat.js
343
chat.js
|
@ -1,343 +0,0 @@
|
||||||
/* global $, Util, connection, nickname:true, getVideoSize, getVideoPosition, showToolbar, processReplacements */
|
|
||||||
/**
|
|
||||||
* Chat related user interface.
|
|
||||||
*/
|
|
||||||
var Chat = (function (my) {
|
|
||||||
var notificationInterval = false;
|
|
||||||
var unreadMessages = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes chat related interface.
|
|
||||||
*/
|
|
||||||
my.init = function () {
|
|
||||||
var storedDisplayName = window.localStorage.displayname;
|
|
||||||
if (storedDisplayName) {
|
|
||||||
nickname = storedDisplayName;
|
|
||||||
|
|
||||||
Chat.setChatConversationMode(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#nickinput').keydown(function (event) {
|
|
||||||
if (event.keyCode === 13) {
|
|
||||||
event.preventDefault();
|
|
||||||
var val = Util.escapeHtml(this.value);
|
|
||||||
this.value = '';
|
|
||||||
if (!nickname) {
|
|
||||||
nickname = val;
|
|
||||||
window.localStorage.displayname = nickname;
|
|
||||||
|
|
||||||
connection.emuc.addDisplayNameToPresence(nickname);
|
|
||||||
connection.emuc.sendPresence();
|
|
||||||
|
|
||||||
Chat.setChatConversationMode(true);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#usermsg').keydown(function (event) {
|
|
||||||
if (event.keyCode === 13) {
|
|
||||||
event.preventDefault();
|
|
||||||
var value = this.value;
|
|
||||||
$('#usermsg').val('').trigger('autosize.resize');
|
|
||||||
this.focus();
|
|
||||||
var command = new CommandsProcessor(value);
|
|
||||||
if(command.isCommand())
|
|
||||||
{
|
|
||||||
command.processCommand();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var message = Util.escapeHtml(value);
|
|
||||||
connection.emuc.sendMessage(message, nickname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var onTextAreaResize = function () {
|
|
||||||
resizeChatConversation();
|
|
||||||
Chat.scrollChatToBottom();
|
|
||||||
};
|
|
||||||
$('#usermsg').autosize({callback: onTextAreaResize});
|
|
||||||
|
|
||||||
$("#chatspace").bind("shown",
|
|
||||||
function () {
|
|
||||||
unreadMessages = 0;
|
|
||||||
setVisualNotification(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
addSmileys();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Appends the given message to the chat conversation.
|
|
||||||
*/
|
|
||||||
my.updateChatConversation = function (from, displayName, message) {
|
|
||||||
var divClassName = '';
|
|
||||||
|
|
||||||
if (connection.emuc.myroomjid === from) {
|
|
||||||
divClassName = "localuser";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
divClassName = "remoteuser";
|
|
||||||
|
|
||||||
if (!Chat.isVisible()) {
|
|
||||||
unreadMessages++;
|
|
||||||
Util.playSoundNotification('chatNotification');
|
|
||||||
setVisualNotification(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//replace links and smileys
|
|
||||||
var escMessage = message.replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br/>'); //Strophe already escapes special symbols on sending, so we escape here only tags to avoid double &
|
|
||||||
var escDisplayName = Util.escapeHtml(displayName);
|
|
||||||
message = processReplacements(escMessage);
|
|
||||||
|
|
||||||
var messageContainer =
|
|
||||||
'<div class="chatmessage">'+
|
|
||||||
'<img src="../images/chatArrow.svg" class="chatArrow">' +
|
|
||||||
'<div class="username ' + divClassName +'">' + escDisplayName + '</div>' +
|
|
||||||
'<div class="timestamp">' + getCurrentTime() + '</div>' +
|
|
||||||
'<div class="usermessage">' + message + '</div>' +
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
$('#chatconversation').append(messageContainer);
|
|
||||||
$('#chatconversation').animate(
|
|
||||||
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Appends error message to the conversation
|
|
||||||
* @param errorMessage the received error message.
|
|
||||||
* @param originalText the original message.
|
|
||||||
*/
|
|
||||||
my.chatAddError = function(errorMessage, originalText)
|
|
||||||
{
|
|
||||||
errorMessage = Util.escapeHtml(errorMessage);
|
|
||||||
originalText = Util.escapeHtml(originalText);
|
|
||||||
|
|
||||||
$('#chatconversation').append('<div class="errorMessage"><b>Error: </b>'
|
|
||||||
+ 'Your message' + (originalText? (' \"'+ originalText + '\"') : "")
|
|
||||||
+ ' was not sent.' + (errorMessage? (' Reason: ' + errorMessage) : '')
|
|
||||||
+ '</div>');
|
|
||||||
$('#chatconversation').animate(
|
|
||||||
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the subject to the UI
|
|
||||||
* @param subject the subject
|
|
||||||
*/
|
|
||||||
my.chatSetSubject = function(subject)
|
|
||||||
{
|
|
||||||
if(subject)
|
|
||||||
subject = subject.trim();
|
|
||||||
$('#subject').html(linkify(Util.escapeHtml(subject)));
|
|
||||||
if(subject == "")
|
|
||||||
{
|
|
||||||
$("#subject").css({display: "none"});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$("#subject").css({display: "block"});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the chat conversation mode.
|
|
||||||
*/
|
|
||||||
my.setChatConversationMode = function (isConversationMode) {
|
|
||||||
if (isConversationMode) {
|
|
||||||
$('#nickname').css({visibility: 'hidden'});
|
|
||||||
$('#chatconversation').css({visibility: 'visible'});
|
|
||||||
$('#usermsg').css({visibility: 'visible'});
|
|
||||||
$('#smileysarea').css({visibility: 'visible'});
|
|
||||||
$('#usermsg').focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resizes the chat area.
|
|
||||||
*/
|
|
||||||
my.resizeChat = function () {
|
|
||||||
var chatSize = PanelToggler.getPanelSize();
|
|
||||||
|
|
||||||
$('#chatspace').width(chatSize[0]);
|
|
||||||
$('#chatspace').height(chatSize[1]);
|
|
||||||
|
|
||||||
resizeChatConversation();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the chat is currently visible.
|
|
||||||
*/
|
|
||||||
my.isVisible = function () {
|
|
||||||
return $('#chatspace').is(":visible");
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Shows and hides the window with the smileys
|
|
||||||
*/
|
|
||||||
my.toggleSmileys = function() {
|
|
||||||
var smileys = $('#smileysContainer');
|
|
||||||
if(!smileys.is(':visible')) {
|
|
||||||
smileys.show("slide", { direction: "down", duration: 300});
|
|
||||||
} else {
|
|
||||||
smileys.hide("slide", { direction: "down", duration: 300});
|
|
||||||
}
|
|
||||||
$('#usermsg').focus();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scrolls chat to the bottom.
|
|
||||||
*/
|
|
||||||
my.scrollChatToBottom = function() {
|
|
||||||
setTimeout(function () {
|
|
||||||
$('#chatconversation').scrollTop(
|
|
||||||
$('#chatconversation')[0].scrollHeight);
|
|
||||||
}, 5);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the smileys container to the chat
|
|
||||||
*/
|
|
||||||
function addSmileys() {
|
|
||||||
var smileysContainer = document.createElement('div');
|
|
||||||
smileysContainer.id = 'smileysContainer';
|
|
||||||
function addClickFunction(smiley, number) {
|
|
||||||
smiley.onclick = function addSmileyToMessage() {
|
|
||||||
var usermsg = $('#usermsg');
|
|
||||||
var message = usermsg.val();
|
|
||||||
message += smileys['smiley' + number];
|
|
||||||
usermsg.val(message);
|
|
||||||
usermsg.get(0).setSelectionRange(message.length, message.length);
|
|
||||||
Chat.toggleSmileys();
|
|
||||||
usermsg.focus();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
for(var i = 1; i <= 21; i++) {
|
|
||||||
var smileyContainer = document.createElement('div');
|
|
||||||
smileyContainer.id = 'smiley' + i;
|
|
||||||
smileyContainer.className = 'smileyContainer';
|
|
||||||
var smiley = document.createElement('img');
|
|
||||||
smiley.src = 'images/smileys/smiley' + i + '.svg';
|
|
||||||
smiley.className = 'smiley';
|
|
||||||
addClickFunction(smiley, i);
|
|
||||||
smileyContainer.appendChild(smiley);
|
|
||||||
smileysContainer.appendChild(smileyContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#chatspace").append(smileysContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resizes the chat conversation.
|
|
||||||
*/
|
|
||||||
function resizeChatConversation() {
|
|
||||||
var msgareaHeight = $('#usermsg').outerHeight();
|
|
||||||
var chatspace = $('#chatspace');
|
|
||||||
var width = chatspace.width();
|
|
||||||
var chat = $('#chatconversation');
|
|
||||||
var smileys = $('#smileysarea');
|
|
||||||
|
|
||||||
smileys.height(msgareaHeight);
|
|
||||||
$("#smileys").css('bottom', (msgareaHeight - 26) / 2);
|
|
||||||
$('#smileysContainer').css('bottom', msgareaHeight);
|
|
||||||
chat.width(width - 10);
|
|
||||||
chat.height(window.innerHeight - 15 - msgareaHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows/hides a visual notification, indicating that a message has arrived.
|
|
||||||
*/
|
|
||||||
function setVisualNotification(show) {
|
|
||||||
var unreadMsgElement = document.getElementById('unreadMessages');
|
|
||||||
var unreadMsgBottomElement = document.getElementById('bottomUnreadMessages');
|
|
||||||
|
|
||||||
var glower = $('#chatButton');
|
|
||||||
var bottomGlower = $('#chatBottomButton');
|
|
||||||
|
|
||||||
if (unreadMessages) {
|
|
||||||
unreadMsgElement.innerHTML = unreadMessages.toString();
|
|
||||||
unreadMsgBottomElement.innerHTML = unreadMessages.toString();
|
|
||||||
|
|
||||||
ToolbarToggler.dockToolbar(true);
|
|
||||||
|
|
||||||
var chatButtonElement
|
|
||||||
= document.getElementById('chatButton').parentNode;
|
|
||||||
var leftIndent = (Util.getTextWidth(chatButtonElement) -
|
|
||||||
Util.getTextWidth(unreadMsgElement)) / 2;
|
|
||||||
var topIndent = (Util.getTextHeight(chatButtonElement) -
|
|
||||||
Util.getTextHeight(unreadMsgElement)) / 2 - 3;
|
|
||||||
|
|
||||||
unreadMsgElement.setAttribute(
|
|
||||||
'style',
|
|
||||||
'top:' + topIndent +
|
|
||||||
'; left:' + leftIndent + ';');
|
|
||||||
|
|
||||||
var chatBottomButtonElement
|
|
||||||
= document.getElementById('chatBottomButton').parentNode;
|
|
||||||
var bottomLeftIndent = (Util.getTextWidth(chatBottomButtonElement) -
|
|
||||||
Util.getTextWidth(unreadMsgBottomElement)) / 2;
|
|
||||||
var bottomTopIndent = (Util.getTextHeight(chatBottomButtonElement) -
|
|
||||||
Util.getTextHeight(unreadMsgBottomElement)) / 2 - 2;
|
|
||||||
|
|
||||||
unreadMsgBottomElement.setAttribute(
|
|
||||||
'style',
|
|
||||||
'top:' + bottomTopIndent +
|
|
||||||
'; left:' + bottomLeftIndent + ';');
|
|
||||||
|
|
||||||
|
|
||||||
if (!glower.hasClass('icon-chat-simple')) {
|
|
||||||
glower.removeClass('icon-chat');
|
|
||||||
glower.addClass('icon-chat-simple');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
unreadMsgElement.innerHTML = '';
|
|
||||||
unreadMsgBottomElement.innerHTML = '';
|
|
||||||
glower.removeClass('icon-chat-simple');
|
|
||||||
glower.addClass('icon-chat');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show && !notificationInterval) {
|
|
||||||
notificationInterval = window.setInterval(function () {
|
|
||||||
glower.toggleClass('active');
|
|
||||||
bottomGlower.toggleClass('active glowing');
|
|
||||||
}, 800);
|
|
||||||
}
|
|
||||||
else if (!show && notificationInterval) {
|
|
||||||
window.clearInterval(notificationInterval);
|
|
||||||
notificationInterval = false;
|
|
||||||
glower.removeClass('active');
|
|
||||||
bottomGlower.removeClass('glowing');
|
|
||||||
bottomGlower.addClass('active');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current time in the format it is shown to the user
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function getCurrentTime() {
|
|
||||||
var now = new Date();
|
|
||||||
var hour = now.getHours();
|
|
||||||
var minute = now.getMinutes();
|
|
||||||
var second = now.getSeconds();
|
|
||||||
if(hour.toString().length === 1) {
|
|
||||||
hour = '0'+hour;
|
|
||||||
}
|
|
||||||
if(minute.toString().length === 1) {
|
|
||||||
minute = '0'+minute;
|
|
||||||
}
|
|
||||||
if(second.toString().length === 1) {
|
|
||||||
second = '0'+second;
|
|
||||||
}
|
|
||||||
return hour+':'+minute+':'+second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return my;
|
|
||||||
}(Chat || {}));
|
|
98
commands.js
98
commands.js
|
@ -1,98 +0,0 @@
|
||||||
/**
|
|
||||||
* Handles commands received via chat messages.
|
|
||||||
*/
|
|
||||||
var CommandsProcessor = (function()
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructs new CommandProccessor instance from a message.
|
|
||||||
* @param message the message
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function CommandsPrototype(message)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Extracts the command from the message.
|
|
||||||
* @param message the received message
|
|
||||||
* @returns {string} the command
|
|
||||||
*/
|
|
||||||
function getCommand(message)
|
|
||||||
{
|
|
||||||
if(message)
|
|
||||||
{
|
|
||||||
for(var command in commands)
|
|
||||||
{
|
|
||||||
if(message.indexOf("/" + command) == 0)
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
var command = getCommand(message);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the command.
|
|
||||||
* @returns {String} the command
|
|
||||||
*/
|
|
||||||
this.getCommand = function()
|
|
||||||
{
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var messageArgument = message.substr(command.length + 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the arguments of the command.
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
this.getArgument = function()
|
|
||||||
{
|
|
||||||
return messageArgument;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether this instance is valid command or not.
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
CommandsPrototype.prototype.isCommand = function()
|
|
||||||
{
|
|
||||||
if(this.getCommand())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes the command.
|
|
||||||
*/
|
|
||||||
CommandsPrototype.prototype.processCommand = function()
|
|
||||||
{
|
|
||||||
if(!this.isCommand())
|
|
||||||
return;
|
|
||||||
|
|
||||||
commands[this.getCommand()](this.getArgument());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes the data for topic command.
|
|
||||||
* @param commandArguments the arguments of the topic command.
|
|
||||||
*/
|
|
||||||
var processTopic = function(commandArguments)
|
|
||||||
{
|
|
||||||
var topic = Util.escapeHtml(commandArguments);
|
|
||||||
connection.emuc.setSubject(topic);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List with supported commands. The keys are the names of the commands and
|
|
||||||
* the value is the function that processes the message.
|
|
||||||
* @type {{String: function}}
|
|
||||||
*/
|
|
||||||
var commands = {
|
|
||||||
"topic" : processTopic
|
|
||||||
};
|
|
||||||
|
|
||||||
return CommandsPrototype;
|
|
||||||
})();
|
|
|
@ -32,7 +32,7 @@ var ConnectionQuality = (function () {
|
||||||
*/
|
*/
|
||||||
ConnectionQuality.updateLocalStats = function (data) {
|
ConnectionQuality.updateLocalStats = function (data) {
|
||||||
stats = data;
|
stats = data;
|
||||||
VideoLayout.updateLocalConnectionStats(100 - stats.packetLoss.total,stats);
|
UI.updateLocalConnectionStats(100 - stats.packetLoss.total,stats);
|
||||||
if(sendIntervalId == null)
|
if(sendIntervalId == null)
|
||||||
{
|
{
|
||||||
startSendingStats();
|
startSendingStats();
|
||||||
|
@ -97,12 +97,12 @@ var ConnectionQuality = (function () {
|
||||||
ConnectionQuality.updateRemoteStats = function (jid, data) {
|
ConnectionQuality.updateRemoteStats = function (jid, data) {
|
||||||
if(data == null || data.packetLoss_total == null)
|
if(data == null || data.packetLoss_total == null)
|
||||||
{
|
{
|
||||||
VideoLayout.updateConnectionStats(jid, null, null);
|
UI.updateConnectionStats(jid, null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
remoteStats[jid] = parseMUCStats(data);
|
remoteStats[jid] = parseMUCStats(data);
|
||||||
|
|
||||||
VideoLayout.updateConnectionStats(jid, 100 - data.packetLoss_total,remoteStats[jid]);
|
UI.updateConnectionStats(jid, 100 - data.packetLoss_total,remoteStats[jid]);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ var ConnectionQuality = (function () {
|
||||||
clearInterval(sendIntervalId);
|
clearInterval(sendIntervalId);
|
||||||
sendIntervalId = null;
|
sendIntervalId = null;
|
||||||
//notify UI about stopping statistics gathering
|
//notify UI about stopping statistics gathering
|
||||||
VideoLayout.onStatsStop();
|
UI.onStatsStop();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global $, alert, changeLocalVideo, chrome, config, connection, getConferenceHandler, getUserMediaWithConstraints, VideoLayout */
|
/* global $, alert, changeLocalVideo, chrome, config, connection, getConferenceHandler, getUserMediaWithConstraints */
|
||||||
/**
|
/**
|
||||||
* Indicates that desktop stream is currently in use(for toggle purpose).
|
* Indicates that desktop stream is currently in use(for toggle purpose).
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
|
@ -86,7 +86,7 @@ function isUpdateRequired(minVersion, extVersion)
|
||||||
catch (e)
|
catch (e)
|
||||||
{
|
{
|
||||||
console.error("Failed to parse extension version", e);
|
console.error("Failed to parse extension version", e);
|
||||||
messageHandler.showError('Error',
|
UI.messageHandler.showError('Error',
|
||||||
'Error when trying to detect desktopsharing extension.');
|
'Error when trying to detect desktopsharing extension.');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ function obtainScreenFromExtension(streamCallback, failCallback) {
|
||||||
function (arg) {
|
function (arg) {
|
||||||
console.log("Failed to install the extension", arg);
|
console.log("Failed to install the extension", arg);
|
||||||
failCallback(arg);
|
failCallback(arg);
|
||||||
messageHandler.showError('Error',
|
UI.messageHandler.showError('Error',
|
||||||
'Failed to install desktop sharing extension');
|
'Failed to install desktop sharing extension');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -247,7 +247,7 @@ function streamSwitchDone() {
|
||||||
//window.setTimeout(
|
//window.setTimeout(
|
||||||
// function () {
|
// function () {
|
||||||
switchInProgress = false;
|
switchInProgress = false;
|
||||||
Toolbar.changeDesktopSharingButtonState(isUsingScreenStream);
|
UI.changeDesktopSharingButtonState(isUsingScreenStream);
|
||||||
// }, 100
|
// }, 100
|
||||||
//);
|
//);
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ function newStreamCreated(stream) {
|
||||||
|
|
||||||
connection.jingle.localVideo = stream;
|
connection.jingle.localVideo = stream;
|
||||||
|
|
||||||
VideoLayout.changeLocalVideo(stream, !isUsingScreenStream);
|
UI.changeLocalVideo(stream, !isUsingScreenStream);
|
||||||
|
|
||||||
var conferenceHandler = getConferenceHandler();
|
var conferenceHandler = getConferenceHandler();
|
||||||
if (conferenceHandler) {
|
if (conferenceHandler) {
|
||||||
|
@ -267,7 +267,7 @@ function newStreamCreated(stream) {
|
||||||
} else {
|
} else {
|
||||||
// We are done immediately
|
// We are done immediately
|
||||||
console.error("No conference handler");
|
console.error("No conference handler");
|
||||||
messageHandler.showError('Error',
|
UI.messageHandler.showError('Error',
|
||||||
'Unable to switch video stream.');
|
'Unable to switch video stream.');
|
||||||
streamSwitchDone();
|
streamSwitchDone();
|
||||||
}
|
}
|
||||||
|
|
206
etherpad.js
206
etherpad.js
|
@ -1,206 +0,0 @@
|
||||||
/* global $, config, connection, dockToolbar, Moderator, Prezi,
|
|
||||||
setLargeVideoVisible, ToolbarToggler, Util, VideoLayout */
|
|
||||||
var Etherpad = (function (my) {
|
|
||||||
var etherpadName = null;
|
|
||||||
var etherpadIFrame = null;
|
|
||||||
var domain = null;
|
|
||||||
var options = "?showControls=true&showChat=false&showLineNumbers=true&useMonospaceFont=false";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the etherpad.
|
|
||||||
*/
|
|
||||||
my.init = function (name) {
|
|
||||||
|
|
||||||
if (config.etherpad_base && !etherpadName) {
|
|
||||||
|
|
||||||
domain = config.etherpad_base;
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
// In case we're the focus we generate the name.
|
|
||||||
etherpadName = Math.random().toString(36).substring(7) +
|
|
||||||
'_' + (new Date().getTime()).toString();
|
|
||||||
shareEtherpad();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
etherpadName = name;
|
|
||||||
|
|
||||||
enableEtherpadButton();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens/hides the Etherpad.
|
|
||||||
*/
|
|
||||||
my.toggleEtherpad = function (isPresentation) {
|
|
||||||
if (!etherpadIFrame)
|
|
||||||
createIFrame();
|
|
||||||
|
|
||||||
var largeVideo = null;
|
|
||||||
if (Prezi.isPresentationVisible())
|
|
||||||
largeVideo = $('#presentation>iframe');
|
|
||||||
else
|
|
||||||
largeVideo = $('#largeVideo');
|
|
||||||
|
|
||||||
if ($('#etherpad>iframe').css('visibility') === 'hidden') {
|
|
||||||
$('#activeSpeaker').css('visibility', 'hidden');
|
|
||||||
largeVideo.fadeOut(300, function () {
|
|
||||||
if (Prezi.isPresentationVisible()) {
|
|
||||||
largeVideo.css({opacity: '0'});
|
|
||||||
} else {
|
|
||||||
VideoLayout.setLargeVideoVisible(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#etherpad>iframe').fadeIn(300, function () {
|
|
||||||
document.body.style.background = '#eeeeee';
|
|
||||||
$('#etherpad>iframe').css({visibility: 'visible'});
|
|
||||||
$('#etherpad').css({zIndex: 2});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if ($('#etherpad>iframe')) {
|
|
||||||
$('#etherpad>iframe').fadeOut(300, function () {
|
|
||||||
$('#etherpad>iframe').css({visibility: 'hidden'});
|
|
||||||
$('#etherpad').css({zIndex: 0});
|
|
||||||
document.body.style.background = 'black';
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!isPresentation) {
|
|
||||||
$('#largeVideo').fadeIn(300, function () {
|
|
||||||
VideoLayout.setLargeVideoVisible(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resize();
|
|
||||||
};
|
|
||||||
|
|
||||||
my.isVisible = function() {
|
|
||||||
var etherpadIframe = $('#etherpad>iframe');
|
|
||||||
return etherpadIframe && etherpadIframe.is(':visible');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resizes the etherpad.
|
|
||||||
*/
|
|
||||||
function resize() {
|
|
||||||
if ($('#etherpad>iframe').length) {
|
|
||||||
var remoteVideos = $('#remoteVideos');
|
|
||||||
var availableHeight
|
|
||||||
= window.innerHeight - remoteVideos.outerHeight();
|
|
||||||
var availableWidth = Util.getAvailableVideoWidth();
|
|
||||||
|
|
||||||
$('#etherpad>iframe').width(availableWidth);
|
|
||||||
$('#etherpad>iframe').height(availableHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shares the Etherpad name with other participants.
|
|
||||||
*/
|
|
||||||
function shareEtherpad() {
|
|
||||||
connection.emuc.addEtherpadToPresence(etherpadName);
|
|
||||||
connection.emuc.sendPresence();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the Etherpad button and adds it to the toolbar.
|
|
||||||
*/
|
|
||||||
function enableEtherpadButton() {
|
|
||||||
if (!$('#etherpadButton').is(":visible"))
|
|
||||||
$('#etherpadButton').css({display: 'inline-block'});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the IFrame for the etherpad.
|
|
||||||
*/
|
|
||||||
function createIFrame() {
|
|
||||||
etherpadIFrame = document.createElement('iframe');
|
|
||||||
etherpadIFrame.src = domain + etherpadName + options;
|
|
||||||
etherpadIFrame.frameBorder = 0;
|
|
||||||
etherpadIFrame.scrolling = "no";
|
|
||||||
etherpadIFrame.width = $('#largeVideoContainer').width() || 640;
|
|
||||||
etherpadIFrame.height = $('#largeVideoContainer').height() || 480;
|
|
||||||
etherpadIFrame.setAttribute('style', 'visibility: hidden;');
|
|
||||||
|
|
||||||
document.getElementById('etherpad').appendChild(etherpadIFrame);
|
|
||||||
|
|
||||||
etherpadIFrame.onload = function() {
|
|
||||||
|
|
||||||
document.domain = document.domain;
|
|
||||||
bubbleIframeMouseMove(etherpadIFrame);
|
|
||||||
setTimeout(function() {
|
|
||||||
//the iframes inside of the etherpad are not yet loaded when the etherpad iframe is loaded
|
|
||||||
var outer = etherpadIFrame.contentDocument.getElementsByName("ace_outer")[0];
|
|
||||||
bubbleIframeMouseMove(outer);
|
|
||||||
var inner = outer.contentDocument.getElementsByName("ace_inner")[0];
|
|
||||||
bubbleIframeMouseMove(inner);
|
|
||||||
}, 2000);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function bubbleIframeMouseMove(iframe){
|
|
||||||
var existingOnMouseMove = iframe.contentWindow.onmousemove;
|
|
||||||
iframe.contentWindow.onmousemove = function(e){
|
|
||||||
if(existingOnMouseMove) existingOnMouseMove(e);
|
|
||||||
var evt = document.createEvent("MouseEvents");
|
|
||||||
var boundingClientRect = iframe.getBoundingClientRect();
|
|
||||||
evt.initMouseEvent(
|
|
||||||
"mousemove",
|
|
||||||
true, // bubbles
|
|
||||||
false, // not cancelable
|
|
||||||
window,
|
|
||||||
e.detail,
|
|
||||||
e.screenX,
|
|
||||||
e.screenY,
|
|
||||||
e.clientX + boundingClientRect.left,
|
|
||||||
e.clientY + boundingClientRect.top,
|
|
||||||
e.ctrlKey,
|
|
||||||
e.altKey,
|
|
||||||
e.shiftKey,
|
|
||||||
e.metaKey,
|
|
||||||
e.button,
|
|
||||||
null // no related element
|
|
||||||
);
|
|
||||||
iframe.dispatchEvent(evt);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On Etherpad added to muc.
|
|
||||||
*/
|
|
||||||
$(document).bind('etherpadadded.muc', function (event, jid, etherpadName) {
|
|
||||||
console.log("Etherpad added", etherpadName);
|
|
||||||
if (config.etherpad_base && !Moderator.isModerator()) {
|
|
||||||
Etherpad.init(etherpadName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On focus changed event.
|
|
||||||
*/
|
|
||||||
// FIXME: there is no such event as 'focusechanged.muc'
|
|
||||||
$(document).bind('focusechanged.muc', function (event, focus) {
|
|
||||||
console.log("Focus changed");
|
|
||||||
if (config.etherpad_base)
|
|
||||||
shareEtherpad();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On video selected event.
|
|
||||||
*/
|
|
||||||
$(document).bind('video.selected', function (event, isPresentation) {
|
|
||||||
if (!config.etherpad_base)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (etherpadIFrame && etherpadIFrame.style.visibility !== 'hidden')
|
|
||||||
Etherpad.toggleEtherpad(isPresentation);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resizes the etherpad, when the window is resized.
|
|
||||||
*/
|
|
||||||
$(window).resize(function () {
|
|
||||||
resize();
|
|
||||||
});
|
|
||||||
|
|
||||||
return my;
|
|
||||||
}(Etherpad || {}));
|
|
77
index.html
77
index.html
|
@ -31,44 +31,24 @@
|
||||||
<script src="libs/pako.bundle.js?v=1"></script><!-- zlib deflate -->
|
<script src="libs/pako.bundle.js?v=1"></script><!-- zlib deflate -->
|
||||||
<script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
|
<script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
|
||||||
<script src="interface_config.js?v=5"></script>
|
<script src="interface_config.js?v=5"></script>
|
||||||
|
<script src="service/RTC/RTCBrowserType.js?v=1"></script>
|
||||||
|
<script src="service/RTC/StreamEventTypes.js?v=1"></script>
|
||||||
|
<script src="service/RTC/MediaStreamTypes.js?v=1"></script>
|
||||||
|
<script src="libs/modules/UI.bundle.js?v=1"></script>
|
||||||
|
<script src="libs/modules/statistics.bundle.js?v=1"></script>
|
||||||
|
<script src="libs/modules/RTC.bundle.js?v=1"></script>
|
||||||
<script src="muc.js?v=17"></script><!-- simple MUC library -->
|
<script src="muc.js?v=17"></script><!-- simple MUC library -->
|
||||||
<script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
|
<script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
|
||||||
<script src="desktopsharing.js?v=3"></script><!-- desktop sharing -->
|
<script src="desktopsharing.js?v=3"></script><!-- desktop sharing -->
|
||||||
<script src="app.js?v=22"></script><!-- application logic -->
|
<script src="app.js?v=22"></script><!-- application logic -->
|
||||||
<script src="commands.js?v=1"></script><!-- application logic -->
|
|
||||||
<script src="chat.js?v=15"></script><!-- chat logic -->
|
|
||||||
<script src="contact_list.js?v=8"></script><!-- contact list logic -->
|
|
||||||
<script src="side_panel_toggler.js?v=1"></script>
|
|
||||||
<script src="util.js?v=7"></script><!-- utility functions -->
|
<script src="util.js?v=7"></script><!-- utility functions -->
|
||||||
<script src="etherpad.js?v=10"></script><!-- etherpad plugin -->
|
|
||||||
<script src="prezi.js?v=7"></script><!-- prezi plugin -->
|
|
||||||
<script src="smileys.js?v=3"></script><!-- smiley images -->
|
|
||||||
<script src="replacement.js?v=7"></script><!-- link and smiley replacement -->
|
|
||||||
<script src="moderatemuc.js?v=4"></script><!-- moderator plugin -->
|
<script src="moderatemuc.js?v=4"></script><!-- moderator plugin -->
|
||||||
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
|
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
|
||||||
<script src="videolayout.js?v=31"></script><!-- video ui -->
|
|
||||||
<script src="connectionquality.js?v=1"></script>
|
<script src="connectionquality.js?v=1"></script>
|
||||||
<script src="toolbar.js?v=7"></script><!-- toolbar ui -->
|
|
||||||
<script src="toolbar_toggler.js?v=2"></script>
|
|
||||||
<script src="canvas_util.js?v=1"></script><!-- canvas drawing utils -->
|
|
||||||
<script src="audio_levels.js?v=4"></script><!-- audio levels plugin -->
|
|
||||||
<script src="media_stream.js?v=2"></script><!-- media stream -->
|
|
||||||
<script src="bottom_toolbar.js?v=6"></script><!-- media stream -->
|
|
||||||
<script src="moderator.js?v=2"></script><!-- media stream -->
|
<script src="moderator.js?v=2"></script><!-- media stream -->
|
||||||
<script src="roomname_generator.js?v=1"></script><!-- generator for random room names -->
|
|
||||||
<script src="keyboard_shortcut.js?v=3"></script>
|
|
||||||
<script src="recording.js?v=1"></script>
|
|
||||||
<script src="tracking.js?v=1"></script><!-- tracking -->
|
<script src="tracking.js?v=1"></script><!-- tracking -->
|
||||||
<script src="jitsipopover.js?v=3"></script>
|
|
||||||
<script src="message_handler.js?v=2"></script>
|
|
||||||
<script src="api_connector.js?v=2"></script>
|
<script src="api_connector.js?v=2"></script>
|
||||||
<script src="settings_menu.js?v=1"></script>
|
<script src="keyboard_shortcut.js?v=1"></script>
|
||||||
<script src="service/RTC/RTCBrowserType.js?v=1"></script>
|
|
||||||
<script src="service/RTC/StreamEventTypes.js?v=1"></script>
|
|
||||||
<script src="service/RTC/MediaStreamTypes.js?v=1"></script>
|
|
||||||
<script src="libs/modules/statistics.bundle.js?v=1"></script>
|
|
||||||
<script src="libs/modules/RTC.bundle.js?v=1"></script>
|
|
||||||
<script src="avatar.js?v=4"></script><!-- avatars -->
|
|
||||||
<link rel="stylesheet" href="css/font.css?v=6"/>
|
<link rel="stylesheet" href="css/font.css?v=6"/>
|
||||||
<link rel="stylesheet" href="css/toastr.css?v=1">
|
<link rel="stylesheet" href="css/toastr.css?v=1">
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=30"/>
|
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=30"/>
|
||||||
|
@ -89,7 +69,6 @@
|
||||||
<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/diibjkoicjeejcmhdnailmkgecihlobk">
|
<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/diibjkoicjeejcmhdnailmkgecihlobk">
|
||||||
<script src="libs/jquery-impromptu.js"></script>
|
<script src="libs/jquery-impromptu.js"></script>
|
||||||
<script src="libs/jquery.autosize.js"></script>
|
<script src="libs/jquery.autosize.js"></script>
|
||||||
<script src="libs/prezi_player.js?v=2"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="welcome_page">
|
<div id="welcome_page">
|
||||||
|
@ -179,36 +158,36 @@
|
||||||
<div style="position: relative;" id="header_container">
|
<div style="position: relative;" id="header_container">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<span id="toolbar">
|
<span id="toolbar">
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="mutePopover" content="Mute / Unmute" onclick='toggleAudio();'>
|
<a class="button" id="toolbar_button_mute" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="mutePopover" content="Mute / Unmute">
|
||||||
<i id="mute" class="icon-microphone"></i>
|
<i id="mute" class="icon-microphone"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="toggleVideoPopover" content="Start / stop camera" onclick='toggleVideo();'>
|
<a class="button" id="toolbar_button_camera" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="toggleVideoPopover" content="Start / stop camera" onclick='toggleVideo();'>
|
||||||
<i id="video" class="icon-camera"></i>
|
<i id="video" class="icon-camera"></i>
|
||||||
</a>
|
</a>
|
||||||
<span id="authentication" style="display: none">
|
<span id="authentication" style="display: none">
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Authenticate" onclick='authenticateClicked();'>
|
<a class="button" id="toolbar_button_authentication" data-container="body" data-toggle="popover" data-placement="bottom" content="Authenticate">
|
||||||
<i id="authButton" class="icon-avatar"></i>
|
<i id="authButton" class="icon-avatar"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span id="recording" style="display: none">
|
<span id="recording" style="display: none">
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Record" onclick='toggleRecording();'>
|
<a class="button" id="toolbar_button_record" data-container="body" data-toggle="popover" data-placement="bottom" content="Record">
|
||||||
<i id="recordButton" class="icon-recEnable"></i>
|
<i id="recordButton" class="icon-recEnable"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Lock / unlock room" onclick="Toolbar.openLockDialog();">
|
<a class="button" id="toolbar_button_security" data-container="body" data-toggle="popover" data-placement="bottom" content="Lock / unlock room">
|
||||||
<i id="lockIcon" class="icon-security"></i>
|
<i id="lockIcon" class="icon-security"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Invite others" onclick="Toolbar.openLinkDialog();">
|
<a class="button" id="toolbar_button_link" data-container="body" data-toggle="popover" data-placement="bottom" content="Invite others">
|
||||||
<i class="icon-link"></i>
|
<i class="icon-link"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<span class="toolbar_span">
|
<span class="toolbar_span">
|
||||||
<a class="button" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="bottom" content="Open / close chat" onclick='BottomToolbar.toggleChat();'>
|
<a class="button" id="toolbar_button_chat" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="bottom" content="Open / close chat">
|
||||||
<i id="chatButton" class="icon-chat">
|
<i id="chatButton" class="icon-chat">
|
||||||
<span id="unreadMessages"></span>
|
<span id="unreadMessages"></span>
|
||||||
</i>
|
</i>
|
||||||
|
@ -216,38 +195,38 @@
|
||||||
</span>
|
</span>
|
||||||
<span id="prezi_button">
|
<span id="prezi_button">
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Share Prezi" onclick='Prezi.openPreziDialog();'>
|
<a class="button" id="toolbar_button_prezi" data-container="body" data-toggle="popover" data-placement="bottom" content="Share Prezi">
|
||||||
<i class="icon-prezi"></i>
|
<i class="icon-prezi"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span id="etherpadButton">
|
<span id="etherpadButton">
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Shared document" onclick='Etherpad.toggleEtherpad(0);'>
|
<a class="button" id="toolbar_button_etherpad" data-container="body" data-toggle="popover" data-placement="bottom" content="Shared document">
|
||||||
<i class="icon-share-doc"></i>
|
<i class="icon-share-doc"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<span id="desktopsharing" style="display: none">
|
<span id="desktopsharing" style="display: none">
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Share screen" onclick="toggleScreenSharing();">
|
<a class="button" id="toolbar_button_desktopsharing" data-container="body" data-toggle="popover" data-placement="bottom" content="Share screen">
|
||||||
<i class="icon-share-desktop"></i>
|
<i class="icon-share-desktop"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Enter / Exit Full Screen" onclick='buttonClick("#fullScreen", "icon-full-screen icon-exit-full-screen");Toolbar.toggleFullScreen();'>
|
<a class="button" id="toolbar_button_fullScreen" data-container="body" data-toggle="popover" data-placement="bottom" content="Enter / Exit Full Screen">
|
||||||
<i id="fullScreen" class="icon-full-screen"></i>
|
<i id="fullScreen" class="icon-full-screen"></i>
|
||||||
</a>
|
</a>
|
||||||
<span id="sipCallButton" style="display: none">
|
<span id="sipCallButton" style="display: none">
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Call SIP number" onclick='callSipButtonClicked();'>
|
<a class="button" id="toolbar_button_sip" data-container="body" data-toggle="popover" data-placement="bottom" content="Call SIP number">
|
||||||
<i class="icon-telephone"></i></a>
|
<i class="icon-telephone"></i></a>
|
||||||
</span>
|
</span>
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Settings" onclick='PanelToggler.toggleSettingsMenu();'>
|
<a class="button" id="toolbar_button_settings" data-container="body" data-toggle="popover" data-placement="bottom" content="Settings" >
|
||||||
<i id="settingsButton" class="icon-settings"></i>
|
<i id="settingsButton" class="icon-settings"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<span id="hangup">
|
<span id="hangup">
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Hang Up" onclick='hangup();'>
|
<a class="button" id="toolbar_button_hangup" data-container="body" data-toggle="popover" data-placement="bottom" content="Hang Up">
|
||||||
<i class="icon-hangup" style="color:#ff0000;font-size: 1.4em;"></i>
|
<i class="icon-hangup" style="color:#ff0000;font-size: 1.4em;"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
@ -264,8 +243,8 @@
|
||||||
<input id="connect" type="submit" value="Connect" />
|
<input id="connect" type="submit" value="Connect" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="reloadPresentation"><a onclick='Prezi.reloadPresentation();'><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
|
<div id="reloadPresentation"><a id="reloadPresentationLink"><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
|
||||||
<div id="videospace" onmousemove="ToolbarToggler.showToolbar();">
|
<div id="videospace">
|
||||||
<div id="largeVideoContainer" class="videocontainer">
|
<div id="largeVideoContainer" class="videocontainer">
|
||||||
<div id="presentation"></div>
|
<div id="presentation"></div>
|
||||||
<div id="etherpad"></div>
|
<div id="etherpad"></div>
|
||||||
|
@ -297,7 +276,7 @@
|
||||||
</div>
|
</div>
|
||||||
<span id="bottomToolbar">
|
<span id="bottomToolbar">
|
||||||
<span class="bottomToolbar_span">
|
<span class="bottomToolbar_span">
|
||||||
<a class="bottomToolbarButton" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="top" content="Open / close chat" onclick='BottomToolbar.toggleChat();'>
|
<a class="bottomToolbarButton" id="bottom_toolbar_chat" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="top" content="Open / close chat">
|
||||||
<i id="chatBottomButton" class="icon-chat-simple">
|
<i id="chatBottomButton" class="icon-chat-simple">
|
||||||
<span id="bottomUnreadMessages"></span>
|
<span id="bottomUnreadMessages"></span>
|
||||||
</i>
|
</i>
|
||||||
|
@ -305,7 +284,7 @@
|
||||||
</span>
|
</span>
|
||||||
<div class="bottom_button_separator"></div>
|
<div class="bottom_button_separator"></div>
|
||||||
<span class="bottomToolbar_span">
|
<span class="bottomToolbar_span">
|
||||||
<a class="bottomToolbarButton" data-container="body" data-toggle="popover" data-placement="top" id="contactlistpopover" content="Open / close contact list" onclick='BottomToolbar.toggleContactList();'>
|
<a class="bottomToolbarButton" id="bottom_toolbar_contact_list" data-container="body" data-toggle="popover" data-placement="top" id="contactlistpopover" content="Open / close contact list">
|
||||||
<i id="contactListButton" class="icon-contactList">
|
<i id="contactListButton" class="icon-contactList">
|
||||||
<span id="numberOfParticipants"></span>
|
<span id="numberOfParticipants"></span>
|
||||||
</i>
|
</i>
|
||||||
|
@ -313,7 +292,7 @@
|
||||||
</span>
|
</span>
|
||||||
<div class="bottom_button_separator"></div>
|
<div class="bottom_button_separator"></div>
|
||||||
<span class="bottomToolbar_span">
|
<span class="bottomToolbar_span">
|
||||||
<a class="bottomToolbarButton" data-container="body" data-toggle="popover" shortcut="filmstripPopover" data-placement="top" content="Show / hide film strip" onclick='BottomToolbar.toggleFilmStrip()'>
|
<a class="bottomToolbarButton" id="bottom_toolbar_film_strip" data-container="body" data-toggle="popover" shortcut="filmstripPopover" data-placement="top" content="Show / hide film strip">
|
||||||
<i id="filmStripButton" class="icon-filmstrip"></i>
|
<i id="filmStripButton" class="icon-filmstrip"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
@ -332,7 +311,7 @@
|
||||||
<audio id="chatNotification" src="sounds/incomingMessage.wav" preload="auto"></audio>
|
<audio id="chatNotification" src="sounds/incomingMessage.wav" preload="auto"></audio>
|
||||||
<textarea id="usermsg" placeholder='Enter text...' autofocus></textarea>
|
<textarea id="usermsg" placeholder='Enter text...' autofocus></textarea>
|
||||||
<div id="smileysarea">
|
<div id="smileysarea">
|
||||||
<div id="smileys" onclick="Chat.toggleSmileys()">
|
<div id="smileys" id="toggle_smileys">
|
||||||
<img src="images/smile.svg"/>
|
<img src="images/smile.svg"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -348,7 +327,7 @@
|
||||||
<div class="arrow-up"></div>
|
<div class="arrow-up"></div>
|
||||||
<input type="text" id="setDisplayName" placeholder="Name">
|
<input type="text" id="setDisplayName" placeholder="Name">
|
||||||
<input type="text" id="setEmail" placeholder="E-Mail">
|
<input type="text" id="setEmail" placeholder="E-Mail">
|
||||||
<button onclick="SettingsMenu.update()" id="updateSettings">Update</button>
|
<button id="updateSettings">Update</button>
|
||||||
</div>
|
</div>
|
||||||
<a id="downloadlog" onclick='dump(event.target);' data-container="body" data-toggle="popover" data-placement="right" data-content="Download logs" ><i class="fa fa-cloud-download"></i></a>
|
<a id="downloadlog" onclick='dump(event.target);' data-container="body" data-toggle="popover" data-placement="right" data-content="Download logs" ><i class="fa fa-cloud-download"></i></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,12 +4,12 @@ var KeyboardShortcut = (function(my) {
|
||||||
67: {
|
67: {
|
||||||
character: "C",
|
character: "C",
|
||||||
id: "toggleChatPopover",
|
id: "toggleChatPopover",
|
||||||
function: BottomToolbar.toggleChat
|
function: UI.toggleChat
|
||||||
},
|
},
|
||||||
70: {
|
70: {
|
||||||
character: "F",
|
character: "F",
|
||||||
id: "filmstripPopover",
|
id: "filmstripPopover",
|
||||||
function: BottomToolbar.toggleFilmStrip
|
function: UI.toggleFilmStrip
|
||||||
},
|
},
|
||||||
77: {
|
77: {
|
||||||
character: "M",
|
character: "M",
|
||||||
|
@ -45,7 +45,7 @@ var KeyboardShortcut = (function(my) {
|
||||||
}
|
}
|
||||||
//esc while the smileys are visible hides them
|
//esc while the smileys are visible hides them
|
||||||
} else if (keycode === 27 && $('#smileysContainer').is(':visible')) {
|
} else if (keycode === 27 && $('#smileysContainer').is(':visible')) {
|
||||||
Chat.toggleSmileys();
|
UI.toggleSmileys();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,12 @@ function ColibriFocus(connection, bridgejid) {
|
||||||
this.endpointsInfo = null;
|
this.endpointsInfo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function conferenceCreated(focus)
|
||||||
|
{
|
||||||
|
statistics.onConfereceCreated(getConferenceHandler());
|
||||||
|
RTC.onConfereceCreated(focus);
|
||||||
|
}
|
||||||
|
|
||||||
// creates a conferences with an initial set of peers
|
// creates a conferences with an initial set of peers
|
||||||
ColibriFocus.prototype.makeConference = function (peers, errorCallback) {
|
ColibriFocus.prototype.makeConference = function (peers, errorCallback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -411,7 +417,7 @@ ColibriFocus.prototype.createdConference = function (result) {
|
||||||
console.log('remote channels', this.channels);
|
console.log('remote channels', this.channels);
|
||||||
|
|
||||||
// Notify that the focus has created the conference on the bridge
|
// Notify that the focus has created the conference on the bridge
|
||||||
$(document).trigger('conferenceCreated.jingle', [self]);
|
conferenceCreated(self);
|
||||||
|
|
||||||
var bridgeSDP = new SDP(
|
var bridgeSDP = new SDP(
|
||||||
'v=0\r\n' +
|
'v=0\r\n' +
|
||||||
|
@ -561,8 +567,7 @@ ColibriFocus.prototype.createdConference = function (result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify we've created the conference
|
// Notify we've created the conference
|
||||||
$(document).trigger(
|
conferenceCreated(self);
|
||||||
'conferenceCreated.jingle', self);
|
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.warn('setLocalDescription failed.', error);
|
console.warn('setLocalDescription failed.', error);
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,23 @@
|
||||||
/* jshint -W117 */
|
/* jshint -W117 */
|
||||||
|
|
||||||
|
|
||||||
|
function CallIncomingJingle(sid) {
|
||||||
|
var sess = connection.jingle.sessions[sid];
|
||||||
|
|
||||||
|
// TODO: do we check activecall == null?
|
||||||
|
activecall = sess;
|
||||||
|
|
||||||
|
statistics.onConferenceCreated(sess);
|
||||||
|
RTC.onConferenceCreated(sess);
|
||||||
|
|
||||||
|
// TODO: check affiliation and/or role
|
||||||
|
console.log('emuc data for', sess.peerjid, connection.emuc.members[sess.peerjid]);
|
||||||
|
sess.usedrip = true; // not-so-naive trickle ice
|
||||||
|
sess.sendAnswer();
|
||||||
|
sess.accept();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
Strophe.addConnectionPlugin('jingle', {
|
Strophe.addConnectionPlugin('jingle', {
|
||||||
connection: null,
|
connection: null,
|
||||||
sessions: {},
|
sessions: {},
|
||||||
|
@ -110,7 +129,7 @@ Strophe.addConnectionPlugin('jingle', {
|
||||||
// the callback should either
|
// the callback should either
|
||||||
// .sendAnswer and .accept
|
// .sendAnswer and .accept
|
||||||
// or .sendTerminate -- not necessarily synchronus
|
// or .sendTerminate -- not necessarily synchronus
|
||||||
$(document).trigger('callincoming.jingle', [sess.sid]);
|
CallIncomingJingle(sess.sid);
|
||||||
break;
|
break;
|
||||||
case 'session-accept':
|
case 'session-accept':
|
||||||
sess.setRemoteDescription($(iq).find('>jingle'), 'answer');
|
sess.setRemoteDescription($(iq).find('>jingle'), 'answer');
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global $, $iq, config, connection, focusMucJid, forceMuted, messageHandler,
|
/* global $, $iq, config, connection, focusMucJid, forceMuted,
|
||||||
setAudioMuted, Strophe, toggleAudio */
|
setAudioMuted, Strophe, toggleAudio */
|
||||||
/**
|
/**
|
||||||
* Moderate connection plugin.
|
* Moderate connection plugin.
|
||||||
|
@ -32,10 +32,6 @@ Strophe.addConnectionPlugin('moderate', {
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.log('set mute error', error);
|
console.log('set mute error', error);
|
||||||
// FIXME: this causes an exception
|
|
||||||
//messageHandler.openReportDialog(null, 'Failed to mute ' +
|
|
||||||
// $("#participant_" + jid).find(".displayname").text() ||
|
|
||||||
//"participant" + '.', error);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onMute: function (iq) {
|
onMute: function (iq) {
|
||||||
|
|
41
moderator.js
41
moderator.js
|
@ -1,5 +1,5 @@
|
||||||
/* global $, $iq, config, connection, Etherpad, hangUp, messageHandler,
|
/* global $, $iq, config, connection, Etherpad, hangUp, messageHandler,
|
||||||
roomName, sessionTerminated, Strophe, Toolbar, Util, VideoLayout */
|
roomName, sessionTerminated, Strophe, Util */
|
||||||
/**
|
/**
|
||||||
* Contains logic responsible for enabling/disabling functionality available
|
* Contains logic responsible for enabling/disabling functionality available
|
||||||
* only to moderator users.
|
* only to moderator users.
|
||||||
|
@ -13,43 +13,24 @@ var Moderator = (function (my) {
|
||||||
var externalAuthEnabled = false;
|
var externalAuthEnabled = false;
|
||||||
|
|
||||||
my.isModerator = function () {
|
my.isModerator = function () {
|
||||||
return connection.emuc.isModerator();
|
return connection && connection.emuc.isModerator();
|
||||||
};
|
};
|
||||||
|
|
||||||
my.isPeerModerator = function (peerJid) {
|
my.isPeerModerator = function (peerJid) {
|
||||||
return connection.emuc.getMemberRole(peerJid) === 'moderator';
|
return connection && connection.emuc.getMemberRole(peerJid) === 'moderator';
|
||||||
};
|
};
|
||||||
|
|
||||||
my.isExternalAuthEnabled = function () {
|
my.isExternalAuthEnabled = function () {
|
||||||
return externalAuthEnabled;
|
return externalAuthEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
my.onModeratorStatusChanged = function (isModerator) {
|
my.init = function () {
|
||||||
|
Moderator.onLocalRoleChange = function (from, member, pres) {
|
||||||
Toolbar.showSipCallButton(isModerator);
|
UI.onModeratorStatusChanged(Moderator.isModerator());
|
||||||
Toolbar.showRecordingButton(
|
};
|
||||||
isModerator); //&&
|
|
||||||
// FIXME:
|
|
||||||
// Recording visible if
|
|
||||||
// there are at least 2(+ 1 focus) participants
|
|
||||||
//Object.keys(connection.emuc.members).length >= 3);
|
|
||||||
|
|
||||||
if (isModerator && config.etherpad_base) {
|
|
||||||
Etherpad.init();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
my.init = function () {
|
my.onMucLeft = function (jid) {
|
||||||
$(document).bind(
|
|
||||||
'local.role.changed.muc',
|
|
||||||
function (event, jid, info, pres) {
|
|
||||||
Moderator.onModeratorStatusChanged(Moderator.isModerator());
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
$(document).bind(
|
|
||||||
'left.muc',
|
|
||||||
function (event, jid) {
|
|
||||||
console.info("Someone left is it focus ? " + jid);
|
console.info("Someone left is it focus ? " + jid);
|
||||||
var resource = Strophe.getResourceFromJid(jid);
|
var resource = Strophe.getResourceFromJid(jid);
|
||||||
if (resource === 'focus' && !sessionTerminated) {
|
if (resource === 'focus' && !sessionTerminated) {
|
||||||
|
@ -61,8 +42,6 @@ var Moderator = (function (my) {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
my.setFocusUserJid = function (focusJid) {
|
my.setFocusUserJid = function (focusJid) {
|
||||||
if (!focusUserJid) {
|
if (!focusUserJid) {
|
||||||
|
@ -185,13 +164,13 @@ var Moderator = (function (my) {
|
||||||
// Not authorized to create new room
|
// Not authorized to create new room
|
||||||
if ($(error).find('>error>not-authorized').length) {
|
if ($(error).find('>error>not-authorized').length) {
|
||||||
console.warn("Unauthorized to start the conference");
|
console.warn("Unauthorized to start the conference");
|
||||||
$(document).trigger('auth_required.moderator');
|
UI.onAuthenticationRequired();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var waitMs = getNextErrorTimeout();
|
var waitMs = getNextErrorTimeout();
|
||||||
console.error("Focus error, retry after " + waitMs, error);
|
console.error("Focus error, retry after " + waitMs, error);
|
||||||
// Show message
|
// Show message
|
||||||
messageHandler.notify(
|
UI.messageHandler.notify(
|
||||||
'Conference focus', 'disconnected',
|
'Conference focus', 'disconnected',
|
||||||
Moderator.getFocusComponent() +
|
Moderator.getFocusComponent() +
|
||||||
' not available - retry in ' + (waitMs / 1000) + ' sec');
|
' not available - retry in ' + (waitMs / 1000) + ' sec');
|
||||||
|
|
|
@ -32,7 +32,7 @@ var DataChannels =
|
||||||
// selections so that it can do adaptive simulcast,
|
// selections so that it can do adaptive simulcast,
|
||||||
// we want the notification to trigger even if userJid is undefined,
|
// we want the notification to trigger even if userJid is undefined,
|
||||||
// or null.
|
// or null.
|
||||||
var userJid = VideoLayout.getLargeVideoState().userJid;
|
var userJid = UI.getLargeVideoState().userJid;
|
||||||
// we want the notification to trigger even if userJid is undefined,
|
// we want the notification to trigger even if userJid is undefined,
|
||||||
// or null.
|
// or null.
|
||||||
onSelectedEndpointChanged(userJid);
|
onSelectedEndpointChanged(userJid);
|
||||||
|
|
|
@ -245,7 +245,7 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
RTCUtils.getUserMedia(constraints,
|
this.getUserMedia(constraints,
|
||||||
function (stream) {
|
function (stream) {
|
||||||
console.log('onUserMediaSuccess');
|
console.log('onUserMediaSuccess');
|
||||||
success_callback(stream);
|
success_callback(stream);
|
||||||
|
@ -296,7 +296,7 @@ RTCUtils.prototype.obtainAudioAndVideoPermissions = function() {
|
||||||
media: error.media || 'video',
|
media: error.media || 'video',
|
||||||
name : error.name
|
name : error.name
|
||||||
});
|
});
|
||||||
messageHandler.showError("Error",
|
UI.messageHandler.showError("Error",
|
||||||
"Failed to obtain permissions to use the local microphone" +
|
"Failed to obtain permissions to use the local microphone" +
|
||||||
"and/or camera.");
|
"and/or camera.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,545 @@
|
||||||
|
var UI = {};
|
||||||
|
|
||||||
|
var VideoLayout = require("./videolayout/VideoLayout.js");
|
||||||
|
var AudioLevels = require("./audio_levels/AudioLevels.js");
|
||||||
|
var Prezi = require("./prezi/Prezi.js");
|
||||||
|
var Etherpad = require("./etherpad/Etherpad.js");
|
||||||
|
var Chat = require("./side_pannels/chat/Chat.js");
|
||||||
|
var Toolbar = require("./toolbars/toolbar");
|
||||||
|
var ToolbarToggler = require("./toolbars/toolbartoggler");
|
||||||
|
var BottomToolbar = require("./toolbars/BottomToolbar");
|
||||||
|
var ContactList = require("./side_pannels/contactlist/ContactList");
|
||||||
|
var Avatar = require("./avatar/Avatar");
|
||||||
|
//var EventEmitter = require("events");
|
||||||
|
var SettingsMenu = require("./side_pannels/settings/SettingsMenu");
|
||||||
|
var Settings = require("./side_pannels/settings/Settings");
|
||||||
|
var PanelToggler = require("./side_pannels/SidePanelToggler");
|
||||||
|
var RoomNameGenerator = require("./welcome_page/RoomnameGenerator");
|
||||||
|
UI.messageHandler = require("./util/MessageHandler");
|
||||||
|
var messageHandler = UI.messageHandler;
|
||||||
|
|
||||||
|
//var eventEmitter = new EventEmitter();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function setupPrezi()
|
||||||
|
{
|
||||||
|
$("#reloadPresentationLink").click(function()
|
||||||
|
{
|
||||||
|
Prezi.reloadPresentation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupChat()
|
||||||
|
{
|
||||||
|
Chat.init();
|
||||||
|
$("#toggle_smileys").click(function() {
|
||||||
|
Chat.toggleSmileys();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupToolbars() {
|
||||||
|
Toolbar.init();
|
||||||
|
Toolbar.setupButtonsFromConfig();
|
||||||
|
BottomToolbar.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function registerListeners() {
|
||||||
|
RTC.addStreamListener(function (stream) {
|
||||||
|
switch (stream.type)
|
||||||
|
{
|
||||||
|
case "audio":
|
||||||
|
VideoLayout.changeLocalAudio(stream.getOriginalStream());
|
||||||
|
break;
|
||||||
|
case "video":
|
||||||
|
VideoLayout.changeLocalVideo(stream.getOriginalStream(), true);
|
||||||
|
break;
|
||||||
|
case "stream":
|
||||||
|
VideoLayout.changeLocalStream(stream.getOriginalStream());
|
||||||
|
break;
|
||||||
|
case "desktop":
|
||||||
|
VideoLayout.changeLocalVideo(stream, !isUsingScreenStream);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
|
||||||
|
|
||||||
|
RTC.addStreamListener(function (stream) {
|
||||||
|
VideoLayout.onRemoteStreamAdded(stream);
|
||||||
|
}, StreamEventTypes.EVENT_TYPE_REMOTE_CREATED);
|
||||||
|
|
||||||
|
// Listen for large video size updates
|
||||||
|
document.getElementById('largeVideo')
|
||||||
|
.addEventListener('loadedmetadata', function (e) {
|
||||||
|
currentVideoWidth = this.videoWidth;
|
||||||
|
currentVideoHeight = this.videoHeight;
|
||||||
|
VideoLayout.positionLarge(currentVideoWidth, currentVideoHeight);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
statistics.addAudioLevelListener(function(jid, audioLevel)
|
||||||
|
{
|
||||||
|
var resourceJid;
|
||||||
|
if(jid === statistics.LOCAL_JID)
|
||||||
|
{
|
||||||
|
resourceJid = AudioLevels.LOCAL_LEVEL;
|
||||||
|
if(isAudioMuted())
|
||||||
|
{
|
||||||
|
audioLevel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resourceJid = Strophe.getResourceFromJid(jid);
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioLevels.updateAudioLevel(resourceJid, audioLevel,
|
||||||
|
UI.getLargeVideoState().userResourceJid);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindEvents()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Resizes and repositions videos in full screen mode.
|
||||||
|
*/
|
||||||
|
$(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange',
|
||||||
|
function () {
|
||||||
|
VideoLayout.resizeLargeVideoContainer();
|
||||||
|
VideoLayout.positionLarge();
|
||||||
|
isFullScreen = document.fullScreen ||
|
||||||
|
document.mozFullScreen ||
|
||||||
|
document.webkitIsFullScreen;
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$(window).resize(function () {
|
||||||
|
VideoLayout.resizeLargeVideoContainer();
|
||||||
|
VideoLayout.positionLarge();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.start = function () {
|
||||||
|
document.title = interfaceConfig.APP_NAME;
|
||||||
|
if(config.enableWelcomePage && window.location.pathname == "/" &&
|
||||||
|
(!window.localStorage.welcomePageDisabled || window.localStorage.welcomePageDisabled == "false"))
|
||||||
|
{
|
||||||
|
$("#videoconference_page").hide();
|
||||||
|
var setupWelcomePage = require("./welcome_page/WelcomePage");
|
||||||
|
setupWelcomePage();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceConfig.SHOW_JITSI_WATERMARK) {
|
||||||
|
var leftWatermarkDiv
|
||||||
|
= $("#largeVideoContainer div[class='watermark leftwatermark']");
|
||||||
|
|
||||||
|
leftWatermarkDiv.css({display: 'block'});
|
||||||
|
leftWatermarkDiv.parent().get(0).href
|
||||||
|
= interfaceConfig.JITSI_WATERMARK_LINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceConfig.SHOW_BRAND_WATERMARK) {
|
||||||
|
var rightWatermarkDiv
|
||||||
|
= $("#largeVideoContainer div[class='watermark rightwatermark']");
|
||||||
|
|
||||||
|
rightWatermarkDiv.css({display: 'block'});
|
||||||
|
rightWatermarkDiv.parent().get(0).href
|
||||||
|
= interfaceConfig.BRAND_WATERMARK_LINK;
|
||||||
|
rightWatermarkDiv.get(0).style.backgroundImage
|
||||||
|
= "url(images/rightwatermark.png)";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceConfig.SHOW_POWERED_BY) {
|
||||||
|
$("#largeVideoContainer>a[class='poweredby']").css({display: 'block'});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#welcome_page").hide();
|
||||||
|
|
||||||
|
$('body').popover({ selector: '[data-toggle=popover]',
|
||||||
|
trigger: 'click hover',
|
||||||
|
content: function() {
|
||||||
|
return this.getAttribute("content") +
|
||||||
|
KeyboardShortcut.getShortcut(this.getAttribute("shortcut"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
VideoLayout.resizeLargeVideoContainer();
|
||||||
|
$("#videospace").mousemove(function () {
|
||||||
|
return ToolbarToggler.showToolbar();
|
||||||
|
});
|
||||||
|
// Set the defaults for prompt dialogs.
|
||||||
|
jQuery.prompt.setDefaults({persistent: false});
|
||||||
|
|
||||||
|
// KeyboardShortcut.init();
|
||||||
|
registerListeners();
|
||||||
|
bindEvents();
|
||||||
|
setupPrezi();
|
||||||
|
setupToolbars();
|
||||||
|
setupChat();
|
||||||
|
|
||||||
|
document.title = interfaceConfig.APP_NAME;
|
||||||
|
|
||||||
|
$("#downloadlog").click(function (event) {
|
||||||
|
dump(event.target);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(config.enableWelcomePage && window.location.pathname == "/" &&
|
||||||
|
(!window.localStorage.welcomePageDisabled || window.localStorage.welcomePageDisabled == "false"))
|
||||||
|
{
|
||||||
|
$("#videoconference_page").hide();
|
||||||
|
var setupWelcomePage = require("./welcome_page/WelcomePage");
|
||||||
|
setupWelcomePage();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#welcome_page").hide();
|
||||||
|
|
||||||
|
document.getElementById('largeVideo').volume = 0;
|
||||||
|
|
||||||
|
if (!$('#settings').is(':visible')) {
|
||||||
|
console.log('init');
|
||||||
|
init();
|
||||||
|
} else {
|
||||||
|
loginInfo.onsubmit = function (e) {
|
||||||
|
if (e.preventDefault) e.preventDefault();
|
||||||
|
$('#settings').hide();
|
||||||
|
init();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
toastr.options = {
|
||||||
|
"closeButton": true,
|
||||||
|
"debug": false,
|
||||||
|
"positionClass": "notification-bottom-right",
|
||||||
|
"onclick": null,
|
||||||
|
"showDuration": "300",
|
||||||
|
"hideDuration": "1000",
|
||||||
|
"timeOut": "2000",
|
||||||
|
"extendedTimeOut": "1000",
|
||||||
|
"showEasing": "swing",
|
||||||
|
"hideEasing": "linear",
|
||||||
|
"showMethod": "fadeIn",
|
||||||
|
"hideMethod": "fadeOut",
|
||||||
|
"reposition": function() {
|
||||||
|
if(PanelToggler.isVisible()) {
|
||||||
|
$("#toast-container").addClass("notification-bottom-right-center");
|
||||||
|
} else {
|
||||||
|
$("#toast-container").removeClass("notification-bottom-right-center");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"newestOnTop": false
|
||||||
|
};
|
||||||
|
|
||||||
|
$('#settingsmenu>input').keyup(function(event){
|
||||||
|
if(event.keyCode === 13) {//enter
|
||||||
|
SettingsMenu.update();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#updateSettings").click(function () {
|
||||||
|
SettingsMenu.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UI.setUserAvatar = function (jid, id) {
|
||||||
|
Avatar.setUserAvatar(jid, id);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.toggleSmileys = function () {
|
||||||
|
Chat.toggleSmileys();
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.chatAddError = function(errorMessage, originalText)
|
||||||
|
{
|
||||||
|
return Chat.chatAddError(errorMessage, originalText);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.chatSetSubject = function(text)
|
||||||
|
{
|
||||||
|
return Chat.chatSetSubject(text);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.updateChatConversation = function (from, displayName, message) {
|
||||||
|
return Chat.updateChatConversation(from, displayName, message);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onMucJoined = function (jid, info) {
|
||||||
|
Toolbar.updateRoomUrl(window.location.href);
|
||||||
|
document.getElementById('localNick').appendChild(
|
||||||
|
document.createTextNode(Strophe.getResourceFromJid(jid) + ' (me)')
|
||||||
|
);
|
||||||
|
|
||||||
|
var settings = Settings.getSettings();
|
||||||
|
// Add myself to the contact list.
|
||||||
|
ContactList.addContact(jid, settings.email || settings.uid);
|
||||||
|
|
||||||
|
// Once we've joined the muc show the toolbar
|
||||||
|
ToolbarToggler.showToolbar();
|
||||||
|
|
||||||
|
// Show authenticate button if needed
|
||||||
|
Toolbar.showAuthenticateButton(
|
||||||
|
Moderator.isExternalAuthEnabled() && !Moderator.isModerator());
|
||||||
|
|
||||||
|
var displayName = !config.displayJids
|
||||||
|
? info.displayName : Strophe.getResourceFromJid(jid);
|
||||||
|
|
||||||
|
if (displayName)
|
||||||
|
$(document).trigger('displaynamechanged',
|
||||||
|
['localVideoContainer', displayName + ' (me)']);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.initEtherpad = function (name) {
|
||||||
|
Etherpad.init(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onMucLeft = function (jid) {
|
||||||
|
console.log('left.muc', jid);
|
||||||
|
var displayName = $('#participant_' + Strophe.getResourceFromJid(jid) +
|
||||||
|
'>.displayname').html();
|
||||||
|
messageHandler.notify(displayName || 'Somebody',
|
||||||
|
'disconnected',
|
||||||
|
'disconnected');
|
||||||
|
// Need to call this with a slight delay, otherwise the element couldn't be
|
||||||
|
// found for some reason.
|
||||||
|
// XXX(gp) it works fine without the timeout for me (with Chrome 38).
|
||||||
|
window.setTimeout(function () {
|
||||||
|
var container = document.getElementById(
|
||||||
|
'participant_' + Strophe.getResourceFromJid(jid));
|
||||||
|
if (container) {
|
||||||
|
ContactList.removeContact(jid);
|
||||||
|
VideoLayout.removeConnectionIndicator(jid);
|
||||||
|
// hide here, wait for video to close before removing
|
||||||
|
$(container).hide();
|
||||||
|
VideoLayout.resizeThumbnails();
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
// Unlock large video
|
||||||
|
if (focusedVideoInfo && focusedVideoInfo.jid === jid)
|
||||||
|
{
|
||||||
|
console.info("Focused video owner has left the conference");
|
||||||
|
focusedVideoInfo = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.getSettings = function () {
|
||||||
|
return Settings.getSettings();
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.toggleFilmStrip = function () {
|
||||||
|
return BottomToolbar.toggleFilmStrip();
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.toggleChat = function () {
|
||||||
|
return BottomToolbar.toggleChat();
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.toggleContactList = function () {
|
||||||
|
return BottomToolbar.toggleContactList();
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onLocalRoleChange = function (jid, info, pres) {
|
||||||
|
|
||||||
|
console.info("My role changed, new role: " + info.role);
|
||||||
|
var isModerator = Moderator.isModerator();
|
||||||
|
|
||||||
|
VideoLayout.showModeratorIndicator();
|
||||||
|
Toolbar.showAuthenticateButton(
|
||||||
|
Moderator.isExternalAuthEnabled() && !isModerator);
|
||||||
|
|
||||||
|
if (isModerator) {
|
||||||
|
Toolbar.closeAuthenticationWindow();
|
||||||
|
messageHandler.notify(
|
||||||
|
'Me', 'connected', 'Moderator rights granted !');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onDisposeConference = function (unload) {
|
||||||
|
Toolbar.showAuthenticateButton(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onModeratorStatusChanged = function (isModerator) {
|
||||||
|
|
||||||
|
Toolbar.showSipCallButton(isModerator);
|
||||||
|
Toolbar.showRecordingButton(
|
||||||
|
isModerator); //&&
|
||||||
|
// FIXME:
|
||||||
|
// Recording visible if
|
||||||
|
// there are at least 2(+ 1 focus) participants
|
||||||
|
//Object.keys(connection.emuc.members).length >= 3);
|
||||||
|
|
||||||
|
if (isModerator && config.etherpad_base) {
|
||||||
|
Etherpad.init();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onPasswordReqiured = function (callback) {
|
||||||
|
// password is required
|
||||||
|
Toolbar.lockLockButton();
|
||||||
|
|
||||||
|
messageHandler.openTwoButtonDialog(null,
|
||||||
|
'<h2>Password required</h2>' +
|
||||||
|
'<input id="lockKey" type="text" placeholder="password" autofocus>',
|
||||||
|
true,
|
||||||
|
"Ok",
|
||||||
|
function (e, v, m, f) {},
|
||||||
|
function (event) {
|
||||||
|
document.getElementById('lockKey').focus();
|
||||||
|
},
|
||||||
|
function (e, v, m, f) {
|
||||||
|
if (v) {
|
||||||
|
var lockKey = document.getElementById('lockKey');
|
||||||
|
if (lockKey.value !== null) {
|
||||||
|
Toolbar.setSharedKey(lockKey.value);
|
||||||
|
callback(lockKey.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onAuthenticationRequired = function () {
|
||||||
|
// extract room name from 'room@muc.server.net'
|
||||||
|
var room = roomName.substr(0, roomName.indexOf('@'));
|
||||||
|
|
||||||
|
messageHandler.openDialog(
|
||||||
|
'Stop',
|
||||||
|
'Authentication is required to create room:<br/>' + room,
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
Authenticate: 'authNow',
|
||||||
|
Close: 'close'
|
||||||
|
},
|
||||||
|
function (onSubmitEvent, submitValue) {
|
||||||
|
console.info('On submit: ' + submitValue, submitValue);
|
||||||
|
if (submitValue === 'authNow') {
|
||||||
|
Toolbar.authenticateClicked();
|
||||||
|
} else {
|
||||||
|
Toolbar.showAuthenticateButton(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.setRecordingButtonState = function (state) {
|
||||||
|
Toolbar.setRecordingButtonState(state);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.changeDesktopSharingButtonState = function (isUsingScreenStream) {
|
||||||
|
Toolbar.changeDesktopSharingButtonState(isUsingScreenStream);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.inputDisplayNameHandler = function (value) {
|
||||||
|
VideoLayout.inputDisplayNameHandler(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onMucEntered = function (jid, id, displayName) {
|
||||||
|
messageHandler.notify(displayName || 'Somebody',
|
||||||
|
'connected',
|
||||||
|
'connected');
|
||||||
|
|
||||||
|
// Add Peer's container
|
||||||
|
VideoLayout.ensurePeerContainerExists(jid,id);
|
||||||
|
|
||||||
|
if(APIConnector.isEnabled() &&
|
||||||
|
APIConnector.isEventEnabled("participantJoined"))
|
||||||
|
{
|
||||||
|
APIConnector.triggerEvent("participantJoined",{jid: jid});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onMucPresenceStatus = function ( jid, info) {
|
||||||
|
VideoLayout.setPresenceStatus(
|
||||||
|
'participant_' + Strophe.getResourceFromJid(jid), info.status);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onMucRoleChanged = function (role, displayName) {
|
||||||
|
VideoLayout.showModeratorIndicator();
|
||||||
|
|
||||||
|
if (role === 'moderator') {
|
||||||
|
var displayName = displayName;
|
||||||
|
if (!displayName) {
|
||||||
|
displayName = 'Somebody';
|
||||||
|
}
|
||||||
|
messageHandler.notify(
|
||||||
|
displayName,
|
||||||
|
'connected',
|
||||||
|
'Moderator rights granted to ' + displayName + '!');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.updateLocalConnectionStats = function(percent, stats)
|
||||||
|
{
|
||||||
|
VideoLayout.updateLocalConnectionStats(percent, stats);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.updateConnectionStats = function(jid, percent, stats)
|
||||||
|
{
|
||||||
|
VideoLayout.updateConnectionStats(jid, percent, stats);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.onStatsStop = function () {
|
||||||
|
VideoLayout.onStatsStop();
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.getLargeVideoState = function()
|
||||||
|
{
|
||||||
|
return VideoLayout.getLargeVideoState();
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.showLocalAudioIndicator = function (mute) {
|
||||||
|
VideoLayout.showLocalAudioIndicator(mute);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.changeLocalVideo = function (stream, flipx) {
|
||||||
|
VideoLayout.changeLocalVideo(stream, flipx);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.generateRoomName = function() {
|
||||||
|
var roomnode = null;
|
||||||
|
var path = window.location.pathname;
|
||||||
|
|
||||||
|
// determinde the room node from the url
|
||||||
|
// TODO: just the roomnode or the whole bare jid?
|
||||||
|
if (config.getroomnode && typeof config.getroomnode === 'function') {
|
||||||
|
// custom function might be responsible for doing the pushstate
|
||||||
|
roomnode = config.getroomnode(path);
|
||||||
|
} else {
|
||||||
|
/* fall back to default strategy
|
||||||
|
* this is making assumptions about how the URL->room mapping happens.
|
||||||
|
* It currently assumes deployment at root, with a rewrite like the
|
||||||
|
* following one (for nginx):
|
||||||
|
location ~ ^/([a-zA-Z0-9]+)$ {
|
||||||
|
rewrite ^/(.*)$ / break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (path.length > 1) {
|
||||||
|
roomnode = path.substr(1).toLowerCase();
|
||||||
|
} else {
|
||||||
|
var word = RoomNameGenerator.generateRoomWithoutSeparator();
|
||||||
|
roomnode = word.toLowerCase();
|
||||||
|
|
||||||
|
window.history.pushState('VideoChat',
|
||||||
|
'Room: ' + word, window.location.pathname + word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
roomName = roomnode + '@' + config.hosts.muc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UI.connectionIndicatorShowMore = function(id)
|
||||||
|
{
|
||||||
|
return VideoLayout.connectionIndicators[id].showMore();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = UI;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
var CanvasUtil = require("./CanvasUtils");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The audio Levels plugin.
|
* The audio Levels plugin.
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +12,7 @@ var AudioLevels = (function(my) {
|
||||||
* Updates the audio level canvas for the given peerJid. If the canvas
|
* Updates the audio level canvas for the given peerJid. If the canvas
|
||||||
* didn't exist we create it.
|
* didn't exist we create it.
|
||||||
*/
|
*/
|
||||||
my.updateAudioLevelCanvas = function (peerJid) {
|
my.updateAudioLevelCanvas = function (peerJid, VideoLayout) {
|
||||||
var resourceJid = null;
|
var resourceJid = null;
|
||||||
var videoSpanId = null;
|
var videoSpanId = null;
|
||||||
if (!peerJid)
|
if (!peerJid)
|
||||||
|
@ -66,7 +68,7 @@ var AudioLevels = (function(my) {
|
||||||
* which we draw the audio level
|
* which we draw the audio level
|
||||||
* @param audioLevel the newAudio level to render
|
* @param audioLevel the newAudio level to render
|
||||||
*/
|
*/
|
||||||
my.updateAudioLevel = function (resourceJid, audioLevel) {
|
my.updateAudioLevel = function (resourceJid, audioLevel, largeVideoResourceJid) {
|
||||||
drawAudioLevelCanvas(resourceJid, audioLevel);
|
drawAudioLevelCanvas(resourceJid, audioLevel);
|
||||||
|
|
||||||
var videoSpanId = getVideoSpanId(resourceJid);
|
var videoSpanId = getVideoSpanId(resourceJid);
|
||||||
|
@ -91,7 +93,7 @@ var AudioLevels = (function(my) {
|
||||||
resourceJid = Strophe.getResourceFromJid(connection.emuc.myroomjid);
|
resourceJid = Strophe.getResourceFromJid(connection.emuc.myroomjid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(resourceJid === VideoLayout.getLargeVideoState().userResourceJid) {
|
if(resourceJid === largeVideoResourceJid) {
|
||||||
AudioLevels.updateActiveSpeakerAudioLevel(audioLevel);
|
AudioLevels.updateActiveSpeakerAudioLevel(audioLevel);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -258,3 +260,5 @@ var AudioLevels = (function(my) {
|
||||||
return my;
|
return my;
|
||||||
|
|
||||||
})(AudioLevels || {});
|
})(AudioLevels || {});
|
||||||
|
|
||||||
|
module.exports = AudioLevels;
|
|
@ -107,3 +107,5 @@ var CanvasUtil = (function(my) {
|
||||||
|
|
||||||
return my;
|
return my;
|
||||||
})(CanvasUtil || {});
|
})(CanvasUtil || {});
|
||||||
|
|
||||||
|
module.exports = CanvasUtil;
|
|
@ -1,15 +1,50 @@
|
||||||
var Avatar = (function(my) {
|
var Settings = require("../side_pannels/settings/Settings");
|
||||||
var users = {};
|
|
||||||
var activeSpeakerJid;
|
var users = {};
|
||||||
|
var activeSpeakerJid;
|
||||||
|
|
||||||
|
function setVisibility(selector, show) {
|
||||||
|
if (selector && selector.length > 0) {
|
||||||
|
selector.css("visibility", show ? "visible" : "hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isUserMuted(jid) {
|
||||||
|
// XXX(gp) we may want to rename this method to something like
|
||||||
|
// isUserStreaming, for example.
|
||||||
|
if (jid && jid != connection.emuc.myroomjid) {
|
||||||
|
var resource = Strophe.getResourceFromJid(jid);
|
||||||
|
if (!require("../videolayout/VideoLayout").isInLastN(resource)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!RTC.remoteStreams[jid] || !RTC.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return RTC.remoteStreams[jid][MediaStreamType.VIDEO_TYPE].muted;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGravatarUrl(id, size) {
|
||||||
|
if(id === connection.emuc.myroomjid || !id) {
|
||||||
|
id = Settings.getSettings().uid;
|
||||||
|
}
|
||||||
|
return 'https://www.gravatar.com/avatar/' +
|
||||||
|
MD5.hexdigest(id.trim().toLowerCase()) +
|
||||||
|
"?d=wavatar&size=" + (size || "30");
|
||||||
|
}
|
||||||
|
|
||||||
|
var Avatar = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
* and thumbnail
|
* and thumbnail
|
||||||
* @param jid jid of the user
|
* @param jid jid of the user
|
||||||
* @param id email or userID to be used as a hash
|
* @param id email or userID to be used as a hash
|
||||||
*/
|
*/
|
||||||
my.setUserAvatar = function(jid, id) {
|
setUserAvatar: function (jid, id) {
|
||||||
if(id) {
|
if (id) {
|
||||||
if(users[jid] === id) {
|
if (users[jid] === id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
users[jid] = id;
|
users[jid] = id;
|
||||||
|
@ -22,19 +57,19 @@ var Avatar = (function(my) {
|
||||||
|
|
||||||
// set the avatar in the settings menu if it is local user and get the
|
// set the avatar in the settings menu if it is local user and get the
|
||||||
// local video container
|
// local video container
|
||||||
if(jid === connection.emuc.myroomjid) {
|
if (jid === connection.emuc.myroomjid) {
|
||||||
$('#avatar').get(0).src = thumbUrl;
|
$('#avatar').get(0).src = thumbUrl;
|
||||||
thumbnail = $('#localVideoContainer');
|
thumbnail = $('#localVideoContainer');
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the avatar in the contact list
|
// set the avatar in the contact list
|
||||||
var contact = $('#' + resourceJid + '>img');
|
var contact = $('#' + resourceJid + '>img');
|
||||||
if(contact && contact.length > 0) {
|
if (contact && contact.length > 0) {
|
||||||
contact.get(0).src = contactListUrl;
|
contact.get(0).src = contactListUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the avatar in the thumbnail
|
// set the avatar in the thumbnail
|
||||||
if(avatar && avatar.length > 0) {
|
if (avatar && avatar.length > 0) {
|
||||||
avatar[0].src = thumbUrl;
|
avatar[0].src = thumbUrl;
|
||||||
} else {
|
} else {
|
||||||
if (thumbnail && thumbnail.length > 0) {
|
if (thumbnail && thumbnail.length > 0) {
|
||||||
|
@ -48,10 +83,10 @@ var Avatar = (function(my) {
|
||||||
|
|
||||||
//if the user is the current active speaker - update the active speaker
|
//if the user is the current active speaker - update the active speaker
|
||||||
// avatar
|
// avatar
|
||||||
if(jid === activeSpeakerJid) {
|
if (jid === activeSpeakerJid) {
|
||||||
Avatar.updateActiveSpeakerAvatarSrc(jid);
|
this.updateActiveSpeakerAvatarSrc(jid);
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides or shows the user's avatar
|
* Hides or shows the user's avatar
|
||||||
|
@ -59,23 +94,23 @@ var Avatar = (function(my) {
|
||||||
* @param show whether we should show the avatar or not
|
* @param show whether we should show the avatar or not
|
||||||
* video because there is no dominant speaker and no focused speaker
|
* video because there is no dominant speaker and no focused speaker
|
||||||
*/
|
*/
|
||||||
my.showUserAvatar = function(jid, show) {
|
showUserAvatar: function (jid, show) {
|
||||||
if(users[jid]) {
|
if (users[jid]) {
|
||||||
var resourceJid = Strophe.getResourceFromJid(jid);
|
var resourceJid = Strophe.getResourceFromJid(jid);
|
||||||
var video = $('#participant_' + resourceJid + '>video');
|
var video = $('#participant_' + resourceJid + '>video');
|
||||||
var avatar = $('#avatar_' + resourceJid);
|
var avatar = $('#avatar_' + resourceJid);
|
||||||
|
|
||||||
if(jid === connection.emuc.myroomjid) {
|
if (jid === connection.emuc.myroomjid) {
|
||||||
video = $('#localVideoWrapper>video');
|
video = $('#localVideoWrapper>video');
|
||||||
}
|
}
|
||||||
if(show === undefined || show === null) {
|
if (show === undefined || show === null) {
|
||||||
show = isUserMuted(jid);
|
show = isUserMuted(jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the user is the currently focused, the dominant speaker or if
|
//if the user is the currently focused, the dominant speaker or if
|
||||||
//there is no focused and no dominant speaker and the large video is
|
//there is no focused and no dominant speaker and the large video is
|
||||||
//currently shown
|
//currently shown
|
||||||
if (activeSpeakerJid === jid && VideoLayout.isLargeVideoOnTop()) {
|
if (activeSpeakerJid === jid && require("../videolayout/VideoLayout").isLargeVideoOnTop()) {
|
||||||
setVisibility($("#largeVideo"), !show);
|
setVisibility($("#largeVideo"), !show);
|
||||||
setVisibility($('#activeSpeaker'), show);
|
setVisibility($('#activeSpeaker'), show);
|
||||||
setVisibility(avatar, false);
|
setVisibility(avatar, false);
|
||||||
|
@ -87,62 +122,33 @@ var Avatar = (function(my) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the src of the active speaker avatar
|
* Updates the src of the active speaker avatar
|
||||||
* @param jid of the current active speaker
|
* @param jid of the current active speaker
|
||||||
*/
|
*/
|
||||||
my.updateActiveSpeakerAvatarSrc = function(jid) {
|
updateActiveSpeakerAvatarSrc: function (jid) {
|
||||||
if(!jid) {
|
if (!jid) {
|
||||||
jid = connection.emuc.findJidFromResource(
|
jid = connection.emuc.findJidFromResource(
|
||||||
VideoLayout.getLargeVideoState().userResourceJid);
|
require("../videolayout/VideoLayout").getLargeVideoState().userResourceJid);
|
||||||
}
|
}
|
||||||
var avatar = $("#activeSpeakerAvatar")[0];
|
var avatar = $("#activeSpeakerAvatar")[0];
|
||||||
var url = getGravatarUrl(users[jid],
|
var url = getGravatarUrl(users[jid],
|
||||||
interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE);
|
interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE);
|
||||||
if(jid === activeSpeakerJid && avatar.src === url) {
|
if (jid === activeSpeakerJid && avatar.src === url) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
activeSpeakerJid = jid;
|
activeSpeakerJid = jid;
|
||||||
var isMuted = isUserMuted(jid);
|
var isMuted = isUserMuted(jid);
|
||||||
if(jid && isMuted !== null) {
|
if (jid && isMuted !== null) {
|
||||||
avatar.src = url;
|
avatar.src = url;
|
||||||
setVisibility($("#largeVideo"), !isMuted);
|
setVisibility($("#largeVideo"), !isMuted);
|
||||||
Avatar.showUserAvatar(jid, isMuted);
|
Avatar.showUserAvatar(jid, isMuted);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function setVisibility(selector, show) {
|
|
||||||
if (selector && selector.length > 0) {
|
|
||||||
selector.css("visibility", show ? "visible" : "hidden");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUserMuted(jid) {
|
};
|
||||||
// XXX(gp) we may want to rename this method to something like
|
|
||||||
// isUserStreaming, for example.
|
|
||||||
if (jid && jid != connection.emuc.myroomjid) {
|
|
||||||
var resource = Strophe.getResourceFromJid(jid);
|
|
||||||
if (!VideoLayout.isInLastN(resource)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RTC.remoteStreams[jid] || !RTC.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return RTC.remoteStreams[jid][MediaStream.VIDEO_TYPE].muted;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getGravatarUrl(id, size) {
|
module.exports = Avatar;
|
||||||
if(id === connection.emuc.myroomjid || !id) {
|
|
||||||
id = SettingsMenu.getUID();
|
|
||||||
}
|
|
||||||
return 'https://www.gravatar.com/avatar/' +
|
|
||||||
MD5.hexdigest(id.trim().toLowerCase()) +
|
|
||||||
"?d=wavatar&size=" + (size || "30");
|
|
||||||
}
|
|
||||||
|
|
||||||
return my;
|
|
||||||
}(Avatar || {}));
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
/* global $, config, connection, dockToolbar, Moderator,
|
||||||
|
setLargeVideoVisible, Util */
|
||||||
|
|
||||||
|
var VideoLayout = require("../videolayout/VideoLayout");
|
||||||
|
var Prezi = require("../prezi/Prezi");
|
||||||
|
var UIUtil = require("../util/UIUtil");
|
||||||
|
|
||||||
|
var etherpadName = null;
|
||||||
|
var etherpadIFrame = null;
|
||||||
|
var domain = null;
|
||||||
|
var options = "?showControls=true&showChat=false&showLineNumbers=true&useMonospaceFont=false";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the etherpad.
|
||||||
|
*/
|
||||||
|
function resize() {
|
||||||
|
if ($('#etherpad>iframe').length) {
|
||||||
|
var remoteVideos = $('#remoteVideos');
|
||||||
|
var availableHeight
|
||||||
|
= window.innerHeight - remoteVideos.outerHeight();
|
||||||
|
var availableWidth = UIUtil.getAvailableVideoWidth();
|
||||||
|
|
||||||
|
$('#etherpad>iframe').width(availableWidth);
|
||||||
|
$('#etherpad>iframe').height(availableHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shares the Etherpad name with other participants.
|
||||||
|
*/
|
||||||
|
function shareEtherpad() {
|
||||||
|
connection.emuc.addEtherpadToPresence(etherpadName);
|
||||||
|
connection.emuc.sendPresence();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the Etherpad button and adds it to the toolbar.
|
||||||
|
*/
|
||||||
|
function enableEtherpadButton() {
|
||||||
|
if (!$('#etherpadButton').is(":visible"))
|
||||||
|
$('#etherpadButton').css({display: 'inline-block'});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the IFrame for the etherpad.
|
||||||
|
*/
|
||||||
|
function createIFrame() {
|
||||||
|
etherpadIFrame = document.createElement('iframe');
|
||||||
|
etherpadIFrame.src = domain + etherpadName + options;
|
||||||
|
etherpadIFrame.frameBorder = 0;
|
||||||
|
etherpadIFrame.scrolling = "no";
|
||||||
|
etherpadIFrame.width = $('#largeVideoContainer').width() || 640;
|
||||||
|
etherpadIFrame.height = $('#largeVideoContainer').height() || 480;
|
||||||
|
etherpadIFrame.setAttribute('style', 'visibility: hidden;');
|
||||||
|
|
||||||
|
document.getElementById('etherpad').appendChild(etherpadIFrame);
|
||||||
|
|
||||||
|
etherpadIFrame.onload = function() {
|
||||||
|
|
||||||
|
document.domain = document.domain;
|
||||||
|
bubbleIframeMouseMove(etherpadIFrame);
|
||||||
|
setTimeout(function() {
|
||||||
|
// the iframes inside of the etherpad are
|
||||||
|
// not yet loaded when the etherpad iframe is loaded
|
||||||
|
var outer = etherpadIFrame.
|
||||||
|
contentDocument.getElementsByName("ace_outer")[0];
|
||||||
|
bubbleIframeMouseMove(outer);
|
||||||
|
var inner = outer.
|
||||||
|
contentDocument.getElementsByName("ace_inner")[0];
|
||||||
|
bubbleIframeMouseMove(inner);
|
||||||
|
}, 2000);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function bubbleIframeMouseMove(iframe){
|
||||||
|
var existingOnMouseMove = iframe.contentWindow.onmousemove;
|
||||||
|
iframe.contentWindow.onmousemove = function(e){
|
||||||
|
if(existingOnMouseMove) existingOnMouseMove(e);
|
||||||
|
var evt = document.createEvent("MouseEvents");
|
||||||
|
var boundingClientRect = iframe.getBoundingClientRect();
|
||||||
|
evt.initMouseEvent(
|
||||||
|
"mousemove",
|
||||||
|
true, // bubbles
|
||||||
|
false, // not cancelable
|
||||||
|
window,
|
||||||
|
e.detail,
|
||||||
|
e.screenX,
|
||||||
|
e.screenY,
|
||||||
|
e.clientX + boundingClientRect.left,
|
||||||
|
e.clientY + boundingClientRect.top,
|
||||||
|
e.ctrlKey,
|
||||||
|
e.altKey,
|
||||||
|
e.shiftKey,
|
||||||
|
e.metaKey,
|
||||||
|
e.button,
|
||||||
|
null // no related element
|
||||||
|
);
|
||||||
|
iframe.dispatchEvent(evt);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On video selected event.
|
||||||
|
*/
|
||||||
|
$(document).bind('video.selected', function (event, isPresentation) {
|
||||||
|
if (config.etherpad_base && etherpadIFrame && etherpadIFrame.style.visibility !== 'hidden')
|
||||||
|
Etherpad.toggleEtherpad(isPresentation);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var Etherpad = {
|
||||||
|
/**
|
||||||
|
* Initializes the etherpad.
|
||||||
|
*/
|
||||||
|
init: function (name) {
|
||||||
|
|
||||||
|
if (config.etherpad_base && !etherpadName) {
|
||||||
|
|
||||||
|
domain = config.etherpad_base;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
// In case we're the focus we generate the name.
|
||||||
|
etherpadName = Math.random().toString(36).substring(7) +
|
||||||
|
'_' + (new Date().getTime()).toString();
|
||||||
|
shareEtherpad();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
etherpadName = name;
|
||||||
|
|
||||||
|
enableEtherpadButton();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the etherpad, when the window is resized.
|
||||||
|
*/
|
||||||
|
$(window).resize(function () {
|
||||||
|
resize();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens/hides the Etherpad.
|
||||||
|
*/
|
||||||
|
toggleEtherpad: function (isPresentation) {
|
||||||
|
if (!etherpadIFrame)
|
||||||
|
createIFrame();
|
||||||
|
|
||||||
|
var largeVideo = null;
|
||||||
|
if (Prezi.isPresentationVisible())
|
||||||
|
largeVideo = $('#presentation>iframe');
|
||||||
|
else
|
||||||
|
largeVideo = $('#largeVideo');
|
||||||
|
|
||||||
|
if ($('#etherpad>iframe').css('visibility') === 'hidden') {
|
||||||
|
$('#activeSpeaker').css('visibility', 'hidden');
|
||||||
|
largeVideo.fadeOut(300, function () {
|
||||||
|
if (Prezi.isPresentationVisible()) {
|
||||||
|
largeVideo.css({opacity: '0'});
|
||||||
|
} else {
|
||||||
|
VideoLayout.setLargeVideoVisible(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#etherpad>iframe').fadeIn(300, function () {
|
||||||
|
document.body.style.background = '#eeeeee';
|
||||||
|
$('#etherpad>iframe').css({visibility: 'visible'});
|
||||||
|
$('#etherpad').css({zIndex: 2});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if ($('#etherpad>iframe')) {
|
||||||
|
$('#etherpad>iframe').fadeOut(300, function () {
|
||||||
|
$('#etherpad>iframe').css({visibility: 'hidden'});
|
||||||
|
$('#etherpad').css({zIndex: 0});
|
||||||
|
document.body.style.background = 'black';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isPresentation) {
|
||||||
|
$('#largeVideo').fadeIn(300, function () {
|
||||||
|
VideoLayout.setLargeVideoVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resize();
|
||||||
|
},
|
||||||
|
|
||||||
|
isVisible: function() {
|
||||||
|
var etherpadIframe = $('#etherpad>iframe');
|
||||||
|
return etherpadIframe && etherpadIframe.is(':visible');
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Etherpad;
|
|
@ -0,0 +1,354 @@
|
||||||
|
var ToolbarToggler = require("../toolbars/ToolbarToggler");
|
||||||
|
var UIUtil = require("../util/UIUtil");
|
||||||
|
var VideoLayout = require("../videolayout/VideoLayout");
|
||||||
|
var messageHandler = require("../util/MessageHandler");
|
||||||
|
|
||||||
|
var preziPlayer = null;
|
||||||
|
|
||||||
|
var Prezi = {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reloads the current presentation.
|
||||||
|
*/
|
||||||
|
reloadPresentation: function() {
|
||||||
|
var iframe = document.getElementById(preziPlayer.options.preziId);
|
||||||
|
iframe.src = iframe.src;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <tt>true</tt> if the presentation is visible, <tt>false</tt> -
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
isPresentationVisible: function () {
|
||||||
|
return ($('#presentation>iframe') != null
|
||||||
|
&& $('#presentation>iframe').css('opacity') == 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the Prezi dialog, from which the user could choose a presentation
|
||||||
|
* to load.
|
||||||
|
*/
|
||||||
|
openPreziDialog: function() {
|
||||||
|
var myprezi = connection.emuc.getPrezi(connection.emuc.myroomjid);
|
||||||
|
if (myprezi) {
|
||||||
|
messageHandler.openTwoButtonDialog("Remove Prezi",
|
||||||
|
"Are you sure you would like to remove your Prezi?",
|
||||||
|
false,
|
||||||
|
"Remove",
|
||||||
|
function(e,v,m,f) {
|
||||||
|
if(v) {
|
||||||
|
connection.emuc.removePreziFromPresence();
|
||||||
|
connection.emuc.sendPresence();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (preziPlayer != null) {
|
||||||
|
messageHandler.openTwoButtonDialog("Share a Prezi",
|
||||||
|
"Another participant is already sharing a Prezi." +
|
||||||
|
"This conference allows only one Prezi at a time.",
|
||||||
|
false,
|
||||||
|
"Ok",
|
||||||
|
function(e,v,m,f) {
|
||||||
|
$.prompt.close();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var openPreziState = {
|
||||||
|
state0: {
|
||||||
|
html: '<h2>Share a Prezi</h2>' +
|
||||||
|
'<input id="preziUrl" type="text" ' +
|
||||||
|
'placeholder="e.g. ' +
|
||||||
|
'http://prezi.com/wz7vhjycl7e6/my-prezi" autofocus>',
|
||||||
|
persistent: false,
|
||||||
|
buttons: { "Share": true , "Cancel": false},
|
||||||
|
defaultButton: 1,
|
||||||
|
submit: function(e,v,m,f){
|
||||||
|
e.preventDefault();
|
||||||
|
if(v)
|
||||||
|
{
|
||||||
|
var preziUrl = document.getElementById('preziUrl');
|
||||||
|
|
||||||
|
if (preziUrl.value)
|
||||||
|
{
|
||||||
|
var urlValue
|
||||||
|
= encodeURI(Util.escapeHtml(preziUrl.value));
|
||||||
|
|
||||||
|
if (urlValue.indexOf('http://prezi.com/') != 0
|
||||||
|
&& urlValue.indexOf('https://prezi.com/') != 0)
|
||||||
|
{
|
||||||
|
$.prompt.goToState('state1');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var presIdTmp = urlValue.substring(
|
||||||
|
urlValue.indexOf("prezi.com/") + 10);
|
||||||
|
if (!isAlphanumeric(presIdTmp)
|
||||||
|
|| presIdTmp.indexOf('/') < 2) {
|
||||||
|
$.prompt.goToState('state1');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
connection.emuc
|
||||||
|
.addPreziToPresence(urlValue, 0);
|
||||||
|
connection.emuc.sendPresence();
|
||||||
|
$.prompt.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$.prompt.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state1: {
|
||||||
|
html: '<h2>Share a Prezi</h2>' +
|
||||||
|
'Please provide a correct prezi link.',
|
||||||
|
persistent: false,
|
||||||
|
buttons: { "Back": true, "Cancel": false },
|
||||||
|
defaultButton: 1,
|
||||||
|
submit:function(e,v,m,f) {
|
||||||
|
e.preventDefault();
|
||||||
|
if(v==0)
|
||||||
|
$.prompt.close();
|
||||||
|
else
|
||||||
|
$.prompt.goToState('state0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var focusPreziUrl = function(e) {
|
||||||
|
document.getElementById('preziUrl').focus();
|
||||||
|
};
|
||||||
|
messageHandler.openDialogWithStates(openPreziState, focusPreziUrl, focusPreziUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A new presentation has been added.
|
||||||
|
*
|
||||||
|
* @param event the event indicating the add of a presentation
|
||||||
|
* @param jid the jid from which the presentation was added
|
||||||
|
* @param presUrl url of the presentation
|
||||||
|
* @param currentSlide the current slide to which we should move
|
||||||
|
*/
|
||||||
|
function presentationAdded(event, jid, presUrl, currentSlide) {
|
||||||
|
console.log("presentation added", presUrl);
|
||||||
|
|
||||||
|
var presId = getPresentationId(presUrl);
|
||||||
|
|
||||||
|
var elementId = 'participant_'
|
||||||
|
+ Strophe.getResourceFromJid(jid)
|
||||||
|
+ '_' + presId;
|
||||||
|
|
||||||
|
// We explicitly don't specify the peer jid here, because we don't want
|
||||||
|
// this video to be dealt with as a peer related one (for example we
|
||||||
|
// don't want to show a mute/kick menu for this one, etc.).
|
||||||
|
VideoLayout.addRemoteVideoContainer(null, elementId);
|
||||||
|
VideoLayout.resizeThumbnails();
|
||||||
|
|
||||||
|
var controlsEnabled = false;
|
||||||
|
if (jid === connection.emuc.myroomjid)
|
||||||
|
controlsEnabled = true;
|
||||||
|
|
||||||
|
setPresentationVisible(true);
|
||||||
|
$('#largeVideoContainer').hover(
|
||||||
|
function (event) {
|
||||||
|
if (Prezi.isPresentationVisible()) {
|
||||||
|
var reloadButtonRight = window.innerWidth
|
||||||
|
- $('#presentation>iframe').offset().left
|
||||||
|
- $('#presentation>iframe').width();
|
||||||
|
|
||||||
|
$('#reloadPresentation').css({ right: reloadButtonRight,
|
||||||
|
display:'inline-block'});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function (event) {
|
||||||
|
if (!Prezi.isPresentationVisible())
|
||||||
|
$('#reloadPresentation').css({display:'none'});
|
||||||
|
else {
|
||||||
|
var e = event.toElement || event.relatedTarget;
|
||||||
|
|
||||||
|
if (e && e.id != 'reloadPresentation' && e.id != 'header')
|
||||||
|
$('#reloadPresentation').css({display:'none'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
preziPlayer = new PreziPlayer(
|
||||||
|
'presentation',
|
||||||
|
{preziId: presId,
|
||||||
|
width: getPresentationWidth(),
|
||||||
|
height: getPresentationHeihgt(),
|
||||||
|
controls: controlsEnabled,
|
||||||
|
debug: true
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#presentation>iframe').attr('id', preziPlayer.options.preziId);
|
||||||
|
|
||||||
|
preziPlayer.on(PreziPlayer.EVENT_STATUS, function(event) {
|
||||||
|
console.log("prezi status", event.value);
|
||||||
|
if (event.value == PreziPlayer.STATUS_CONTENT_READY) {
|
||||||
|
if (jid != connection.emuc.myroomjid)
|
||||||
|
preziPlayer.flyToStep(currentSlide);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
preziPlayer.on(PreziPlayer.EVENT_CURRENT_STEP, function(event) {
|
||||||
|
console.log("event value", event.value);
|
||||||
|
connection.emuc.addCurrentSlideToPresence(event.value);
|
||||||
|
connection.emuc.sendPresence();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#" + elementId).css( 'background-image',
|
||||||
|
'url(../images/avatarprezi.png)');
|
||||||
|
$("#" + elementId).click(
|
||||||
|
function () {
|
||||||
|
setPresentationVisible(true);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A presentation has been removed.
|
||||||
|
*
|
||||||
|
* @param event the event indicating the remove of a presentation
|
||||||
|
* @param jid the jid for which the presentation was removed
|
||||||
|
* @param the url of the presentation
|
||||||
|
*/
|
||||||
|
function presentationRemoved(event, jid, presUrl) {
|
||||||
|
console.log('presentation removed', presUrl);
|
||||||
|
var presId = getPresentationId(presUrl);
|
||||||
|
setPresentationVisible(false);
|
||||||
|
$('#participant_'
|
||||||
|
+ Strophe.getResourceFromJid(jid)
|
||||||
|
+ '_' + presId).remove();
|
||||||
|
$('#presentation>iframe').remove();
|
||||||
|
if (preziPlayer != null) {
|
||||||
|
preziPlayer.destroy();
|
||||||
|
preziPlayer = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the given string is an alphanumeric string.
|
||||||
|
* Note that some special characters are also allowed (-, _ , /, &, ?, =, ;) for the
|
||||||
|
* purpose of checking URIs.
|
||||||
|
*/
|
||||||
|
function isAlphanumeric(unsafeText) {
|
||||||
|
var regex = /^[a-z0-9-_\/&\?=;]+$/i;
|
||||||
|
return regex.test(unsafeText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the presentation id from the given url.
|
||||||
|
*/
|
||||||
|
function getPresentationId (presUrl) {
|
||||||
|
var presIdTmp = presUrl.substring(presUrl.indexOf("prezi.com/") + 10);
|
||||||
|
return presIdTmp.substring(0, presIdTmp.indexOf('/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the presentation width.
|
||||||
|
*/
|
||||||
|
function getPresentationWidth() {
|
||||||
|
var availableWidth = UIUtil.getAvailableVideoWidth();
|
||||||
|
var availableHeight = getPresentationHeihgt();
|
||||||
|
|
||||||
|
var aspectRatio = 16.0 / 9.0;
|
||||||
|
if (availableHeight < availableWidth / aspectRatio) {
|
||||||
|
availableWidth = Math.floor(availableHeight * aspectRatio);
|
||||||
|
}
|
||||||
|
return availableWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the presentation height.
|
||||||
|
*/
|
||||||
|
function getPresentationHeihgt() {
|
||||||
|
var remoteVideos = $('#remoteVideos');
|
||||||
|
return window.innerHeight - remoteVideos.outerHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the presentation iframe.
|
||||||
|
*/
|
||||||
|
function resize() {
|
||||||
|
if ($('#presentation>iframe')) {
|
||||||
|
$('#presentation>iframe').width(getPresentationWidth());
|
||||||
|
$('#presentation>iframe').height(getPresentationHeihgt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows/hides a presentation.
|
||||||
|
*/
|
||||||
|
function setPresentationVisible(visible) {
|
||||||
|
var prezi = $('#presentation>iframe');
|
||||||
|
if (visible) {
|
||||||
|
// Trigger the video.selected event to indicate a change in the
|
||||||
|
// large video.
|
||||||
|
$(document).trigger("video.selected", [true]);
|
||||||
|
|
||||||
|
$('#largeVideo').fadeOut(300);
|
||||||
|
prezi.fadeIn(300, function() {
|
||||||
|
prezi.css({opacity:'1'});
|
||||||
|
ToolbarToggler.dockToolbar(true);
|
||||||
|
VideoLayout.setLargeVideoVisible(false);
|
||||||
|
});
|
||||||
|
$('#activeSpeaker').css('visibility', 'hidden');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (prezi.css('opacity') == '1') {
|
||||||
|
prezi.fadeOut(300, function () {
|
||||||
|
prezi.css({opacity:'0'});
|
||||||
|
$('#reloadPresentation').css({display:'none'});
|
||||||
|
$('#largeVideo').fadeIn(300, function() {
|
||||||
|
VideoLayout.setLargeVideoVisible(true);
|
||||||
|
ToolbarToggler.dockToolbar(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Presentation has been removed.
|
||||||
|
*/
|
||||||
|
$(document).bind('presentationremoved.muc', presentationRemoved);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Presentation has been added.
|
||||||
|
*/
|
||||||
|
$(document).bind('presentationadded.muc', presentationAdded);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Indicates presentation slide change.
|
||||||
|
*/
|
||||||
|
$(document).bind('gotoslide.muc', function (event, jid, presUrl, current) {
|
||||||
|
if (preziPlayer && preziPlayer.getCurrentStep() != current) {
|
||||||
|
preziPlayer.flyToStep(current);
|
||||||
|
|
||||||
|
var animationStepsArray = preziPlayer.getAnimationCountOnSteps();
|
||||||
|
for (var i = 0; i < parseInt(animationStepsArray[current]); i++) {
|
||||||
|
preziPlayer.flyToStep(current, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On video selected event.
|
||||||
|
*/
|
||||||
|
$(document).bind('video.selected', function (event, isPresentation) {
|
||||||
|
if (!isPresentation && $('#presentation>iframe')) {
|
||||||
|
setPresentationVisible(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).resize(function () {
|
||||||
|
resize();
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = Prezi;
|
|
@ -1,3 +1,10 @@
|
||||||
|
var Chat = require("./chat/Chat");
|
||||||
|
var ContactList = require("./contactlist/ContactList");
|
||||||
|
var Settings = require("./settings/Settings");
|
||||||
|
var SettingsMenu = require("./settings/SettingsMenu");
|
||||||
|
var VideoLayout = require("../videolayout/VideoLayout");
|
||||||
|
var ToolbarToggler = require("../toolbars/ToolbarToggler");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggler for the chat, contact list, settings menu, etc..
|
* Toggler for the chat, contact list, settings menu, etc..
|
||||||
*/
|
*/
|
||||||
|
@ -215,8 +222,9 @@ var PanelToggler = (function(my) {
|
||||||
'#settingsmenu',
|
'#settingsmenu',
|
||||||
null,
|
null,
|
||||||
function() {
|
function() {
|
||||||
$('#setDisplayName').get(0).value = SettingsMenu.getDisplayName();
|
var settings = Settings.getSettings();
|
||||||
$('#setEmail').get(0).value = SettingsMenu.getEmail();
|
$('#setDisplayName').get(0).value = settings.displayName;
|
||||||
|
$('#setEmail').get(0).value = settings.email;
|
||||||
},
|
},
|
||||||
null);
|
null);
|
||||||
};
|
};
|
||||||
|
@ -243,3 +251,5 @@ var PanelToggler = (function(my) {
|
||||||
return my;
|
return my;
|
||||||
|
|
||||||
}(PanelToggler || {}));
|
}(PanelToggler || {}));
|
||||||
|
|
||||||
|
module.exports = PanelToggler;
|
|
@ -0,0 +1,361 @@
|
||||||
|
/* global $, Util, connection, nickname:true, getVideoSize,
|
||||||
|
getVideoPosition, showToolbar */
|
||||||
|
var Replacement = require("./Replacement");
|
||||||
|
var CommandsProcessor = require("./Commands");
|
||||||
|
var ToolbarToggler = require("../../toolbars/ToolbarToggler");
|
||||||
|
var smileys = require("./smileys.json").smileys;
|
||||||
|
|
||||||
|
var notificationInterval = false;
|
||||||
|
var unreadMessages = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows/hides a visual notification, indicating that a message has arrived.
|
||||||
|
*/
|
||||||
|
function setVisualNotification(show) {
|
||||||
|
var unreadMsgElement = document.getElementById('unreadMessages');
|
||||||
|
var unreadMsgBottomElement
|
||||||
|
= document.getElementById('bottomUnreadMessages');
|
||||||
|
|
||||||
|
var glower = $('#chatButton');
|
||||||
|
var bottomGlower = $('#chatBottomButton');
|
||||||
|
|
||||||
|
if (unreadMessages) {
|
||||||
|
unreadMsgElement.innerHTML = unreadMessages.toString();
|
||||||
|
unreadMsgBottomElement.innerHTML = unreadMessages.toString();
|
||||||
|
|
||||||
|
ToolbarToggler.dockToolbar(true);
|
||||||
|
|
||||||
|
var chatButtonElement
|
||||||
|
= document.getElementById('chatButton').parentNode;
|
||||||
|
var leftIndent = (Util.getTextWidth(chatButtonElement) -
|
||||||
|
Util.getTextWidth(unreadMsgElement)) / 2;
|
||||||
|
var topIndent = (Util.getTextHeight(chatButtonElement) -
|
||||||
|
Util.getTextHeight(unreadMsgElement)) / 2 - 3;
|
||||||
|
|
||||||
|
unreadMsgElement.setAttribute(
|
||||||
|
'style',
|
||||||
|
'top:' + topIndent +
|
||||||
|
'; left:' + leftIndent + ';');
|
||||||
|
|
||||||
|
var chatBottomButtonElement
|
||||||
|
= document.getElementById('chatBottomButton').parentNode;
|
||||||
|
var bottomLeftIndent = (Util.getTextWidth(chatBottomButtonElement) -
|
||||||
|
Util.getTextWidth(unreadMsgBottomElement)) / 2;
|
||||||
|
var bottomTopIndent = (Util.getTextHeight(chatBottomButtonElement) -
|
||||||
|
Util.getTextHeight(unreadMsgBottomElement)) / 2 - 2;
|
||||||
|
|
||||||
|
unreadMsgBottomElement.setAttribute(
|
||||||
|
'style',
|
||||||
|
'top:' + bottomTopIndent +
|
||||||
|
'; left:' + bottomLeftIndent + ';');
|
||||||
|
|
||||||
|
|
||||||
|
if (!glower.hasClass('icon-chat-simple')) {
|
||||||
|
glower.removeClass('icon-chat');
|
||||||
|
glower.addClass('icon-chat-simple');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unreadMsgElement.innerHTML = '';
|
||||||
|
unreadMsgBottomElement.innerHTML = '';
|
||||||
|
glower.removeClass('icon-chat-simple');
|
||||||
|
glower.addClass('icon-chat');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show && !notificationInterval) {
|
||||||
|
notificationInterval = window.setInterval(function () {
|
||||||
|
glower.toggleClass('active');
|
||||||
|
bottomGlower.toggleClass('active glowing');
|
||||||
|
}, 800);
|
||||||
|
}
|
||||||
|
else if (!show && notificationInterval) {
|
||||||
|
window.clearInterval(notificationInterval);
|
||||||
|
notificationInterval = false;
|
||||||
|
glower.removeClass('active');
|
||||||
|
bottomGlower.removeClass('glowing');
|
||||||
|
bottomGlower.addClass('active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current time in the format it is shown to the user
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getCurrentTime() {
|
||||||
|
var now = new Date();
|
||||||
|
var hour = now.getHours();
|
||||||
|
var minute = now.getMinutes();
|
||||||
|
var second = now.getSeconds();
|
||||||
|
if(hour.toString().length === 1) {
|
||||||
|
hour = '0'+hour;
|
||||||
|
}
|
||||||
|
if(minute.toString().length === 1) {
|
||||||
|
minute = '0'+minute;
|
||||||
|
}
|
||||||
|
if(second.toString().length === 1) {
|
||||||
|
second = '0'+second;
|
||||||
|
}
|
||||||
|
return hour+':'+minute+':'+second;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSmileys()
|
||||||
|
{
|
||||||
|
var smileys = $('#smileysContainer');
|
||||||
|
if(!smileys.is(':visible')) {
|
||||||
|
smileys.show("slide", { direction: "down", duration: 300});
|
||||||
|
} else {
|
||||||
|
smileys.hide("slide", { direction: "down", duration: 300});
|
||||||
|
}
|
||||||
|
$('#usermsg').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addClickFunction(smiley, number) {
|
||||||
|
smiley.onclick = function addSmileyToMessage() {
|
||||||
|
var usermsg = $('#usermsg');
|
||||||
|
var message = usermsg.val();
|
||||||
|
message += smileys['smiley' + number];
|
||||||
|
usermsg.val(message);
|
||||||
|
usermsg.get(0).setSelectionRange(message.length, message.length);
|
||||||
|
toggleSmileys();
|
||||||
|
usermsg.focus();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the smileys container to the chat
|
||||||
|
*/
|
||||||
|
function addSmileys() {
|
||||||
|
var smileysContainer = document.createElement('div');
|
||||||
|
smileysContainer.id = 'smileysContainer';
|
||||||
|
for(var i = 1; i <= 21; i++) {
|
||||||
|
var smileyContainer = document.createElement('div');
|
||||||
|
smileyContainer.id = 'smiley' + i;
|
||||||
|
smileyContainer.className = 'smileyContainer';
|
||||||
|
var smiley = document.createElement('img');
|
||||||
|
smiley.src = 'images/smileys/smiley' + i + '.svg';
|
||||||
|
smiley.className = 'smiley';
|
||||||
|
addClickFunction(smiley, i);
|
||||||
|
smileyContainer.appendChild(smiley);
|
||||||
|
smileysContainer.appendChild(smileyContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#chatspace").append(smileysContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the chat conversation.
|
||||||
|
*/
|
||||||
|
function resizeChatConversation() {
|
||||||
|
var msgareaHeight = $('#usermsg').outerHeight();
|
||||||
|
var chatspace = $('#chatspace');
|
||||||
|
var width = chatspace.width();
|
||||||
|
var chat = $('#chatconversation');
|
||||||
|
var smileys = $('#smileysarea');
|
||||||
|
|
||||||
|
smileys.height(msgareaHeight);
|
||||||
|
$("#smileys").css('bottom', (msgareaHeight - 26) / 2);
|
||||||
|
$('#smileysContainer').css('bottom', msgareaHeight);
|
||||||
|
chat.width(width - 10);
|
||||||
|
chat.height(window.innerHeight - 15 - msgareaHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chat related user interface.
|
||||||
|
*/
|
||||||
|
var Chat = (function (my) {
|
||||||
|
/**
|
||||||
|
* Initializes chat related interface.
|
||||||
|
*/
|
||||||
|
my.init = function () {
|
||||||
|
var storedDisplayName = window.localStorage.displayname;
|
||||||
|
if (storedDisplayName) {
|
||||||
|
nickname = storedDisplayName;
|
||||||
|
|
||||||
|
Chat.setChatConversationMode(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#nickinput').keydown(function (event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
event.preventDefault();
|
||||||
|
var val = Util.escapeHtml(this.value);
|
||||||
|
this.value = '';
|
||||||
|
if (!nickname) {
|
||||||
|
nickname = val;
|
||||||
|
window.localStorage.displayname = nickname;
|
||||||
|
|
||||||
|
connection.emuc.addDisplayNameToPresence(nickname);
|
||||||
|
connection.emuc.sendPresence();
|
||||||
|
|
||||||
|
Chat.setChatConversationMode(true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#usermsg').keydown(function (event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
event.preventDefault();
|
||||||
|
var value = this.value;
|
||||||
|
$('#usermsg').val('').trigger('autosize.resize');
|
||||||
|
this.focus();
|
||||||
|
var command = new CommandsProcessor(value);
|
||||||
|
if(command.isCommand())
|
||||||
|
{
|
||||||
|
command.processCommand();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var message = Util.escapeHtml(value);
|
||||||
|
connection.emuc.sendMessage(message, nickname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var onTextAreaResize = function () {
|
||||||
|
resizeChatConversation();
|
||||||
|
Chat.scrollChatToBottom();
|
||||||
|
};
|
||||||
|
$('#usermsg').autosize({callback: onTextAreaResize});
|
||||||
|
|
||||||
|
$("#chatspace").bind("shown",
|
||||||
|
function () {
|
||||||
|
unreadMessages = 0;
|
||||||
|
setVisualNotification(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
addSmileys();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the given message to the chat conversation.
|
||||||
|
*/
|
||||||
|
my.updateChatConversation = function (from, displayName, message) {
|
||||||
|
var divClassName = '';
|
||||||
|
|
||||||
|
if (connection.emuc.myroomjid === from) {
|
||||||
|
divClassName = "localuser";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
divClassName = "remoteuser";
|
||||||
|
|
||||||
|
if (!Chat.isVisible()) {
|
||||||
|
unreadMessages++;
|
||||||
|
Util.playSoundNotification('chatNotification');
|
||||||
|
setVisualNotification(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace links and smileys
|
||||||
|
// Strophe already escapes special symbols on sending,
|
||||||
|
// so we escape here only tags to avoid double &
|
||||||
|
var escMessage = message.replace(/</g, '<').
|
||||||
|
replace(/>/g, '>').replace(/\n/g, '<br/>');
|
||||||
|
var escDisplayName = Util.escapeHtml(displayName);
|
||||||
|
message = Replacement.processReplacements(escMessage);
|
||||||
|
|
||||||
|
var messageContainer =
|
||||||
|
'<div class="chatmessage">'+
|
||||||
|
'<img src="../images/chatArrow.svg" class="chatArrow">' +
|
||||||
|
'<div class="username ' + divClassName +'">' + escDisplayName +
|
||||||
|
'</div>' + '<div class="timestamp">' + getCurrentTime() +
|
||||||
|
'</div>' + '<div class="usermessage">' + message + '</div>' +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
$('#chatconversation').append(messageContainer);
|
||||||
|
$('#chatconversation').animate(
|
||||||
|
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends error message to the conversation
|
||||||
|
* @param errorMessage the received error message.
|
||||||
|
* @param originalText the original message.
|
||||||
|
*/
|
||||||
|
my.chatAddError = function(errorMessage, originalText)
|
||||||
|
{
|
||||||
|
errorMessage = Util.escapeHtml(errorMessage);
|
||||||
|
originalText = Util.escapeHtml(originalText);
|
||||||
|
|
||||||
|
$('#chatconversation').append(
|
||||||
|
'<div class="errorMessage"><b>Error: </b>' + 'Your message' +
|
||||||
|
(originalText? (' \"'+ originalText + '\"') : "") +
|
||||||
|
' was not sent.' +
|
||||||
|
(errorMessage? (' Reason: ' + errorMessage) : '') + '</div>');
|
||||||
|
$('#chatconversation').animate(
|
||||||
|
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the subject to the UI
|
||||||
|
* @param subject the subject
|
||||||
|
*/
|
||||||
|
my.chatSetSubject = function(subject)
|
||||||
|
{
|
||||||
|
if(subject)
|
||||||
|
subject = subject.trim();
|
||||||
|
$('#subject').html(Replacement.linkify(Util.escapeHtml(subject)));
|
||||||
|
if(subject === "")
|
||||||
|
{
|
||||||
|
$("#subject").css({display: "none"});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$("#subject").css({display: "block"});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the chat conversation mode.
|
||||||
|
*/
|
||||||
|
my.setChatConversationMode = function (isConversationMode) {
|
||||||
|
if (isConversationMode) {
|
||||||
|
$('#nickname').css({visibility: 'hidden'});
|
||||||
|
$('#chatconversation').css({visibility: 'visible'});
|
||||||
|
$('#usermsg').css({visibility: 'visible'});
|
||||||
|
$('#smileysarea').css({visibility: 'visible'});
|
||||||
|
$('#usermsg').focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the chat area.
|
||||||
|
*/
|
||||||
|
my.resizeChat = function () {
|
||||||
|
var chatSize = require("../SidePanelToggler").getPanelSize();
|
||||||
|
|
||||||
|
$('#chatspace').width(chatSize[0]);
|
||||||
|
$('#chatspace').height(chatSize[1]);
|
||||||
|
|
||||||
|
resizeChatConversation();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the chat is currently visible.
|
||||||
|
*/
|
||||||
|
my.isVisible = function () {
|
||||||
|
return $('#chatspace').is(":visible");
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Shows and hides the window with the smileys
|
||||||
|
*/
|
||||||
|
my.toggleSmileys = toggleSmileys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrolls chat to the bottom.
|
||||||
|
*/
|
||||||
|
my.scrollChatToBottom = function() {
|
||||||
|
setTimeout(function () {
|
||||||
|
$('#chatconversation').scrollTop(
|
||||||
|
$('#chatconversation')[0].scrollHeight);
|
||||||
|
}, 5);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return my;
|
||||||
|
}(Chat || {}));
|
||||||
|
module.exports = Chat;
|
|
@ -0,0 +1,95 @@
|
||||||
|
/**
|
||||||
|
* List with supported commands. The keys are the names of the commands and
|
||||||
|
* the value is the function that processes the message.
|
||||||
|
* @type {{String: function}}
|
||||||
|
*/
|
||||||
|
var commands = {
|
||||||
|
"topic" : processTopic
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the command from the message.
|
||||||
|
* @param message the received message
|
||||||
|
* @returns {string} the command
|
||||||
|
*/
|
||||||
|
function getCommand(message)
|
||||||
|
{
|
||||||
|
if(message)
|
||||||
|
{
|
||||||
|
for(var command in commands)
|
||||||
|
{
|
||||||
|
if(message.indexOf("/" + command) == 0)
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the data for topic command.
|
||||||
|
* @param commandArguments the arguments of the topic command.
|
||||||
|
*/
|
||||||
|
function processTopic(commandArguments)
|
||||||
|
{
|
||||||
|
var topic = Util.escapeHtml(commandArguments);
|
||||||
|
connection.emuc.setSubject(topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs new CommandProccessor instance from a message that
|
||||||
|
* handles commands received via chat messages.
|
||||||
|
* @param message the message
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function CommandsProcessor(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
var command = getCommand(message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the command.
|
||||||
|
* @returns {String} the command
|
||||||
|
*/
|
||||||
|
this.getCommand = function()
|
||||||
|
{
|
||||||
|
return command;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var messageArgument = message.substr(command.length + 2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the arguments of the command.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
this.getArgument = function()
|
||||||
|
{
|
||||||
|
return messageArgument;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether this instance is valid command or not.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
CommandsProcessor.prototype.isCommand = function()
|
||||||
|
{
|
||||||
|
if(this.getCommand())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the command.
|
||||||
|
*/
|
||||||
|
CommandsProcessor.prototype.processCommand = function()
|
||||||
|
{
|
||||||
|
if(!this.isCommand())
|
||||||
|
return;
|
||||||
|
|
||||||
|
commands[this.getCommand()](this.getArgument());
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = CommandsProcessor;
|
|
@ -1,3 +1,4 @@
|
||||||
|
var Smileys = require("./smileys.json");
|
||||||
/**
|
/**
|
||||||
* Processes links and smileys in "body"
|
* Processes links and smileys in "body"
|
||||||
*/
|
*/
|
||||||
|
@ -44,6 +45,7 @@ function smilify(body)
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var regexs = Smileys["regexs"];
|
||||||
for(var smiley in regexs) {
|
for(var smiley in regexs) {
|
||||||
if(regexs.hasOwnProperty(smiley)) {
|
if(regexs.hasOwnProperty(smiley)) {
|
||||||
body = body.replace(regexs[smiley],
|
body = body.replace(regexs[smiley],
|
||||||
|
@ -53,3 +55,8 @@ function smilify(body)
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
processReplacements: processReplacements,
|
||||||
|
linkify: linkify
|
||||||
|
};
|
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"smileys": {
|
||||||
|
"smiley1": ":)",
|
||||||
|
"smiley2": ":(",
|
||||||
|
"smiley3": ":D",
|
||||||
|
"smiley4": "(y)",
|
||||||
|
"smiley5": " :P",
|
||||||
|
"smiley6": "(wave)",
|
||||||
|
"smiley7": "(blush)",
|
||||||
|
"smiley8": "(chuckle)",
|
||||||
|
"smiley9": "(shocked)",
|
||||||
|
"smiley10": ":*",
|
||||||
|
"smiley11": "(n)",
|
||||||
|
"smiley12": "(search)",
|
||||||
|
"smiley13": " <3",
|
||||||
|
"smiley14": "(oops)",
|
||||||
|
"smiley15": "(angry)",
|
||||||
|
"smiley16": "(angel)",
|
||||||
|
"smiley17": "(sick)",
|
||||||
|
"smiley18": ";(",
|
||||||
|
"smiley19": "(bomb)",
|
||||||
|
"smiley20": "(clap)",
|
||||||
|
"smiley21": " ;)"
|
||||||
|
},
|
||||||
|
"regexs": {
|
||||||
|
"smiley2": /(:-\(\(|:-\(|:\(\(|:\(|\(sad\))/gi,
|
||||||
|
"smiley3": /(:-\)\)|:\)\)|\(lol\)|:-D|:D)/gi,
|
||||||
|
"smiley1": /(:-\)|:\))/gi,
|
||||||
|
"smiley4": /(\(y\)|\(Y\)|\(ok\))/gi,
|
||||||
|
"smiley5": /(:-P|:P|:-p|:p)/gi,
|
||||||
|
"smiley6": /(\(wave\))/gi,
|
||||||
|
"smiley7": /(\(blush\))/gi,
|
||||||
|
"smiley8": /(\(chuckle\))/gi,
|
||||||
|
"smiley9": /(:-0|\(shocked\))/gi,
|
||||||
|
"smiley10": /(:-\*|:\*|\(kiss\))/gi,
|
||||||
|
"smiley11": /(\(n\))/gi,
|
||||||
|
"smiley12": /(\(search\))/g,
|
||||||
|
"smiley13": /(<3|<3|&lt;3|\(L\)|\(l\)|\(H\)|\(h\))/gi,
|
||||||
|
"smiley14": /(\(oops\))/gi,
|
||||||
|
"smiley15": /(\(angry\))/gi,
|
||||||
|
"smiley16": /(\(angel\))/gi,
|
||||||
|
"smiley17": /(\(sick\))/gi,
|
||||||
|
"smiley18": /(;-\(\(|;\(\(|;-\(|;\(|:"\(|:"-\(|:~-\(|:~\(|\(upset\))/gi,
|
||||||
|
"smiley19": /(\(bomb\))/gi,
|
||||||
|
"smiley20": /(\(clap\))/gi,
|
||||||
|
"smiley21": /(;-\)|;\)|;-\)\)|;\)\)|;-D|;D|\(wink\))/gi
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,125 +1,14 @@
|
||||||
|
|
||||||
|
var numberOfContacts = 0;
|
||||||
|
var notificationInterval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contact list.
|
|
||||||
*/
|
|
||||||
var ContactList = (function (my) {
|
|
||||||
|
|
||||||
var numberOfContacts = 0;
|
|
||||||
var notificationInterval;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the chat is currently visible.
|
|
||||||
*
|
|
||||||
* @return <tt>true</tt> if the chat is currently visible, <tt>false</tt> -
|
|
||||||
* otherwise
|
|
||||||
*/
|
|
||||||
my.isVisible = function () {
|
|
||||||
return $('#contactlist').is(":visible");
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a contact for the given peerJid if such doesn't yet exist.
|
|
||||||
*
|
|
||||||
* @param peerJid the peerJid corresponding to the contact
|
|
||||||
* @param id the user's email or userId used to get the user's avatar
|
|
||||||
*/
|
|
||||||
my.ensureAddContact = function(peerJid, id) {
|
|
||||||
var resourceJid = Strophe.getResourceFromJid(peerJid);
|
|
||||||
|
|
||||||
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
|
|
||||||
|
|
||||||
if (!contact || contact.length <= 0)
|
|
||||||
ContactList.addContact(peerJid,id);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a contact for the given peer jid.
|
|
||||||
*
|
|
||||||
* @param peerJid the jid of the contact to add
|
|
||||||
* @param id the email or userId of the user
|
|
||||||
*/
|
|
||||||
my.addContact = function(peerJid, id) {
|
|
||||||
var resourceJid = Strophe.getResourceFromJid(peerJid);
|
|
||||||
|
|
||||||
var contactlist = $('#contactlist>ul');
|
|
||||||
|
|
||||||
var newContact = document.createElement('li');
|
|
||||||
// XXX(gp) contact click event handling is now in videolayout.js. Is the
|
|
||||||
// following statement (newContact.id = resourceJid) still relevant?
|
|
||||||
newContact.id = resourceJid;
|
|
||||||
newContact.className = "clickable";
|
|
||||||
newContact.onclick = function(event) {
|
|
||||||
if(event.currentTarget.className === "clickable") {
|
|
||||||
$(ContactList).trigger('contactclicked', [peerJid]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
newContact.appendChild(createAvatar(id));
|
|
||||||
newContact.appendChild(createDisplayNameParagraph("Participant"));
|
|
||||||
|
|
||||||
var clElement = contactlist.get(0);
|
|
||||||
|
|
||||||
if (resourceJid === Strophe.getResourceFromJid(connection.emuc.myroomjid)
|
|
||||||
&& $('#contactlist>ul .title')[0].nextSibling.nextSibling)
|
|
||||||
{
|
|
||||||
clElement.insertBefore(newContact,
|
|
||||||
$('#contactlist>ul .title')[0].nextSibling.nextSibling);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clElement.appendChild(newContact);
|
|
||||||
}
|
|
||||||
updateNumberOfParticipants(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a contact for the given peer jid.
|
|
||||||
*
|
|
||||||
* @param peerJid the peerJid corresponding to the contact to remove
|
|
||||||
*/
|
|
||||||
my.removeContact = function(peerJid) {
|
|
||||||
var resourceJid = Strophe.getResourceFromJid(peerJid);
|
|
||||||
|
|
||||||
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
|
|
||||||
|
|
||||||
if (contact && contact.length > 0) {
|
|
||||||
var contactlist = $('#contactlist>ul');
|
|
||||||
|
|
||||||
contactlist.get(0).removeChild(contact.get(0));
|
|
||||||
|
|
||||||
updateNumberOfParticipants(-1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
my.setVisualNotification = function(show, stopGlowingIn) {
|
|
||||||
var glower = $('#contactListButton');
|
|
||||||
function stopGlowing() {
|
|
||||||
window.clearInterval(notificationInterval);
|
|
||||||
notificationInterval = false;
|
|
||||||
glower.removeClass('glowing');
|
|
||||||
if(!ContactList.isVisible()) {
|
|
||||||
glower.removeClass('active');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show && !notificationInterval) {
|
|
||||||
notificationInterval = window.setInterval(function () {
|
|
||||||
glower.toggleClass('active glowing');
|
|
||||||
}, 800);
|
|
||||||
}
|
|
||||||
else if (!show && notificationInterval) {
|
|
||||||
stopGlowing();
|
|
||||||
}
|
|
||||||
if(stopGlowingIn) {
|
|
||||||
setTimeout(stopGlowing, stopGlowingIn);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the number of participants in the contact list button and sets
|
* Updates the number of participants in the contact list button and sets
|
||||||
* the glow
|
* the glow
|
||||||
* @param delta indicates whether a new user has joined (1) or someone has
|
* @param delta indicates whether a new user has joined (1) or someone has
|
||||||
* left(-1)
|
* left(-1)
|
||||||
*/
|
*/
|
||||||
function updateNumberOfParticipants(delta) {
|
function updateNumberOfParticipants(delta) {
|
||||||
//when the user is alone we don't show the number of participants
|
//when the user is alone we don't show the number of participants
|
||||||
if(numberOfContacts === 0) {
|
if(numberOfContacts === 0) {
|
||||||
$("#numberOfParticipants").text('');
|
$("#numberOfParticipants").text('');
|
||||||
|
@ -129,38 +18,38 @@ var ContactList = (function (my) {
|
||||||
numberOfContacts += delta;
|
numberOfContacts += delta;
|
||||||
$("#numberOfParticipants").text(numberOfContacts);
|
$("#numberOfParticipants").text(numberOfContacts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the avatar element.
|
* Creates the avatar element.
|
||||||
*
|
*
|
||||||
* @return the newly created avatar element
|
* @return the newly created avatar element
|
||||||
*/
|
*/
|
||||||
function createAvatar(id) {
|
function createAvatar(id) {
|
||||||
var avatar = document.createElement('img');
|
var avatar = document.createElement('img');
|
||||||
avatar.className = "icon-avatar avatar";
|
avatar.className = "icon-avatar avatar";
|
||||||
avatar.src = "https://www.gravatar.com/avatar/" + id + "?d=wavatar&size=30";
|
avatar.src = "https://www.gravatar.com/avatar/" + id + "?d=wavatar&size=30";
|
||||||
|
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the display name paragraph.
|
* Creates the display name paragraph.
|
||||||
*
|
*
|
||||||
* @param displayName the display name to set
|
* @param displayName the display name to set
|
||||||
*/
|
*/
|
||||||
function createDisplayNameParagraph(displayName) {
|
function createDisplayNameParagraph(displayName) {
|
||||||
var p = document.createElement('p');
|
var p = document.createElement('p');
|
||||||
p.innerText = displayName;
|
p.innerText = displayName;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that the display name has changed.
|
* Indicates that the display name has changed.
|
||||||
*/
|
*/
|
||||||
$(document).bind( 'displaynamechanged',
|
$(document).bind( 'displaynamechanged',
|
||||||
function (event, peerJid, displayName) {
|
function (event, peerJid, displayName) {
|
||||||
if (peerJid === 'localVideoContainer')
|
if (peerJid === 'localVideoContainer')
|
||||||
peerJid = connection.emuc.myroomjid;
|
peerJid = connection.emuc.myroomjid;
|
||||||
|
@ -173,14 +62,127 @@ var ContactList = (function (my) {
|
||||||
contactName.html(displayName);
|
contactName.html(displayName);
|
||||||
});
|
});
|
||||||
|
|
||||||
my.setClickable = function(resourceJid, isClickable) {
|
|
||||||
|
function stopGlowing(glower) {
|
||||||
|
window.clearInterval(notificationInterval);
|
||||||
|
notificationInterval = false;
|
||||||
|
glower.removeClass('glowing');
|
||||||
|
if (!ContactList.isVisible()) {
|
||||||
|
glower.removeClass('active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contact list.
|
||||||
|
*/
|
||||||
|
var ContactList = {
|
||||||
|
/**
|
||||||
|
* Indicates if the chat is currently visible.
|
||||||
|
*
|
||||||
|
* @return <tt>true</tt> if the chat is currently visible, <tt>false</tt> -
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
isVisible: function () {
|
||||||
|
return $('#contactlist').is(":visible");
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a contact for the given peerJid if such doesn't yet exist.
|
||||||
|
*
|
||||||
|
* @param peerJid the peerJid corresponding to the contact
|
||||||
|
* @param id the user's email or userId used to get the user's avatar
|
||||||
|
*/
|
||||||
|
ensureAddContact: function (peerJid, id) {
|
||||||
|
var resourceJid = Strophe.getResourceFromJid(peerJid);
|
||||||
|
|
||||||
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
|
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
|
||||||
if(isClickable) {
|
|
||||||
|
if (!contact || contact.length <= 0)
|
||||||
|
ContactList.addContact(peerJid, id);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a contact for the given peer jid.
|
||||||
|
*
|
||||||
|
* @param peerJid the jid of the contact to add
|
||||||
|
* @param id the email or userId of the user
|
||||||
|
*/
|
||||||
|
addContact: function (peerJid, id) {
|
||||||
|
var resourceJid = Strophe.getResourceFromJid(peerJid);
|
||||||
|
|
||||||
|
var contactlist = $('#contactlist>ul');
|
||||||
|
|
||||||
|
var newContact = document.createElement('li');
|
||||||
|
newContact.id = resourceJid;
|
||||||
|
newContact.className = "clickable";
|
||||||
|
newContact.onclick = function (event) {
|
||||||
|
if (event.currentTarget.className === "clickable") {
|
||||||
|
$(ContactList).trigger('contactclicked', [peerJid]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
newContact.appendChild(createAvatar(id));
|
||||||
|
newContact.appendChild(createDisplayNameParagraph("Participant"));
|
||||||
|
|
||||||
|
var clElement = contactlist.get(0);
|
||||||
|
|
||||||
|
if (resourceJid === Strophe.getResourceFromJid(connection.emuc.myroomjid)
|
||||||
|
&& $('#contactlist>ul .title')[0].nextSibling.nextSibling) {
|
||||||
|
clElement.insertBefore(newContact,
|
||||||
|
$('#contactlist>ul .title')[0].nextSibling.nextSibling);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clElement.appendChild(newContact);
|
||||||
|
}
|
||||||
|
updateNumberOfParticipants(1);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a contact for the given peer jid.
|
||||||
|
*
|
||||||
|
* @param peerJid the peerJid corresponding to the contact to remove
|
||||||
|
*/
|
||||||
|
removeContact: function (peerJid) {
|
||||||
|
var resourceJid = Strophe.getResourceFromJid(peerJid);
|
||||||
|
|
||||||
|
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
|
||||||
|
|
||||||
|
if (contact && contact.length > 0) {
|
||||||
|
var contactlist = $('#contactlist>ul');
|
||||||
|
|
||||||
|
contactlist.get(0).removeChild(contact.get(0));
|
||||||
|
|
||||||
|
updateNumberOfParticipants(-1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setVisualNotification: function (show, stopGlowingIn) {
|
||||||
|
var glower = $('#contactListButton');
|
||||||
|
|
||||||
|
if (show && !notificationInterval) {
|
||||||
|
notificationInterval = window.setInterval(function () {
|
||||||
|
glower.toggleClass('active glowing');
|
||||||
|
}, 800);
|
||||||
|
}
|
||||||
|
else if (!show && notificationInterval) {
|
||||||
|
stopGlowing(glower);
|
||||||
|
}
|
||||||
|
if (stopGlowingIn) {
|
||||||
|
setTimeout(function () {
|
||||||
|
stopGlowing(glower);
|
||||||
|
}, stopGlowingIn);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setClickable: function (resourceJid, isClickable) {
|
||||||
|
var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
|
||||||
|
if (isClickable) {
|
||||||
contact.addClass('clickable');
|
contact.addClass('clickable');
|
||||||
} else {
|
} else {
|
||||||
contact.removeClass('clickable');
|
contact.removeClass('clickable');
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return my;
|
module.exports = ContactList;
|
||||||
}(ContactList || {}));
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
var email = '';
|
||||||
|
var displayName = '';
|
||||||
|
var userId;
|
||||||
|
|
||||||
|
|
||||||
|
function supportsLocalStorage() {
|
||||||
|
try {
|
||||||
|
return 'localStorage' in window && window.localStorage !== null;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("localstorage is not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function generateUniqueId() {
|
||||||
|
function _p8() {
|
||||||
|
return (Math.random().toString(16)+"000000000").substr(2,8);
|
||||||
|
}
|
||||||
|
return _p8() + _p8() + _p8() + _p8();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(supportsLocalStorage()) {
|
||||||
|
if(!window.localStorage.jitsiMeetId) {
|
||||||
|
window.localStorage.jitsiMeetId = generateUniqueId();
|
||||||
|
console.log("generated id", window.localStorage.jitsiMeetId);
|
||||||
|
}
|
||||||
|
userId = window.localStorage.jitsiMeetId || '';
|
||||||
|
email = window.localStorage.email || '';
|
||||||
|
displayName = window.localStorage.displayname || '';
|
||||||
|
} else {
|
||||||
|
console.log("local storage is not supported");
|
||||||
|
userId = generateUniqueId();
|
||||||
|
}
|
||||||
|
|
||||||
|
var Settings =
|
||||||
|
{
|
||||||
|
setDisplayName: function (newDisplayName) {
|
||||||
|
displayName = newDisplayName;
|
||||||
|
window.localStorage.displayname = displayName;
|
||||||
|
return displayName;
|
||||||
|
},
|
||||||
|
setEmail: function(newEmail)
|
||||||
|
{
|
||||||
|
email = newEmail;
|
||||||
|
window.localStorage.email = newEmail;
|
||||||
|
return email;
|
||||||
|
},
|
||||||
|
getSettings: function () {
|
||||||
|
return {
|
||||||
|
email: email,
|
||||||
|
displayName: displayName,
|
||||||
|
uid: userId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Settings;
|
|
@ -0,0 +1,42 @@
|
||||||
|
var Avatar = require("../../avatar/Avatar");
|
||||||
|
var Settings = require("./Settings");
|
||||||
|
|
||||||
|
|
||||||
|
var SettingsMenu = {
|
||||||
|
|
||||||
|
update: function() {
|
||||||
|
var newDisplayName = Util.escapeHtml($('#setDisplayName').get(0).value);
|
||||||
|
var newEmail = Util.escapeHtml($('#setEmail').get(0).value);
|
||||||
|
|
||||||
|
if(newDisplayName) {
|
||||||
|
var displayName = Settings.setDisplayName(newDisplayName);
|
||||||
|
connection.emuc.addDisplayNameToPresence(displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
connection.emuc.addEmailToPresence(newEmail);
|
||||||
|
var email = Settings.setEmail(newEmail);
|
||||||
|
|
||||||
|
|
||||||
|
connection.emuc.sendPresence();
|
||||||
|
Avatar.setUserAvatar(connection.emuc.myroomjid, email);
|
||||||
|
},
|
||||||
|
|
||||||
|
isVisible: function() {
|
||||||
|
return $('#settingsmenu').is(':visible');
|
||||||
|
},
|
||||||
|
|
||||||
|
setDisplayName: function(newDisplayName) {
|
||||||
|
var displayName = Settings.setDisplayName(newDisplayName);
|
||||||
|
$('#setDisplayName').get(0).value = displayName;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$(document).bind('displaynamechanged', function(event, peerJid, newDisplayName) {
|
||||||
|
if(peerJid === 'localVideoContainer' ||
|
||||||
|
peerJid === connection.emuc.myroomjid) {
|
||||||
|
SettingsMenu.setDisplayName(newDisplayName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = SettingsMenu;
|
|
@ -1,4 +1,23 @@
|
||||||
|
var PanelToggler = require("../side_pannels/SidePanelToggler");
|
||||||
|
|
||||||
|
var buttonHandlers = {
|
||||||
|
"bottom_toolbar_contact_list": function () {
|
||||||
|
BottomToolbar.toggleContactList();
|
||||||
|
},
|
||||||
|
"bottom_toolbar_film_strip": function () {
|
||||||
|
BottomToolbar.toggleFilmStrip();
|
||||||
|
},
|
||||||
|
"bottom_toolbar_chat": function () {
|
||||||
|
BottomToolbar.toggleChat();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var BottomToolbar = (function (my) {
|
var BottomToolbar = (function (my) {
|
||||||
|
my.init = function () {
|
||||||
|
for(var k in buttonHandlers)
|
||||||
|
$("#" + k).click(buttonHandlers[k]);
|
||||||
|
};
|
||||||
|
|
||||||
my.toggleChat = function() {
|
my.toggleChat = function() {
|
||||||
PanelToggler.toggleChat();
|
PanelToggler.toggleChat();
|
||||||
};
|
};
|
||||||
|
@ -20,3 +39,5 @@ var BottomToolbar = (function (my) {
|
||||||
|
|
||||||
return my;
|
return my;
|
||||||
}(BottomToolbar || {}));
|
}(BottomToolbar || {}));
|
||||||
|
|
||||||
|
module.exports = BottomToolbar;
|
|
@ -1,7 +1,205 @@
|
||||||
/* global $, buttonClick, config, lockRoom, messageHandler, Moderator, roomUrl,
|
/* global $, buttonClick, config, lockRoom, Moderator,
|
||||||
setSharedKey, sharedKey, Util */
|
setSharedKey, sharedKey, Util */
|
||||||
|
var messageHandler = require("../util/MessageHandler");
|
||||||
|
var BottomToolbar = require("./BottomToolbar");
|
||||||
|
var Prezi = require("../prezi/Prezi");
|
||||||
|
var Etherpad = require("../etherpad/Etherpad");
|
||||||
|
var PanelToggler = require("../side_pannels/SidePanelToggler");
|
||||||
|
|
||||||
|
var roomUrl = null;
|
||||||
|
var sharedKey = '';
|
||||||
|
var authenticationWindow = null;
|
||||||
|
|
||||||
|
var buttonHandlers =
|
||||||
|
{
|
||||||
|
"toolbar_button_mute": function () {
|
||||||
|
return toggleAudio();
|
||||||
|
},
|
||||||
|
"toolbar_button_camera": function () {
|
||||||
|
return toggleVideo();
|
||||||
|
},
|
||||||
|
"toolbar_button_authentication": function () {
|
||||||
|
return Toolbar.authenticateClicked();
|
||||||
|
},
|
||||||
|
"toolbar_button_record": function () {
|
||||||
|
return toggleRecording();
|
||||||
|
},
|
||||||
|
"toolbar_button_security": function () {
|
||||||
|
return Toolbar.openLockDialog();
|
||||||
|
},
|
||||||
|
"toolbar_button_link": function () {
|
||||||
|
return Toolbar.openLinkDialog();
|
||||||
|
},
|
||||||
|
"toolbar_button_chat": function () {
|
||||||
|
return BottomToolbar.toggleChat();
|
||||||
|
},
|
||||||
|
"toolbar_button_prezi": function () {
|
||||||
|
return Prezi.openPreziDialog();
|
||||||
|
},
|
||||||
|
"toolbar_button_etherpad": function () {
|
||||||
|
return Etherpad.toggleEtherpad(0);
|
||||||
|
},
|
||||||
|
"toolbar_button_desktopsharing": function () {
|
||||||
|
return toggleScreenSharing();
|
||||||
|
},
|
||||||
|
"toolbar_button_fullScreen": function()
|
||||||
|
{
|
||||||
|
buttonClick("#fullScreen", "icon-full-screen icon-exit-full-screen");
|
||||||
|
return Toolbar.toggleFullScreen();
|
||||||
|
},
|
||||||
|
"toolbar_button_sip": function () {
|
||||||
|
return callSipButtonClicked();
|
||||||
|
},
|
||||||
|
"toolbar_button_settings": function () {
|
||||||
|
PanelToggler.toggleSettingsMenu();
|
||||||
|
},
|
||||||
|
"toolbar_button_hangup": function () {
|
||||||
|
return hangup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts or stops the recording for the conference.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function toggleRecording() {
|
||||||
|
Recording.toggleRecording();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks / unlocks the room.
|
||||||
|
*/
|
||||||
|
function lockRoom(lock) {
|
||||||
|
var currentSharedKey = '';
|
||||||
|
if (lock)
|
||||||
|
currentSharedKey = sharedKey;
|
||||||
|
|
||||||
|
connection.emuc.lockRoom(currentSharedKey, function (res) {
|
||||||
|
// password is required
|
||||||
|
if (sharedKey)
|
||||||
|
{
|
||||||
|
console.log('set room password');
|
||||||
|
Toolbar.lockLockButton();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log('removed room password');
|
||||||
|
Toolbar.unlockLockButton();
|
||||||
|
}
|
||||||
|
}, function (err) {
|
||||||
|
console.warn('setting password failed', err);
|
||||||
|
messageHandler.showError('Lock failed',
|
||||||
|
'Failed to lock conference.',
|
||||||
|
err);
|
||||||
|
Toolbar.setSharedKey('');
|
||||||
|
}, function () {
|
||||||
|
console.warn('room passwords not supported');
|
||||||
|
messageHandler.showError('Warning',
|
||||||
|
'Room passwords are currently not supported.');
|
||||||
|
Toolbar.setSharedKey('');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invite participants to conference.
|
||||||
|
*/
|
||||||
|
function inviteParticipants() {
|
||||||
|
if (roomUrl === null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var sharedKeyText = "";
|
||||||
|
if (sharedKey && sharedKey.length > 0) {
|
||||||
|
sharedKeyText =
|
||||||
|
"This conference is password protected. Please use the " +
|
||||||
|
"following pin when joining:%0D%0A%0D%0A" +
|
||||||
|
sharedKey + "%0D%0A%0D%0A";
|
||||||
|
}
|
||||||
|
|
||||||
|
var conferenceName = roomUrl.substring(roomUrl.lastIndexOf('/') + 1);
|
||||||
|
var subject = "Invitation to a " + interfaceConfig.APP_NAME + " (" + conferenceName + ")";
|
||||||
|
var body = "Hey there, I%27d like to invite you to a " + interfaceConfig.APP_NAME +
|
||||||
|
" conference I%27ve just set up.%0D%0A%0D%0A" +
|
||||||
|
"Please click on the following link in order" +
|
||||||
|
" to join the conference.%0D%0A%0D%0A" +
|
||||||
|
roomUrl +
|
||||||
|
"%0D%0A%0D%0A" +
|
||||||
|
sharedKeyText +
|
||||||
|
"Note that " + interfaceConfig.APP_NAME + " is currently" +
|
||||||
|
" only supported by Chromium," +
|
||||||
|
" Google Chrome and Opera, so you need" +
|
||||||
|
" to be using one of these browsers.%0D%0A%0D%0A" +
|
||||||
|
"Talk to you in a sec!";
|
||||||
|
|
||||||
|
if (window.localStorage.displayname) {
|
||||||
|
body += "%0D%0A%0D%0A" + window.localStorage.displayname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceConfig.INVITATION_POWERED_BY) {
|
||||||
|
body += "%0D%0A%0D%0A--%0D%0Apowered by jitsi.org";
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open("mailto:?subject=" + subject + "&body=" + body, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
var Toolbar = (function (my) {
|
var Toolbar = (function (my) {
|
||||||
|
|
||||||
|
my.init = function () {
|
||||||
|
for(var k in buttonHandlers)
|
||||||
|
$("#" + k).click(buttonHandlers[k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets shared key
|
||||||
|
* @param sKey the shared key
|
||||||
|
*/
|
||||||
|
my.setSharedKey = function (sKey) {
|
||||||
|
sharedKey = sKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
my.closeAuthenticationWindow = function () {
|
||||||
|
if (authenticationWindow) {
|
||||||
|
authenticationWindow.close();
|
||||||
|
authenticationWindow = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my.authenticateClicked = function () {
|
||||||
|
// Get authentication URL
|
||||||
|
Moderator.getAuthUrl(function (url) {
|
||||||
|
// Open popup with authentication URL
|
||||||
|
authenticationWindow = messageHandler.openCenteredPopup(
|
||||||
|
url, 500, 400,
|
||||||
|
function () {
|
||||||
|
// On popup closed - retry room allocation
|
||||||
|
Moderator.allocateConferenceFocus(
|
||||||
|
roomName, doJoinAfterFocus);
|
||||||
|
authenticationWindow = null;
|
||||||
|
});
|
||||||
|
if (!authenticationWindow) {
|
||||||
|
Toolbar.showAuthenticateButton(true);
|
||||||
|
messageHandler.openMessageDialog(
|
||||||
|
null, "Your browser is blocking popup windows from this site." +
|
||||||
|
" Please enable popups in your browser security settings" +
|
||||||
|
" and try again.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the room invite url.
|
||||||
|
*/
|
||||||
|
my.updateRoomUrl = function (newRoomUrl) {
|
||||||
|
roomUrl = newRoomUrl;
|
||||||
|
|
||||||
|
// If the invite dialog has been already opened we update the information.
|
||||||
|
var inviteLink = document.getElementById('inviteLinkRef');
|
||||||
|
if (inviteLink) {
|
||||||
|
inviteLink.value = roomUrl;
|
||||||
|
inviteLink.select();
|
||||||
|
document.getElementById('jqi_state0_buttonInvite').disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables and enables some of the buttons.
|
* Disables and enables some of the buttons.
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +239,7 @@ var Toolbar = (function (my) {
|
||||||
"Remove",
|
"Remove",
|
||||||
function (e, v) {
|
function (e, v) {
|
||||||
if (v) {
|
if (v) {
|
||||||
setSharedKey('');
|
Toolbar.setSharedKey('');
|
||||||
lockRoom(false);
|
lockRoom(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -57,7 +255,7 @@ var Toolbar = (function (my) {
|
||||||
var lockKey = document.getElementById('lockKey');
|
var lockKey = document.getElementById('lockKey');
|
||||||
|
|
||||||
if (lockKey.value) {
|
if (lockKey.value) {
|
||||||
setSharedKey(Util.escapeHtml(lockKey.value));
|
Toolbar.setSharedKey(Util.escapeHtml(lockKey.value));
|
||||||
lockRoom(true);
|
lockRoom(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,47 +302,6 @@ var Toolbar = (function (my) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Invite participants to conference.
|
|
||||||
*/
|
|
||||||
function inviteParticipants() {
|
|
||||||
if (roomUrl === null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var sharedKeyText = "";
|
|
||||||
if (sharedKey && sharedKey.length > 0) {
|
|
||||||
sharedKeyText =
|
|
||||||
"This conference is password protected. Please use the " +
|
|
||||||
"following pin when joining:%0D%0A%0D%0A" +
|
|
||||||
sharedKey + "%0D%0A%0D%0A";
|
|
||||||
}
|
|
||||||
|
|
||||||
var conferenceName = roomUrl.substring(roomUrl.lastIndexOf('/') + 1);
|
|
||||||
var subject = "Invitation to a " + interfaceConfig.APP_NAME + " (" + conferenceName + ")";
|
|
||||||
var body = "Hey there, I%27d like to invite you to a " + interfaceConfig.APP_NAME +
|
|
||||||
" conference I%27ve just set up.%0D%0A%0D%0A" +
|
|
||||||
"Please click on the following link in order" +
|
|
||||||
" to join the conference.%0D%0A%0D%0A" +
|
|
||||||
roomUrl +
|
|
||||||
"%0D%0A%0D%0A" +
|
|
||||||
sharedKeyText +
|
|
||||||
"Note that " + interfaceConfig.APP_NAME + " is currently" +
|
|
||||||
" only supported by Chromium," +
|
|
||||||
" Google Chrome and Opera, so you need" +
|
|
||||||
" to be using one of these browsers.%0D%0A%0D%0A" +
|
|
||||||
"Talk to you in a sec!";
|
|
||||||
|
|
||||||
if (window.localStorage.displayname) {
|
|
||||||
body += "%0D%0A%0D%0A" + window.localStorage.displayname;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceConfig.INVITATION_POWERED_BY) {
|
|
||||||
body += "%0D%0A%0D%0A--%0D%0Apowered by jitsi.org";
|
|
||||||
}
|
|
||||||
|
|
||||||
window.open("mailto:?subject=" + subject + "&body=" + body, '_blank');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the settings dialog.
|
* Opens the settings dialog.
|
||||||
*/
|
*/
|
||||||
|
@ -291,3 +448,5 @@ var Toolbar = (function (my) {
|
||||||
|
|
||||||
return my;
|
return my;
|
||||||
}(Toolbar || {}));
|
}(Toolbar || {}));
|
||||||
|
|
||||||
|
module.exports = Toolbar;
|
|
@ -1,45 +1,12 @@
|
||||||
/* global $, interfaceConfig, Moderator, showDesktopSharingButton */
|
/* global $, interfaceConfig, Moderator, showDesktopSharingButton */
|
||||||
var ToolbarToggler = (function (my) {
|
|
||||||
var toolbarTimeoutObject,
|
var toolbarTimeoutObject,
|
||||||
toolbarTimeout = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
|
toolbarTimeout = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the main toolbar.
|
|
||||||
*/
|
|
||||||
my.showToolbar = function () {
|
|
||||||
var header = $("#header"),
|
|
||||||
bottomToolbar = $("#bottomToolbar");
|
|
||||||
if (!header.is(':visible') || !bottomToolbar.is(":visible")) {
|
|
||||||
header.show("slide", { direction: "up", duration: 300});
|
|
||||||
$('#subject').animate({top: "+=40"}, 300);
|
|
||||||
if (!bottomToolbar.is(":visible")) {
|
|
||||||
bottomToolbar.show(
|
|
||||||
"slide", {direction: "right", duration: 300});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toolbarTimeoutObject) {
|
|
||||||
clearTimeout(toolbarTimeoutObject);
|
|
||||||
toolbarTimeoutObject = null;
|
|
||||||
}
|
|
||||||
toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
|
|
||||||
toolbarTimeout = interfaceConfig.TOOLBAR_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Moderator.isModerator())
|
|
||||||
{
|
|
||||||
// TODO: Enable settings functionality.
|
|
||||||
// Need to uncomment the settings button in index.html.
|
|
||||||
// $('#settingsButton').css({visibility:"visible"});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show/hide desktop sharing button
|
|
||||||
showDesktopSharingButton();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hides the toolbar.
|
* Hides the toolbar.
|
||||||
*/
|
*/
|
||||||
var hideToolbar = function () {
|
function hideToolbar() {
|
||||||
var header = $("#header"),
|
var header = $("#header"),
|
||||||
bottomToolbar = $("#bottomToolbar");
|
bottomToolbar = $("#bottomToolbar");
|
||||||
var isToolbarHover = false;
|
var isToolbarHover = false;
|
||||||
|
@ -67,7 +34,41 @@ var ToolbarToggler = (function (my) {
|
||||||
else {
|
else {
|
||||||
toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
|
toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
var ToolbarToggler = {
|
||||||
|
/**
|
||||||
|
* Shows the main toolbar.
|
||||||
|
*/
|
||||||
|
showToolbar: function () {
|
||||||
|
var header = $("#header"),
|
||||||
|
bottomToolbar = $("#bottomToolbar");
|
||||||
|
if (!header.is(':visible') || !bottomToolbar.is(":visible")) {
|
||||||
|
header.show("slide", { direction: "up", duration: 300});
|
||||||
|
$('#subject').animate({top: "+=40"}, 300);
|
||||||
|
if (!bottomToolbar.is(":visible")) {
|
||||||
|
bottomToolbar.show(
|
||||||
|
"slide", {direction: "right", duration: 300});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toolbarTimeoutObject) {
|
||||||
|
clearTimeout(toolbarTimeoutObject);
|
||||||
|
toolbarTimeoutObject = null;
|
||||||
|
}
|
||||||
|
toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
|
||||||
|
toolbarTimeout = interfaceConfig.TOOLBAR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Moderator.isModerator())
|
||||||
|
{
|
||||||
|
// TODO: Enable settings functionality.
|
||||||
|
// Need to uncomment the settings button in index.html.
|
||||||
|
// $('#settingsButton').css({visibility:"visible"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show/hide desktop sharing button
|
||||||
|
showDesktopSharingButton();
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,11 +76,11 @@ var ToolbarToggler = (function (my) {
|
||||||
*
|
*
|
||||||
* @param isDock indicates what operation to perform
|
* @param isDock indicates what operation to perform
|
||||||
*/
|
*/
|
||||||
my.dockToolbar = function (isDock) {
|
dockToolbar: function (isDock) {
|
||||||
if (isDock) {
|
if (isDock) {
|
||||||
// First make sure the toolbar is shown.
|
// First make sure the toolbar is shown.
|
||||||
if (!$('#header').is(':visible')) {
|
if (!$('#header').is(':visible')) {
|
||||||
ToolbarToggler.showToolbar();
|
this.showToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then clear the time out, to dock the toolbar.
|
// Then clear the time out, to dock the toolbar.
|
||||||
|
@ -90,14 +91,14 @@ var ToolbarToggler = (function (my) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!$('#header').is(':visible')) {
|
if (!$('#header').is(':visible')) {
|
||||||
ToolbarToggler.showToolbar();
|
this.showToolbar();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
|
toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
return my;
|
module.exports = ToolbarToggler;
|
||||||
}(ToolbarToggler || {}));
|
|
|
@ -119,3 +119,5 @@ var JitsiPopover = (function () {
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
module.exports = JitsiPopover;
|
|
@ -149,4 +149,6 @@ var messageHandler = (function(my) {
|
||||||
return my;
|
return my;
|
||||||
}(messageHandler || {}));
|
}(messageHandler || {}));
|
||||||
|
|
||||||
|
module.exports = messageHandler;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/**
|
||||||
|
* Created by hristo on 12/22/14.
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* Returns the available video width.
|
||||||
|
*/
|
||||||
|
getAvailableVideoWidth: function () {
|
||||||
|
var PanelToggler = require("../side_pannels/SidePanelToggler");
|
||||||
|
var rightPanelWidth
|
||||||
|
= PanelToggler.isVisible() ? PanelToggler.getPanelSize()[0] : 0;
|
||||||
|
|
||||||
|
return window.innerWidth - rightPanelWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,410 @@
|
||||||
|
var JitsiPopover = require("../util/JitsiPopover");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs new connection indicator.
|
||||||
|
* @param videoContainer the video container associated with the indicator.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function ConnectionIndicator(videoContainer, jid, VideoLayout)
|
||||||
|
{
|
||||||
|
this.videoContainer = videoContainer;
|
||||||
|
this.bandwidth = null;
|
||||||
|
this.packetLoss = null;
|
||||||
|
this.bitrate = null;
|
||||||
|
this.showMoreValue = false;
|
||||||
|
this.resolution = null;
|
||||||
|
this.transport = [];
|
||||||
|
this.popover = null;
|
||||||
|
this.jid = jid;
|
||||||
|
this.create();
|
||||||
|
this.videoLayout = VideoLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Values for the connection quality
|
||||||
|
* @type {{98: string,
|
||||||
|
* 81: string,
|
||||||
|
* 64: string,
|
||||||
|
* 47: string,
|
||||||
|
* 30: string,
|
||||||
|
* 0: string}}
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.connectionQualityValues = {
|
||||||
|
98: "18px", //full
|
||||||
|
81: "15px",//4 bars
|
||||||
|
64: "11px",//3 bars
|
||||||
|
47: "7px",//2 bars
|
||||||
|
30: "3px",//1 bar
|
||||||
|
0: "0px"//empty
|
||||||
|
};
|
||||||
|
|
||||||
|
ConnectionIndicator.getIP = function(value)
|
||||||
|
{
|
||||||
|
return value.substring(0, value.lastIndexOf(":"));
|
||||||
|
};
|
||||||
|
|
||||||
|
ConnectionIndicator.getPort = function(value)
|
||||||
|
{
|
||||||
|
return value.substring(value.lastIndexOf(":") + 1, value.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
ConnectionIndicator.getStringFromArray = function (array) {
|
||||||
|
var res = "";
|
||||||
|
for(var i = 0; i < array.length; i++)
|
||||||
|
{
|
||||||
|
res += (i === 0? "" : ", ") + array[i];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the html content.
|
||||||
|
* @returns {string} the html content.
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.generateText = function () {
|
||||||
|
var downloadBitrate, uploadBitrate, packetLoss, resolution, i;
|
||||||
|
|
||||||
|
if(this.bitrate === null)
|
||||||
|
{
|
||||||
|
downloadBitrate = "N/A";
|
||||||
|
uploadBitrate = "N/A";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
downloadBitrate =
|
||||||
|
this.bitrate.download? this.bitrate.download + " Kbps" : "N/A";
|
||||||
|
uploadBitrate =
|
||||||
|
this.bitrate.upload? this.bitrate.upload + " Kbps" : "N/A";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.packetLoss === null)
|
||||||
|
{
|
||||||
|
packetLoss = "N/A";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
packetLoss = "<span class='jitsipopover_green'>↓</span>" +
|
||||||
|
(this.packetLoss.download !== null? this.packetLoss.download : "N/A") +
|
||||||
|
"% <span class='jitsipopover_orange'>↑</span>" +
|
||||||
|
(this.packetLoss.upload !== null? this.packetLoss.upload : "N/A") + "%";
|
||||||
|
}
|
||||||
|
|
||||||
|
var resolutionValue = null;
|
||||||
|
if(this.resolution)
|
||||||
|
{
|
||||||
|
var keys = Object.keys(this.resolution);
|
||||||
|
if(keys.length == 1)
|
||||||
|
{
|
||||||
|
for(var ssrc in this.resolution)
|
||||||
|
{
|
||||||
|
resolutionValue = this.resolution[ssrc];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keys.length > 1)
|
||||||
|
{
|
||||||
|
var displayedSsrc = simulcast.getReceivingSSRC(this.jid);
|
||||||
|
resolutionValue = this.resolution[displayedSsrc];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.jid === null)
|
||||||
|
{
|
||||||
|
resolution = "";
|
||||||
|
if(this.resolution === null || !Object.keys(this.resolution) ||
|
||||||
|
Object.keys(this.resolution).length === 0)
|
||||||
|
{
|
||||||
|
resolution = "N/A";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for(i in this.resolution)
|
||||||
|
{
|
||||||
|
resolutionValue = this.resolution[i];
|
||||||
|
if(resolutionValue)
|
||||||
|
{
|
||||||
|
if(resolutionValue.height &&
|
||||||
|
resolutionValue.width)
|
||||||
|
{
|
||||||
|
resolution += (resolution === ""? "" : ", ") +
|
||||||
|
resolutionValue.width + "x" +
|
||||||
|
resolutionValue.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!resolutionValue ||
|
||||||
|
!resolutionValue.height ||
|
||||||
|
!resolutionValue.width)
|
||||||
|
{
|
||||||
|
resolution = "N/A";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resolution = resolutionValue.width + "x" + resolutionValue.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = "<table style='width:100%'>" +
|
||||||
|
"<tr>" +
|
||||||
|
"<td><span class='jitsipopover_blue'>Bitrate:</span></td>" +
|
||||||
|
"<td><span class='jitsipopover_green'>↓</span>" +
|
||||||
|
downloadBitrate + " <span class='jitsipopover_orange'>↑</span>" +
|
||||||
|
uploadBitrate + "</td>" +
|
||||||
|
"</tr><tr>" +
|
||||||
|
"<td><span class='jitsipopover_blue'>Packet loss: </span></td>" +
|
||||||
|
"<td>" + packetLoss + "</td>" +
|
||||||
|
"</tr><tr>" +
|
||||||
|
"<td><span class='jitsipopover_blue'>Resolution:</span></td>" +
|
||||||
|
"<td>" + resolution + "</td></tr></table>";
|
||||||
|
|
||||||
|
if(this.videoContainer.id == "localVideoContainer")
|
||||||
|
result += "<div class=\"jitsipopover_showmore\" " +
|
||||||
|
"onclick = \"UI.connectionIndicatorShowMore('" +
|
||||||
|
this.videoContainer.id + "')\">" +
|
||||||
|
(this.showMoreValue? "Show less" : "Show More") + "</div><br />";
|
||||||
|
|
||||||
|
if(this.showMoreValue)
|
||||||
|
{
|
||||||
|
var downloadBandwidth, uploadBandwidth, transport;
|
||||||
|
if(this.bandwidth === null)
|
||||||
|
{
|
||||||
|
downloadBandwidth = "N/A";
|
||||||
|
uploadBandwidth = "N/A";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
downloadBandwidth = this.bandwidth.download?
|
||||||
|
this.bandwidth.download + " Kbps" :
|
||||||
|
"N/A";
|
||||||
|
uploadBandwidth = this.bandwidth.upload?
|
||||||
|
this.bandwidth.upload + " Kbps" :
|
||||||
|
"N/A";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.transport || this.transport.length === 0)
|
||||||
|
{
|
||||||
|
transport = "<tr>" +
|
||||||
|
"<td><span class='jitsipopover_blue'>Address:</span></td>" +
|
||||||
|
"<td> N/A</td></tr>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var data = {remoteIP: [], localIP:[], remotePort:[], localPort:[]};
|
||||||
|
for(i = 0; i < this.transport.length; i++)
|
||||||
|
{
|
||||||
|
var ip = ConnectionIndicator.getIP(this.transport[i].ip);
|
||||||
|
var port = ConnectionIndicator.getPort(this.transport[i].ip);
|
||||||
|
var localIP =
|
||||||
|
ConnectionIndicator.getIP(this.transport[i].localip);
|
||||||
|
var localPort =
|
||||||
|
ConnectionIndicator.getPort(this.transport[i].localip);
|
||||||
|
if(data.remoteIP.indexOf(ip) == -1)
|
||||||
|
{
|
||||||
|
data.remoteIP.push(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data.remotePort.indexOf(port) == -1)
|
||||||
|
{
|
||||||
|
data.remotePort.push(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data.localIP.indexOf(localIP) == -1)
|
||||||
|
{
|
||||||
|
data.localIP.push(localIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data.localPort.indexOf(localPort) == -1)
|
||||||
|
{
|
||||||
|
data.localPort.push(localPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
var localTransport =
|
||||||
|
"<tr><td><span class='jitsipopover_blue'>Local address" +
|
||||||
|
(data.localIP.length > 1? "es" : "") + ": </span></td><td> " +
|
||||||
|
ConnectionIndicator.getStringFromArray(data.localIP) +
|
||||||
|
"</td></tr>";
|
||||||
|
transport =
|
||||||
|
"<tr><td><span class='jitsipopover_blue'>Remote address"+
|
||||||
|
(data.remoteIP.length > 1? "es" : "") + ":</span></td><td> " +
|
||||||
|
ConnectionIndicator.getStringFromArray(data.remoteIP) +
|
||||||
|
"</td></tr>";
|
||||||
|
if(this.transport.length > 1)
|
||||||
|
{
|
||||||
|
transport += "<tr>" +
|
||||||
|
"<td>" +
|
||||||
|
"<span class='jitsipopover_blue'>Remote ports:</span>" +
|
||||||
|
"</td><td>";
|
||||||
|
localTransport += "<tr>" +
|
||||||
|
"<td>" +
|
||||||
|
"<span class='jitsipopover_blue'>Local ports:</span>" +
|
||||||
|
"</td><td>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transport +=
|
||||||
|
"<tr>" +
|
||||||
|
"<td>" +
|
||||||
|
"<span class='jitsipopover_blue'>Remote port:</span>" +
|
||||||
|
"</td><td>";
|
||||||
|
localTransport +=
|
||||||
|
"<tr>" +
|
||||||
|
"<td>" +
|
||||||
|
"<span class='jitsipopover_blue'>Local port:</span>" +
|
||||||
|
"</td><td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
transport +=
|
||||||
|
ConnectionIndicator.getStringFromArray(data.remotePort);
|
||||||
|
localTransport +=
|
||||||
|
ConnectionIndicator.getStringFromArray(data.localPort);
|
||||||
|
transport += "</td></tr>";
|
||||||
|
transport += localTransport + "</td></tr>";
|
||||||
|
transport +="<tr>" +
|
||||||
|
"<td><span class='jitsipopover_blue'>Transport:</span></td>" +
|
||||||
|
"<td>" + this.transport[0].type + "</td></tr>";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
result += "<table style='width:100%'>" +
|
||||||
|
"<tr>" +
|
||||||
|
"<td>" +
|
||||||
|
"<span class='jitsipopover_blue'>Estimated bandwidth:</span>" +
|
||||||
|
"</td><td>" +
|
||||||
|
"<span class='jitsipopover_green'>↓</span>" +
|
||||||
|
downloadBandwidth +
|
||||||
|
" <span class='jitsipopover_orange'>↑</span>" +
|
||||||
|
uploadBandwidth + "</td></tr>";
|
||||||
|
|
||||||
|
result += transport + "</table>";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows or hide the additional information.
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.showMore = function () {
|
||||||
|
this.showMoreValue = !this.showMoreValue;
|
||||||
|
this.updatePopoverData();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function createIcon(classes)
|
||||||
|
{
|
||||||
|
var icon = document.createElement("span");
|
||||||
|
for(var i in classes)
|
||||||
|
{
|
||||||
|
icon.classList.add(classes[i]);
|
||||||
|
}
|
||||||
|
icon.appendChild(
|
||||||
|
document.createElement("i")).classList.add("icon-connection");
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the indicator
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.create = function () {
|
||||||
|
this.connectionIndicatorContainer = document.createElement("div");
|
||||||
|
this.connectionIndicatorContainer.className = "connectionindicator";
|
||||||
|
this.connectionIndicatorContainer.style.display = "none";
|
||||||
|
this.videoContainer.appendChild(this.connectionIndicatorContainer);
|
||||||
|
this.popover = new JitsiPopover(
|
||||||
|
$("#" + this.videoContainer.id + " > .connectionindicator"),
|
||||||
|
{content: "<div class=\"connection_info\">Come back here for " +
|
||||||
|
"connection information once the conference starts</div>",
|
||||||
|
skin: "black"});
|
||||||
|
|
||||||
|
this.emptyIcon = this.connectionIndicatorContainer.appendChild(
|
||||||
|
createIcon(["connection", "connection_empty"]));
|
||||||
|
this.fullIcon = this.connectionIndicatorContainer.appendChild(
|
||||||
|
createIcon(["connection", "connection_full"]));
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the indicator
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.remove = function()
|
||||||
|
{
|
||||||
|
this.connectionIndicatorContainer.remove();
|
||||||
|
this.popover.forceHide();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the data of the indicator
|
||||||
|
* @param percent the percent of connection quality
|
||||||
|
* @param object the statistics data.
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.updateConnectionQuality =
|
||||||
|
function (percent, object) {
|
||||||
|
|
||||||
|
if(percent === null)
|
||||||
|
{
|
||||||
|
this.connectionIndicatorContainer.style.display = "none";
|
||||||
|
this.popover.forceHide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(this.connectionIndicatorContainer.style.display == "none") {
|
||||||
|
this.connectionIndicatorContainer.style.display = "block";
|
||||||
|
this.videoLayout.updateMutePosition(this.videoContainer.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.bandwidth = object.bandwidth;
|
||||||
|
this.bitrate = object.bitrate;
|
||||||
|
this.packetLoss = object.packetLoss;
|
||||||
|
this.transport = object.transport;
|
||||||
|
if(object.resolution)
|
||||||
|
{
|
||||||
|
this.resolution = object.resolution;
|
||||||
|
}
|
||||||
|
for(var quality in ConnectionIndicator.connectionQualityValues)
|
||||||
|
{
|
||||||
|
if(percent >= quality)
|
||||||
|
{
|
||||||
|
this.fullIcon.style.width =
|
||||||
|
ConnectionIndicator.connectionQualityValues[quality];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updatePopoverData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the resolution
|
||||||
|
* @param resolution the new resolution
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.updateResolution = function (resolution) {
|
||||||
|
this.resolution = resolution;
|
||||||
|
this.updatePopoverData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the content of the popover
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.updatePopoverData = function () {
|
||||||
|
this.popover.updateContent(
|
||||||
|
"<div class=\"connection_info\">" + this.generateText() + "</div>");
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the popover
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.hide = function () {
|
||||||
|
this.popover.forceHide();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the indicator
|
||||||
|
*/
|
||||||
|
ConnectionIndicator.prototype.hideIndicator = function () {
|
||||||
|
this.connectionIndicatorContainer.style.display = "none";
|
||||||
|
if(this.popover)
|
||||||
|
this.popover.forceHide();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = ConnectionIndicator;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,179 @@
|
||||||
|
//var nouns = [
|
||||||
|
//];
|
||||||
|
var pluralNouns = [
|
||||||
|
"Aliens", "Animals", "Antelopes", "Ants", "Apes", "Apples", "Baboons", "Bacteria", "Badgers", "Bananas", "Bats",
|
||||||
|
"Bears", "Birds", "Bonobos", "Brides", "Bugs", "Bulls", "Butterflies", "Cheetahs",
|
||||||
|
"Cherries", "Chicken", "Children", "Chimps", "Clowns", "Cows", "Creatures", "Dinosaurs", "Dogs", "Dolphins",
|
||||||
|
"Donkeys", "Dragons", "Ducks", "Dwarfs", "Eagles", "Elephants", "Elves", "FAIL", "Fathers",
|
||||||
|
"Fish", "Flowers", "Frogs", "Fruit", "Fungi", "Galaxies", "Geese", "Goats",
|
||||||
|
"Gorillas", "Hedgehogs", "Hippos", "Horses", "Hunters", "Insects", "Kids", "Knights",
|
||||||
|
"Lemons", "Lemurs", "Leopards", "LifeForms", "Lions", "Lizards", "Mice", "Monkeys", "Monsters",
|
||||||
|
"Mushrooms", "Octopodes", "Oranges", "Orangutans", "Organisms", "Pants", "Parrots", "Penguins",
|
||||||
|
"People", "Pigeons", "Pigs", "Pineapples", "Plants", "Potatoes", "Priests", "Rats", "Reptiles", "Reptilians",
|
||||||
|
"Rhinos", "Seagulls", "Sheep", "Siblings", "Snakes", "Spaghetti", "Spiders", "Squid", "Squirrels",
|
||||||
|
"Stars", "Students", "Teachers", "Tigers", "Tomatoes", "Trees", "Vampires", "Vegetables", "Viruses", "Vulcans",
|
||||||
|
"Warewolves", "Weasels", "Whales", "Witches", "Wizards", "Wolves", "Workers", "Worms", "Zebras"
|
||||||
|
];
|
||||||
|
//var places = [
|
||||||
|
//"Pub", "University", "Airport", "Library", "Mall", "Theater", "Stadium", "Office", "Show", "Gallows", "Beach",
|
||||||
|
// "Cemetery", "Hospital", "Reception", "Restaurant", "Bar", "Church", "House", "School", "Square", "Village",
|
||||||
|
// "Cinema", "Movies", "Party", "Restroom", "End", "Jail", "PostOffice", "Station", "Circus", "Gates", "Entrance",
|
||||||
|
// "Bridge"
|
||||||
|
//];
|
||||||
|
var verbs = [
|
||||||
|
"Abandon", "Adapt", "Advertise", "Answer", "Anticipate", "Appreciate",
|
||||||
|
"Approach", "Argue", "Ask", "Bite", "Blossom", "Blush", "Breathe", "Breed", "Bribe", "Burn", "Calculate",
|
||||||
|
"Clean", "Code", "Communicate", "Compute", "Confess", "Confiscate", "Conjugate", "Conjure", "Consume",
|
||||||
|
"Contemplate", "Crawl", "Dance", "Delegate", "Devour", "Develop", "Differ", "Discuss",
|
||||||
|
"Dissolve", "Drink", "Eat", "Elaborate", "Emancipate", "Estimate", "Expire", "Extinguish",
|
||||||
|
"Extract", "FAIL", "Facilitate", "Fall", "Feed", "Finish", "Floss", "Fly", "Follow", "Fragment", "Freeze",
|
||||||
|
"Gather", "Glow", "Grow", "Hex", "Hide", "Hug", "Hurry", "Improve", "Intersect", "Investigate", "Jinx",
|
||||||
|
"Joke", "Jubilate", "Kiss", "Laugh", "Manage", "Meet", "Merge", "Move", "Object", "Observe", "Offer",
|
||||||
|
"Paint", "Participate", "Party", "Perform", "Plan", "Pursue", "Pierce", "Play", "Postpone", "Pray", "Proclaim",
|
||||||
|
"Question", "Read", "Reckon", "Rejoice", "Represent", "Resize", "Rhyme", "Scream", "Search", "Select", "Share", "Shoot",
|
||||||
|
"Shout", "Signal", "Sing", "Skate", "Sleep", "Smile", "Smoke", "Solve", "Spell", "Steer", "Stink",
|
||||||
|
"Substitute", "Swim", "Taste", "Teach", "Terminate", "Think", "Type", "Unite", "Vanish", "Worship"
|
||||||
|
];
|
||||||
|
var adverbs = [
|
||||||
|
"Absently", "Accurately", "Accusingly", "Adorably", "AllTheTime", "Alone", "Always", "Amazingly", "Angrily",
|
||||||
|
"Anxiously", "Anywhere", "Appallingly", "Apparently", "Articulately", "Astonishingly", "Badly", "Barely",
|
||||||
|
"Beautifully", "Blindly", "Bravely", "Brightly", "Briskly", "Brutally", "Calmly", "Carefully", "Casually",
|
||||||
|
"Cautiously", "Cleverly", "Constantly", "Correctly", "Crazily", "Curiously", "Cynically", "Daily",
|
||||||
|
"Dangerously", "Deliberately", "Delicately", "Desperately", "Discreetly", "Eagerly", "Easily", "Euphoricly",
|
||||||
|
"Evenly", "Everywhere", "Exactly", "Expectantly", "Extensively", "FAIL", "Ferociously", "Fiercely", "Finely",
|
||||||
|
"Flatly", "Frequently", "Frighteningly", "Gently", "Gloriously", "Grimly", "Guiltily", "Happily",
|
||||||
|
"Hard", "Hastily", "Heroically", "High", "Highly", "Hourly", "Humbly", "Hysterically", "Immensely",
|
||||||
|
"Impartially", "Impolitely", "Indifferently", "Intensely", "Jealously", "Jovially", "Kindly", "Lazily",
|
||||||
|
"Lightly", "Loudly", "Lovingly", "Loyally", "Magnificently", "Malevolently", "Merrily", "Mightily", "Miserably",
|
||||||
|
"Mysteriously", "NOT", "Nervously", "Nicely", "Nowhere", "Objectively", "Obnoxiously", "Obsessively",
|
||||||
|
"Obviously", "Often", "Painfully", "Patiently", "Playfully", "Politely", "Poorly", "Precisely", "Promptly",
|
||||||
|
"Quickly", "Quietly", "Randomly", "Rapidly", "Rarely", "Recklessly", "Regularly", "Remorsefully", "Responsibly",
|
||||||
|
"Rudely", "Ruthlessly", "Sadly", "Scornfully", "Seamlessly", "Seldom", "Selfishly", "Seriously", "Shakily",
|
||||||
|
"Sharply", "Sideways", "Silently", "Sleepily", "Slightly", "Slowly", "Slyly", "Smoothly", "Softly", "Solemnly", "Steadily", "Sternly", "Strangely", "Strongly", "Stunningly", "Surely", "Tenderly", "Thoughtfully",
|
||||||
|
"Tightly", "Uneasily", "Vanishingly", "Violently", "Warmly", "Weakly", "Wearily", "Weekly", "Weirdly", "Well",
|
||||||
|
"Well", "Wickedly", "Wildly", "Wisely", "Wonderfully", "Yearly"
|
||||||
|
];
|
||||||
|
var adjectives = [
|
||||||
|
"Abominable", "Accurate", "Adorable", "All", "Alleged", "Ancient", "Angry", "Angry", "Anxious", "Appalling",
|
||||||
|
"Apparent", "Astonishing", "Attractive", "Awesome", "Baby", "Bad", "Beautiful", "Benign", "Big", "Bitter",
|
||||||
|
"Blind", "Blue", "Bold", "Brave", "Bright", "Brisk", "Calm", "Camouflaged", "Casual", "Cautious",
|
||||||
|
"Choppy", "Chosen", "Clever", "Cold", "Cool", "Crawly", "Crazy", "Creepy", "Cruel", "Curious", "Cynical",
|
||||||
|
"Dangerous", "Dark", "Delicate", "Desperate", "Difficult", "Discreet", "Disguised", "Dizzy",
|
||||||
|
"Dumb", "Eager", "Easy", "Edgy", "Electric", "Elegant", "Emancipated", "Enormous", "Euphoric", "Evil",
|
||||||
|
"FAIL", "Fast", "Ferocious", "Fierce", "Fine", "Flawed", "Flying", "Foolish", "Foxy",
|
||||||
|
"Freezing", "Funny", "Furious", "Gentle", "Glorious", "Golden", "Good", "Green", "Green", "Guilty",
|
||||||
|
"Hairy", "Happy", "Hard", "Hasty", "Hazy", "Heroic", "Hostile", "Hot", "Humble", "Humongous",
|
||||||
|
"Humorous", "Hysterical", "Idealistic", "Ignorant", "Immense", "Impartial", "Impolite", "Indifferent",
|
||||||
|
"Infuriated", "Insightful", "Intense", "Interesting", "Intimidated", "Intriguing", "Jealous", "Jolly", "Jovial",
|
||||||
|
"Jumpy", "Kind", "Laughing", "Lazy", "Liquid", "Lonely", "Longing", "Loud", "Loving", "Loyal", "Macabre", "Mad",
|
||||||
|
"Magical", "Magnificent", "Malevolent", "Medieval", "Memorable", "Mere", "Merry", "Mighty",
|
||||||
|
"Mischievous", "Miserable", "Modified", "Moody", "Most", "Mysterious", "Mystical", "Needy",
|
||||||
|
"Nervous", "Nice", "Objective", "Obnoxious", "Obsessive", "Obvious", "Opinionated", "Orange",
|
||||||
|
"Painful", "Passionate", "Perfect", "Pink", "Playful", "Poisonous", "Polite", "Poor", "Popular", "Powerful",
|
||||||
|
"Precise", "Preserved", "Pretty", "Purple", "Quick", "Quiet", "Random", "Rapid", "Rare", "Real",
|
||||||
|
"Reassuring", "Reckless", "Red", "Regular", "Remorseful", "Responsible", "Rich", "Rude", "Ruthless",
|
||||||
|
"Sad", "Scared", "Scary", "Scornful", "Screaming", "Selfish", "Serious", "Shady", "Shaky", "Sharp",
|
||||||
|
"Shiny", "Shy", "Simple", "Sleepy", "Slow", "Sly", "Small", "Smart", "Smelly", "Smiling", "Smooth",
|
||||||
|
"Smug", "Sober", "Soft", "Solemn", "Square", "Square", "Steady", "Strange", "Strong",
|
||||||
|
"Stunning", "Subjective", "Successful", "Surly", "Sweet", "Tactful", "Tense",
|
||||||
|
"Thoughtful", "Tight", "Tiny", "Tolerant", "Uneasy", "Unique", "Unseen", "Warm", "Weak",
|
||||||
|
"Weird", "WellCooked", "Wild", "Wise", "Witty", "Wonderful", "Worried", "Yellow", "Young",
|
||||||
|
"Zealous"
|
||||||
|
];
|
||||||
|
//var pronouns = [
|
||||||
|
//];
|
||||||
|
//var conjunctions = [
|
||||||
|
//"And", "Or", "For", "Above", "Before", "Against", "Between"
|
||||||
|
//];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maps a string (category name) to the array of words from that category.
|
||||||
|
*/
|
||||||
|
var CATEGORIES =
|
||||||
|
{
|
||||||
|
//"_NOUN_": nouns,
|
||||||
|
"_PLURALNOUN_": pluralNouns,
|
||||||
|
//"_PLACE_": places,
|
||||||
|
"_VERB_": verbs,
|
||||||
|
"_ADVERB_": adverbs,
|
||||||
|
"_ADJECTIVE_": adjectives
|
||||||
|
//"_PRONOUN_": pronouns,
|
||||||
|
//"_CONJUNCTION_": conjunctions,
|
||||||
|
};
|
||||||
|
|
||||||
|
var PATTERNS = [
|
||||||
|
"_ADJECTIVE__PLURALNOUN__VERB__ADVERB_"
|
||||||
|
|
||||||
|
// BeautifulFungiOrSpaghetti
|
||||||
|
//"_ADJECTIVE__PLURALNOUN__CONJUNCTION__PLURALNOUN_",
|
||||||
|
|
||||||
|
// AmazinglyScaryToy
|
||||||
|
//"_ADVERB__ADJECTIVE__NOUN_",
|
||||||
|
|
||||||
|
// NeitherTrashNorRifle
|
||||||
|
//"Neither_NOUN_Nor_NOUN_",
|
||||||
|
//"Either_NOUN_Or_NOUN_",
|
||||||
|
|
||||||
|
// EitherCopulateOrInvestigate
|
||||||
|
//"Either_VERB_Or_VERB_",
|
||||||
|
//"Neither_VERB_Nor_VERB_",
|
||||||
|
|
||||||
|
//"The_ADJECTIVE__ADJECTIVE__NOUN_",
|
||||||
|
//"The_ADVERB__ADJECTIVE__NOUN_",
|
||||||
|
//"The_ADVERB__ADJECTIVE__NOUN_s",
|
||||||
|
//"The_ADVERB__ADJECTIVE__PLURALNOUN__VERB_",
|
||||||
|
|
||||||
|
// WolvesComputeBadly
|
||||||
|
//"_PLURALNOUN__VERB__ADVERB_",
|
||||||
|
|
||||||
|
// UniteFacilitateAndMerge
|
||||||
|
//"_VERB__VERB_And_VERB_",
|
||||||
|
|
||||||
|
//NastyWitchesAtThePub
|
||||||
|
//"_ADJECTIVE__PLURALNOUN_AtThe_PLACE_",
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a random element from the array 'arr'
|
||||||
|
*/
|
||||||
|
function randomElement(arr)
|
||||||
|
{
|
||||||
|
return arr[Math.floor(Math.random() * arr.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if the string 's' contains one of the
|
||||||
|
* template strings.
|
||||||
|
*/
|
||||||
|
function hasTemplate(s)
|
||||||
|
{
|
||||||
|
for (var template in CATEGORIES){
|
||||||
|
if (s.indexOf(template) >= 0){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates new room name.
|
||||||
|
*/
|
||||||
|
var RoomNameGenerator = {
|
||||||
|
generateRoomWithoutSeparator: function()
|
||||||
|
{
|
||||||
|
// Note that if more than one pattern is available, the choice of 'name' won't be random (names from patterns
|
||||||
|
// with fewer options will have higher probability of being chosen that names from patterns with more options).
|
||||||
|
var name = randomElement(PATTERNS);
|
||||||
|
var word;
|
||||||
|
while (hasTemplate(name)){
|
||||||
|
for (var template in CATEGORIES){
|
||||||
|
word = randomElement(CATEGORIES[template]);
|
||||||
|
name = name.replace(template, word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RoomNameGenerator;
|
|
@ -0,0 +1,103 @@
|
||||||
|
var animateTimeout, updateTimeout;
|
||||||
|
|
||||||
|
var RoomNameGenerator = require("./RoomnameGenerator");
|
||||||
|
|
||||||
|
function enter_room()
|
||||||
|
{
|
||||||
|
var val = $("#enter_room_field").val();
|
||||||
|
if(!val) {
|
||||||
|
val = $("#enter_room_field").attr("room_name");
|
||||||
|
}
|
||||||
|
if (val) {
|
||||||
|
window.location.pathname = "/" + val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate(word) {
|
||||||
|
var currentVal = $("#enter_room_field").attr("placeholder");
|
||||||
|
$("#enter_room_field").attr("placeholder", currentVal + word.substr(0, 1));
|
||||||
|
animateTimeout = setTimeout(function() {
|
||||||
|
animate(word.substring(1, word.length))
|
||||||
|
}, 70);
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_roomname()
|
||||||
|
{
|
||||||
|
var word = RoomNameGenerator.generateRoomWithoutSeparator();
|
||||||
|
$("#enter_room_field").attr("room_name", word);
|
||||||
|
$("#enter_room_field").attr("placeholder", "");
|
||||||
|
clearTimeout(animateTimeout);
|
||||||
|
animate(word);
|
||||||
|
updateTimeout = setTimeout(update_roomname, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setupWelcomePage()
|
||||||
|
{
|
||||||
|
$("#videoconference_page").hide();
|
||||||
|
$("#domain_name").text(
|
||||||
|
window.location.protocol + "//" + window.location.host + "/");
|
||||||
|
$("span[name='appName']").text(interfaceConfig.APP_NAME);
|
||||||
|
|
||||||
|
if (interfaceConfig.SHOW_JITSI_WATERMARK) {
|
||||||
|
var leftWatermarkDiv
|
||||||
|
= $("#welcome_page_header div[class='watermark leftwatermark']");
|
||||||
|
if(leftWatermarkDiv && leftWatermarkDiv.length > 0)
|
||||||
|
{
|
||||||
|
leftWatermarkDiv.css({display: 'block'});
|
||||||
|
leftWatermarkDiv.parent().get(0).href
|
||||||
|
= interfaceConfig.JITSI_WATERMARK_LINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceConfig.SHOW_BRAND_WATERMARK) {
|
||||||
|
var rightWatermarkDiv
|
||||||
|
= $("#welcome_page_header div[class='watermark rightwatermark']");
|
||||||
|
if(rightWatermarkDiv && rightWatermarkDiv.length > 0) {
|
||||||
|
rightWatermarkDiv.css({display: 'block'});
|
||||||
|
rightWatermarkDiv.parent().get(0).href
|
||||||
|
= interfaceConfig.BRAND_WATERMARK_LINK;
|
||||||
|
rightWatermarkDiv.get(0).style.backgroundImage
|
||||||
|
= "url(images/rightwatermark.png)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceConfig.SHOW_POWERED_BY) {
|
||||||
|
$("#welcome_page_header>a[class='poweredby']")
|
||||||
|
.css({display: 'block'});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#enter_room_button").click(function()
|
||||||
|
{
|
||||||
|
enter_room();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#enter_room_field").keydown(function (event) {
|
||||||
|
if (event.keyCode === 13 /* enter */) {
|
||||||
|
enter_room();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!(interfaceConfig.GENERATE_ROOMNAMES_ON_WELCOME_PAGE === false)){
|
||||||
|
var updateTimeout;
|
||||||
|
var animateTimeout;
|
||||||
|
$("#reload_roomname").click(function () {
|
||||||
|
clearTimeout(updateTimeout);
|
||||||
|
clearTimeout(animateTimeout);
|
||||||
|
update_roomname();
|
||||||
|
});
|
||||||
|
$("#reload_roomname").show();
|
||||||
|
|
||||||
|
|
||||||
|
update_roomname();
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#disable_welcome").click(function () {
|
||||||
|
window.localStorage.welcomePageDisabled
|
||||||
|
= $("#disable_welcome").is(":checked");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = setupWelcomePage;
|
|
@ -51,10 +51,10 @@ function startRemoteStats (peerconnection) {
|
||||||
|
|
||||||
function onStreamCreated(stream)
|
function onStreamCreated(stream)
|
||||||
{
|
{
|
||||||
if(stream.getAudioTracks().length === 0)
|
if(stream.getOriginalStream().getAudioTracks().length === 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
localStats = new LocalStats(stream, 100, this,
|
localStats = new LocalStats(stream.getOriginalStream(), 100, statistics,
|
||||||
eventEmitter);
|
eventEmitter);
|
||||||
localStats.start();
|
localStats.start();
|
||||||
}
|
}
|
||||||
|
|
112
muc.js
112
muc.js
|
@ -49,6 +49,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
onPresence: function (pres) {
|
onPresence: function (pres) {
|
||||||
var from = pres.getAttribute('from');
|
var from = pres.getAttribute('from');
|
||||||
var type = pres.getAttribute('type');
|
var type = pres.getAttribute('type');
|
||||||
|
console.debug("Presence " + from + " - " + type);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +57,9 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
// Parse etherpad tag.
|
// Parse etherpad tag.
|
||||||
var etherpad = $(pres).find('>etherpad');
|
var etherpad = $(pres).find('>etherpad');
|
||||||
if (etherpad.length) {
|
if (etherpad.length) {
|
||||||
$(document).trigger('etherpadadded.muc', [from, etherpad.text()]);
|
if (config.etherpad_base && !Moderator.isModerator()) {
|
||||||
|
UI.initEtherpad(etherpad.text());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse prezi tag.
|
// Parse prezi tag.
|
||||||
|
@ -138,24 +141,40 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
if (member.affiliation == 'owner') this.isOwner = true;
|
if (member.affiliation == 'owner') this.isOwner = true;
|
||||||
if (this.role !== member.role) {
|
if (this.role !== member.role) {
|
||||||
this.role = member.role;
|
this.role = member.role;
|
||||||
$(document).trigger('local.role.changed.muc', [from, member, pres]);
|
if(Moderator.onLocalRoleChange)
|
||||||
|
Moderator.onLocalRoleChange(from, member, pres);
|
||||||
|
UI.onLocalRoleChange(from, member, pres);
|
||||||
}
|
}
|
||||||
if (!this.joined) {
|
if (!this.joined) {
|
||||||
this.joined = true;
|
this.joined = true;
|
||||||
$(document).trigger('joined.muc', [from, member]);
|
$(document).trigger('joined.muc', [from, member]);
|
||||||
|
UI.onMucJoined(from, member);
|
||||||
this.list_members.push(from);
|
this.list_members.push(from);
|
||||||
}
|
}
|
||||||
} else if (this.members[from] === undefined) {
|
} else if (this.members[from] === undefined) {
|
||||||
// new participant
|
// new participant
|
||||||
this.members[from] = member;
|
this.members[from] = member;
|
||||||
this.list_members.push(from);
|
this.list_members.push(from);
|
||||||
$(document).trigger('entered.muc', [from, member, pres]);
|
console.log('entered', from, member);
|
||||||
|
if (member.isFocus)
|
||||||
|
{
|
||||||
|
focusMucJid = from;
|
||||||
|
console.info("Ignore focus: " + from +", real JID: " + member.jid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var id = $(pres).find('>userID').text();
|
||||||
|
var email = $(pres).find('>email');
|
||||||
|
if (email.length > 0) {
|
||||||
|
id = email.text();
|
||||||
|
}
|
||||||
|
UI.onMucEntered(from, id, member.displayName);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Presence update for existing participant
|
// Presence update for existing participant
|
||||||
// Watch role change:
|
// Watch role change:
|
||||||
if (this.members[from].role != member.role) {
|
if (this.members[from].role != member.role) {
|
||||||
this.members[from].role = member.role
|
this.members[from].role = member.role;
|
||||||
$(document).trigger('role.changed.muc', [from, member, pres]);
|
UI.onMucRoleChanged(member.role, member.displayName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Always trigger presence to update bindings
|
// Always trigger presence to update bindings
|
||||||
|
@ -164,7 +183,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
|
|
||||||
// Trigger status message update
|
// Trigger status message update
|
||||||
if (member.status) {
|
if (member.status) {
|
||||||
$(document).trigger('presence.status.muc', [from, member, pres]);
|
UI.onMucPresenceStatus(from, member);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -175,7 +194,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
if (!$(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="110"]').length) {
|
if (!$(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="110"]').length) {
|
||||||
delete this.members[from];
|
delete this.members[from];
|
||||||
this.list_members.splice(this.list_members.indexOf(from), 1);
|
this.list_members.splice(this.list_members.indexOf(from), 1);
|
||||||
$(document).trigger('left.muc', [from]);
|
this.onParticipantLeft(from);
|
||||||
}
|
}
|
||||||
// If the status code is 110 this means we're leaving and we would like
|
// If the status code is 110 this means we're leaving and we would like
|
||||||
// to remove everyone else from our view, so we trigger the event.
|
// to remove everyone else from our view, so we trigger the event.
|
||||||
|
@ -184,7 +203,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
var member = this.list_members[i];
|
var member = this.list_members[i];
|
||||||
delete this.members[i];
|
delete this.members[i];
|
||||||
this.list_members.splice(i, 1);
|
this.list_members.splice(i, 1);
|
||||||
$(document).trigger('left.muc', member);
|
this.onParticipantLeft(member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="307"]').length) {
|
if ($(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="307"]').length) {
|
||||||
|
@ -195,7 +214,11 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
onPresenceError: function (pres) {
|
onPresenceError: function (pres) {
|
||||||
var from = pres.getAttribute('from');
|
var from = pres.getAttribute('from');
|
||||||
if ($(pres).find('>error[type="auth"]>not-authorized[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]').length) {
|
if ($(pres).find('>error[type="auth"]>not-authorized[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]').length) {
|
||||||
$(document).trigger('passwordrequired.muc', [from]);
|
console.log('on password required', from);
|
||||||
|
|
||||||
|
UI.onPasswordReqiured(function (value) {
|
||||||
|
connection.emuc.doJoin(from, value);
|
||||||
|
})
|
||||||
} else if ($(pres).find(
|
} else if ($(pres).find(
|
||||||
'>error[type="cancel"]>not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]').length) {
|
'>error[type="cancel"]>not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]').length) {
|
||||||
var toDomain = Strophe.getDomainFromJid(pres.getAttribute('to'));
|
var toDomain = Strophe.getDomainFromJid(pres.getAttribute('to'));
|
||||||
|
@ -205,13 +228,13 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
$(document).trigger('passwordrequired.main');
|
$(document).trigger('passwordrequired.main');
|
||||||
} else {
|
} else {
|
||||||
console.warn('onPresError ', pres);
|
console.warn('onPresError ', pres);
|
||||||
messageHandler.openReportDialog(null,
|
UI.messageHandler.openReportDialog(null,
|
||||||
'Oops! Something went wrong and we couldn`t connect to the conference.',
|
'Oops! Something went wrong and we couldn`t connect to the conference.',
|
||||||
pres);
|
pres);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn('onPresError ', pres);
|
console.warn('onPresError ', pres);
|
||||||
messageHandler.openReportDialog(null,
|
UI.messageHandler.openReportDialog(null,
|
||||||
'Oops! Something went wrong and we couldn`t connect to the conference.',
|
'Oops! Something went wrong and we couldn`t connect to the conference.',
|
||||||
pres);
|
pres);
|
||||||
}
|
}
|
||||||
|
@ -244,7 +267,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
var type = msg.getAttribute("type");
|
var type = msg.getAttribute("type");
|
||||||
if(type == "error")
|
if(type == "error")
|
||||||
{
|
{
|
||||||
Chat.chatAddError($(msg).find('>text').text(), txt);
|
UI.chatAddError($(msg).find('>text').text(), txt);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +276,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
{
|
{
|
||||||
var subjectText = subject.text();
|
var subjectText = subject.text();
|
||||||
if(subjectText || subjectText == "") {
|
if(subjectText || subjectText == "") {
|
||||||
Chat.chatSetSubject(subjectText);
|
UI.chatSetSubject(subjectText);
|
||||||
console.log("Subject is changed to " + subjectText);
|
console.log("Subject is changed to " + subjectText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,7 +284,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
|
|
||||||
if (txt) {
|
if (txt) {
|
||||||
console.log('chat', nick, txt);
|
console.log('chat', nick, txt);
|
||||||
Chat.updateChatConversation(from, nick, txt);
|
UI.updateChatConversation(from, nick, txt);
|
||||||
if(APIConnector.isEnabled() && APIConnector.isEventEnabled("incomingMessage"))
|
if(APIConnector.isEnabled() && APIConnector.isEventEnabled("incomingMessage"))
|
||||||
{
|
{
|
||||||
if(from != this.myroomjid)
|
if(from != this.myroomjid)
|
||||||
|
@ -271,7 +294,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
lockRoom: function (key) {
|
lockRoom: function (key, onSuccess, onError, onNotSupported) {
|
||||||
//http://xmpp.org/extensions/xep-0045.html#roomconfig
|
//http://xmpp.org/extensions/xep-0045.html#roomconfig
|
||||||
var ob = this;
|
var ob = this;
|
||||||
this.connection.sendIQ($iq({to: this.roomjid, type: 'get'}).c('query', {xmlns: 'http://jabber.org/protocol/muc#owner'}),
|
this.connection.sendIQ($iq({to: this.roomjid, type: 'get'}).c('query', {xmlns: 'http://jabber.org/protocol/muc#owner'}),
|
||||||
|
@ -285,43 +308,12 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
formsubmit.c('field', {'var': 'muc#roomconfig_whois'}).c('value').t('anyone').up().up();
|
formsubmit.c('field', {'var': 'muc#roomconfig_whois'}).c('value').t('anyone').up().up();
|
||||||
// FIXME: is muc#roomconfig_passwordprotectedroom required?
|
// FIXME: is muc#roomconfig_passwordprotectedroom required?
|
||||||
this.connection.sendIQ(formsubmit,
|
this.connection.sendIQ(formsubmit,
|
||||||
function (res) {
|
onSuccess,
|
||||||
// password is required
|
onError);
|
||||||
if (sharedKey)
|
|
||||||
{
|
|
||||||
console.log('set room password');
|
|
||||||
Toolbar.lockLockButton();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
console.log('removed room password');
|
|
||||||
Toolbar.unlockLockButton();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function (err) {
|
|
||||||
console.warn('setting password failed', err);
|
|
||||||
messageHandler.showError('Lock failed',
|
|
||||||
'Failed to lock conference.',
|
|
||||||
err);
|
|
||||||
setSharedKey('');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
console.warn('room passwords not supported');
|
onNotSupported();
|
||||||
messageHandler.showError('Warning',
|
|
||||||
'Room passwords are currently not supported.');
|
|
||||||
setSharedKey('');
|
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
}, onError);
|
||||||
function (err) {
|
|
||||||
console.warn('setting password failed', err);
|
|
||||||
messageHandler.showError('Lock failed',
|
|
||||||
'Failed to lock conference.',
|
|
||||||
err);
|
|
||||||
setSharedKey('');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
kick: function (jid) {
|
kick: function (jid) {
|
||||||
var kickIQ = $iq({to: this.roomjid, type: 'set'})
|
var kickIQ = $iq({to: this.roomjid, type: 'set'})
|
||||||
|
@ -427,6 +419,7 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
}
|
}
|
||||||
|
|
||||||
pres.up();
|
pres.up();
|
||||||
|
// console.debug(pres.toString());
|
||||||
connection.send(pres);
|
connection.send(pres);
|
||||||
},
|
},
|
||||||
addDisplayNameToPresence: function (displayName) {
|
addDisplayNameToPresence: function (displayName) {
|
||||||
|
@ -509,5 +502,24 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
return this.members[peerJid].role;
|
return this.members[peerJid].role;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
},
|
||||||
|
onParticipantLeft: function (jid) {
|
||||||
|
UI.onMucLeft(jid);
|
||||||
|
|
||||||
|
if(APIConnector.isEnabled() && APIConnector.isEventEnabled("participantLeft"))
|
||||||
|
{
|
||||||
|
APIConnector.triggerEvent("participantLeft",{jid: jid});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete jid2Ssrc[jid];
|
||||||
|
|
||||||
|
connection.jingle.terminateByJid(jid);
|
||||||
|
|
||||||
|
if (connection.emuc.getPrezi(jid)) {
|
||||||
|
$(document).trigger('presentationremoved.muc',
|
||||||
|
[jid, connection.emuc.getPrezi(jid)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Moderator.onMucLeft(jid);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
346
prezi.js
346
prezi.js
|
@ -1,346 +0,0 @@
|
||||||
var Prezi = (function (my) {
|
|
||||||
var preziPlayer = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reloads the current presentation.
|
|
||||||
*/
|
|
||||||
my.reloadPresentation = function() {
|
|
||||||
var iframe = document.getElementById(preziPlayer.options.preziId);
|
|
||||||
iframe.src = iframe.src;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows/hides a presentation.
|
|
||||||
*/
|
|
||||||
my.setPresentationVisible = function (visible) {
|
|
||||||
var prezi = $('#presentation>iframe');
|
|
||||||
if (visible) {
|
|
||||||
// Trigger the video.selected event to indicate a change in the
|
|
||||||
// large video.
|
|
||||||
$(document).trigger("video.selected", [true]);
|
|
||||||
|
|
||||||
$('#largeVideo').fadeOut(300);
|
|
||||||
prezi.fadeIn(300, function() {
|
|
||||||
prezi.css({opacity:'1'});
|
|
||||||
ToolbarToggler.dockToolbar(true);
|
|
||||||
VideoLayout.setLargeVideoVisible(false);
|
|
||||||
});
|
|
||||||
$('#activeSpeaker').css('visibility', 'hidden');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (prezi.css('opacity') == '1') {
|
|
||||||
prezi.fadeOut(300, function () {
|
|
||||||
prezi.css({opacity:'0'});
|
|
||||||
$('#reloadPresentation').css({display:'none'});
|
|
||||||
$('#largeVideo').fadeIn(300, function() {
|
|
||||||
VideoLayout.setLargeVideoVisible(true);
|
|
||||||
ToolbarToggler.dockToolbar(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns <tt>true</tt> if the presentation is visible, <tt>false</tt> -
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
my.isPresentationVisible = function () {
|
|
||||||
return ($('#presentation>iframe') != null
|
|
||||||
&& $('#presentation>iframe').css('opacity') == 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens the Prezi dialog, from which the user could choose a presentation
|
|
||||||
* to load.
|
|
||||||
*/
|
|
||||||
my.openPreziDialog = function() {
|
|
||||||
var myprezi = connection.emuc.getPrezi(connection.emuc.myroomjid);
|
|
||||||
if (myprezi) {
|
|
||||||
messageHandler.openTwoButtonDialog("Remove Prezi",
|
|
||||||
"Are you sure you would like to remove your Prezi?",
|
|
||||||
false,
|
|
||||||
"Remove",
|
|
||||||
function(e,v,m,f) {
|
|
||||||
if(v) {
|
|
||||||
connection.emuc.removePreziFromPresence();
|
|
||||||
connection.emuc.sendPresence();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (preziPlayer != null) {
|
|
||||||
messageHandler.openTwoButtonDialog("Share a Prezi",
|
|
||||||
"Another participant is already sharing a Prezi." +
|
|
||||||
"This conference allows only one Prezi at a time.",
|
|
||||||
false,
|
|
||||||
"Ok",
|
|
||||||
function(e,v,m,f) {
|
|
||||||
$.prompt.close();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var openPreziState = {
|
|
||||||
state0: {
|
|
||||||
html: '<h2>Share a Prezi</h2>' +
|
|
||||||
'<input id="preziUrl" type="text" ' +
|
|
||||||
'placeholder="e.g. ' +
|
|
||||||
'http://prezi.com/wz7vhjycl7e6/my-prezi" autofocus>',
|
|
||||||
persistent: false,
|
|
||||||
buttons: { "Share": true , "Cancel": false},
|
|
||||||
defaultButton: 1,
|
|
||||||
submit: function(e,v,m,f){
|
|
||||||
e.preventDefault();
|
|
||||||
if(v)
|
|
||||||
{
|
|
||||||
var preziUrl = document.getElementById('preziUrl');
|
|
||||||
|
|
||||||
if (preziUrl.value)
|
|
||||||
{
|
|
||||||
var urlValue
|
|
||||||
= encodeURI(Util.escapeHtml(preziUrl.value));
|
|
||||||
|
|
||||||
if (urlValue.indexOf('http://prezi.com/') != 0
|
|
||||||
&& urlValue.indexOf('https://prezi.com/') != 0)
|
|
||||||
{
|
|
||||||
$.prompt.goToState('state1');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var presIdTmp = urlValue.substring(
|
|
||||||
urlValue.indexOf("prezi.com/") + 10);
|
|
||||||
if (!isAlphanumeric(presIdTmp)
|
|
||||||
|| presIdTmp.indexOf('/') < 2) {
|
|
||||||
$.prompt.goToState('state1');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
connection.emuc
|
|
||||||
.addPreziToPresence(urlValue, 0);
|
|
||||||
connection.emuc.sendPresence();
|
|
||||||
$.prompt.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$.prompt.close();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
state1: {
|
|
||||||
html: '<h2>Share a Prezi</h2>' +
|
|
||||||
'Please provide a correct prezi link.',
|
|
||||||
persistent: false,
|
|
||||||
buttons: { "Back": true, "Cancel": false },
|
|
||||||
defaultButton: 1,
|
|
||||||
submit:function(e,v,m,f) {
|
|
||||||
e.preventDefault();
|
|
||||||
if(v==0)
|
|
||||||
$.prompt.close();
|
|
||||||
else
|
|
||||||
$.prompt.goToState('state0');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var focusPreziUrl = function(e) {
|
|
||||||
document.getElementById('preziUrl').focus();
|
|
||||||
};
|
|
||||||
messageHandler.openDialogWithStates(openPreziState, focusPreziUrl, focusPreziUrl);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A new presentation has been added.
|
|
||||||
*
|
|
||||||
* @param event the event indicating the add of a presentation
|
|
||||||
* @param jid the jid from which the presentation was added
|
|
||||||
* @param presUrl url of the presentation
|
|
||||||
* @param currentSlide the current slide to which we should move
|
|
||||||
*/
|
|
||||||
var presentationAdded = function(event, jid, presUrl, currentSlide) {
|
|
||||||
console.log("presentation added", presUrl);
|
|
||||||
|
|
||||||
var presId = getPresentationId(presUrl);
|
|
||||||
|
|
||||||
var elementId = 'participant_'
|
|
||||||
+ Strophe.getResourceFromJid(jid)
|
|
||||||
+ '_' + presId;
|
|
||||||
|
|
||||||
// We explicitly don't specify the peer jid here, because we don't want
|
|
||||||
// this video to be dealt with as a peer related one (for example we
|
|
||||||
// don't want to show a mute/kick menu for this one, etc.).
|
|
||||||
VideoLayout.addRemoteVideoContainer(null, elementId);
|
|
||||||
VideoLayout.resizeThumbnails();
|
|
||||||
|
|
||||||
var controlsEnabled = false;
|
|
||||||
if (jid === connection.emuc.myroomjid)
|
|
||||||
controlsEnabled = true;
|
|
||||||
|
|
||||||
Prezi.setPresentationVisible(true);
|
|
||||||
$('#largeVideoContainer').hover(
|
|
||||||
function (event) {
|
|
||||||
if (Prezi.isPresentationVisible()) {
|
|
||||||
var reloadButtonRight = window.innerWidth
|
|
||||||
- $('#presentation>iframe').offset().left
|
|
||||||
- $('#presentation>iframe').width();
|
|
||||||
|
|
||||||
$('#reloadPresentation').css({ right: reloadButtonRight,
|
|
||||||
display:'inline-block'});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function (event) {
|
|
||||||
if (!Prezi.isPresentationVisible())
|
|
||||||
$('#reloadPresentation').css({display:'none'});
|
|
||||||
else {
|
|
||||||
var e = event.toElement || event.relatedTarget;
|
|
||||||
|
|
||||||
if (e && e.id != 'reloadPresentation' && e.id != 'header')
|
|
||||||
$('#reloadPresentation').css({display:'none'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
preziPlayer = new PreziPlayer(
|
|
||||||
'presentation',
|
|
||||||
{preziId: presId,
|
|
||||||
width: getPresentationWidth(),
|
|
||||||
height: getPresentationHeihgt(),
|
|
||||||
controls: controlsEnabled,
|
|
||||||
debug: true
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#presentation>iframe').attr('id', preziPlayer.options.preziId);
|
|
||||||
|
|
||||||
preziPlayer.on(PreziPlayer.EVENT_STATUS, function(event) {
|
|
||||||
console.log("prezi status", event.value);
|
|
||||||
if (event.value == PreziPlayer.STATUS_CONTENT_READY) {
|
|
||||||
if (jid != connection.emuc.myroomjid)
|
|
||||||
preziPlayer.flyToStep(currentSlide);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
preziPlayer.on(PreziPlayer.EVENT_CURRENT_STEP, function(event) {
|
|
||||||
console.log("event value", event.value);
|
|
||||||
connection.emuc.addCurrentSlideToPresence(event.value);
|
|
||||||
connection.emuc.sendPresence();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#" + elementId).css( 'background-image',
|
|
||||||
'url(../images/avatarprezi.png)');
|
|
||||||
$("#" + elementId).click(
|
|
||||||
function () {
|
|
||||||
Prezi.setPresentationVisible(true);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A presentation has been removed.
|
|
||||||
*
|
|
||||||
* @param event the event indicating the remove of a presentation
|
|
||||||
* @param jid the jid for which the presentation was removed
|
|
||||||
* @param the url of the presentation
|
|
||||||
*/
|
|
||||||
var presentationRemoved = function (event, jid, presUrl) {
|
|
||||||
console.log('presentation removed', presUrl);
|
|
||||||
var presId = getPresentationId(presUrl);
|
|
||||||
Prezi.setPresentationVisible(false);
|
|
||||||
$('#participant_'
|
|
||||||
+ Strophe.getResourceFromJid(jid)
|
|
||||||
+ '_' + presId).remove();
|
|
||||||
$('#presentation>iframe').remove();
|
|
||||||
if (preziPlayer != null) {
|
|
||||||
preziPlayer.destroy();
|
|
||||||
preziPlayer = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the given string is an alphanumeric string.
|
|
||||||
* Note that some special characters are also allowed (-, _ , /, &, ?, =, ;) for the
|
|
||||||
* purpose of checking URIs.
|
|
||||||
*/
|
|
||||||
function isAlphanumeric(unsafeText) {
|
|
||||||
var regex = /^[a-z0-9-_\/&\?=;]+$/i;
|
|
||||||
return regex.test(unsafeText);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the presentation id from the given url.
|
|
||||||
*/
|
|
||||||
function getPresentationId (presUrl) {
|
|
||||||
var presIdTmp = presUrl.substring(presUrl.indexOf("prezi.com/") + 10);
|
|
||||||
return presIdTmp.substring(0, presIdTmp.indexOf('/'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the presentation width.
|
|
||||||
*/
|
|
||||||
function getPresentationWidth() {
|
|
||||||
var availableWidth = Util.getAvailableVideoWidth();
|
|
||||||
var availableHeight = getPresentationHeihgt();
|
|
||||||
|
|
||||||
var aspectRatio = 16.0 / 9.0;
|
|
||||||
if (availableHeight < availableWidth / aspectRatio) {
|
|
||||||
availableWidth = Math.floor(availableHeight * aspectRatio);
|
|
||||||
}
|
|
||||||
return availableWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the presentation height.
|
|
||||||
*/
|
|
||||||
function getPresentationHeihgt() {
|
|
||||||
var remoteVideos = $('#remoteVideos');
|
|
||||||
return window.innerHeight - remoteVideos.outerHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resizes the presentation iframe.
|
|
||||||
*/
|
|
||||||
function resize() {
|
|
||||||
if ($('#presentation>iframe')) {
|
|
||||||
$('#presentation>iframe').width(getPresentationWidth());
|
|
||||||
$('#presentation>iframe').height(getPresentationHeihgt());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Presentation has been removed.
|
|
||||||
*/
|
|
||||||
$(document).bind('presentationremoved.muc', presentationRemoved);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Presentation has been added.
|
|
||||||
*/
|
|
||||||
$(document).bind('presentationadded.muc', presentationAdded);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Indicates presentation slide change.
|
|
||||||
*/
|
|
||||||
$(document).bind('gotoslide.muc', function (event, jid, presUrl, current) {
|
|
||||||
if (preziPlayer && preziPlayer.getCurrentStep() != current) {
|
|
||||||
preziPlayer.flyToStep(current);
|
|
||||||
|
|
||||||
var animationStepsArray = preziPlayer.getAnimationCountOnSteps();
|
|
||||||
for (var i = 0; i < parseInt(animationStepsArray[current]); i++) {
|
|
||||||
preziPlayer.flyToStep(current, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On video selected event.
|
|
||||||
*/
|
|
||||||
$(document).bind('video.selected', function (event, isPresentation) {
|
|
||||||
if (!isPresentation && $('#presentation>iframe')) {
|
|
||||||
Prezi.setPresentationVisible(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(window).resize(function () {
|
|
||||||
resize();
|
|
||||||
});
|
|
||||||
|
|
||||||
return my;
|
|
||||||
}(Prezi || {}));
|
|
|
@ -45,7 +45,7 @@ var Recording = (function (my) {
|
||||||
|
|
||||||
if (!recordingToken)
|
if (!recordingToken)
|
||||||
{
|
{
|
||||||
messageHandler.openTwoButtonDialog(null,
|
UI.messageHandler.openTwoButtonDialog(null,
|
||||||
'<h2>Enter recording token</h2>' +
|
'<h2>Enter recording token</h2>' +
|
||||||
'<input id="recordingToken" type="text" placeholder="token" autofocus>',
|
'<input id="recordingToken" type="text" placeholder="token" autofocus>',
|
||||||
false,
|
false,
|
||||||
|
@ -70,7 +70,7 @@ var Recording = (function (my) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var oldState = recordingEnabled;
|
var oldState = recordingEnabled;
|
||||||
Toolbar.setRecordingButtonState(!oldState);
|
UI.setRecordingButtonState(!oldState);
|
||||||
my.setRecording(!oldState,
|
my.setRecording(!oldState,
|
||||||
recordingToken,
|
recordingToken,
|
||||||
function (state) {
|
function (state) {
|
||||||
|
@ -99,7 +99,7 @@ var Recording = (function (my) {
|
||||||
my.setRecordingToken(null);
|
my.setRecordingToken(null);
|
||||||
}
|
}
|
||||||
// Update with returned status
|
// Update with returned status
|
||||||
Toolbar.setRecordingButtonState(state);
|
UI.setRecordingButtonState(state);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,188 +0,0 @@
|
||||||
var RoomNameGenerator = function(my) {
|
|
||||||
/**
|
|
||||||
* Constructs new RoomNameGenerator object.
|
|
||||||
* @constructor constructs new RoomNameGenerator object.
|
|
||||||
*/
|
|
||||||
function RoomNameGeneratorProto()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//var nouns = [
|
|
||||||
//];
|
|
||||||
var pluralNouns = [
|
|
||||||
"Aliens", "Animals", "Antelopes", "Ants", "Apes", "Apples", "Baboons", "Bacteria", "Badgers", "Bananas", "Bats",
|
|
||||||
"Bears", "Birds", "Bonobos", "Brides", "Bugs", "Bulls", "Butterflies", "Cheetahs",
|
|
||||||
"Cherries", "Chicken", "Children", "Chimps", "Clowns", "Cows", "Creatures", "Dinosaurs", "Dogs", "Dolphins",
|
|
||||||
"Donkeys", "Dragons", "Ducks", "Dwarfs", "Eagles", "Elephants", "Elves", "FAIL", "Fathers",
|
|
||||||
"Fish", "Flowers", "Frogs", "Fruit", "Fungi", "Galaxies", "Geese", "Goats",
|
|
||||||
"Gorillas", "Hedgehogs", "Hippos", "Horses", "Hunters", "Insects", "Kids", "Knights",
|
|
||||||
"Lemons", "Lemurs", "Leopards", "LifeForms", "Lions", "Lizards", "Mice", "Monkeys", "Monsters",
|
|
||||||
"Mushrooms", "Octopodes", "Oranges", "Orangutans", "Organisms", "Pants", "Parrots", "Penguins",
|
|
||||||
"People", "Pigeons", "Pigs", "Pineapples", "Plants", "Potatoes", "Priests", "Rats", "Reptiles", "Reptilians",
|
|
||||||
"Rhinos", "Seagulls", "Sheep", "Siblings", "Snakes", "Spaghetti", "Spiders", "Squid", "Squirrels",
|
|
||||||
"Stars", "Students", "Teachers", "Tigers", "Tomatoes", "Trees", "Vampires", "Vegetables", "Viruses", "Vulcans",
|
|
||||||
"Warewolves", "Weasels", "Whales", "Witches", "Wizards", "Wolves", "Workers", "Worms", "Zebras"
|
|
||||||
];
|
|
||||||
//var places = [
|
|
||||||
//"Pub", "University", "Airport", "Library", "Mall", "Theater", "Stadium", "Office", "Show", "Gallows", "Beach",
|
|
||||||
// "Cemetery", "Hospital", "Reception", "Restaurant", "Bar", "Church", "House", "School", "Square", "Village",
|
|
||||||
// "Cinema", "Movies", "Party", "Restroom", "End", "Jail", "PostOffice", "Station", "Circus", "Gates", "Entrance",
|
|
||||||
// "Bridge"
|
|
||||||
//];
|
|
||||||
var verbs = [
|
|
||||||
"Abandon", "Adapt", "Advertise", "Answer", "Anticipate", "Appreciate",
|
|
||||||
"Approach", "Argue", "Ask", "Bite", "Blossom", "Blush", "Breathe", "Breed", "Bribe", "Burn", "Calculate",
|
|
||||||
"Clean", "Code", "Communicate", "Compute", "Confess", "Confiscate", "Conjugate", "Conjure", "Consume",
|
|
||||||
"Contemplate", "Crawl", "Dance", "Delegate", "Devour", "Develop", "Differ", "Discuss",
|
|
||||||
"Dissolve", "Drink", "Eat", "Elaborate", "Emancipate", "Estimate", "Expire", "Extinguish",
|
|
||||||
"Extract", "FAIL", "Facilitate", "Fall", "Feed", "Finish", "Floss", "Fly", "Follow", "Fragment", "Freeze",
|
|
||||||
"Gather", "Glow", "Grow", "Hex", "Hide", "Hug", "Hurry", "Improve", "Intersect", "Investigate", "Jinx",
|
|
||||||
"Joke", "Jubilate", "Kiss", "Laugh", "Manage", "Meet", "Merge", "Move", "Object", "Observe", "Offer",
|
|
||||||
"Paint", "Participate", "Party", "Perform", "Plan", "Pursue", "Pierce", "Play", "Postpone", "Pray", "Proclaim",
|
|
||||||
"Question", "Read", "Reckon", "Rejoice", "Represent", "Resize", "Rhyme", "Scream", "Search", "Select", "Share", "Shoot",
|
|
||||||
"Shout", "Signal", "Sing", "Skate", "Sleep", "Smile", "Smoke", "Solve", "Spell", "Steer", "Stink",
|
|
||||||
"Substitute", "Swim", "Taste", "Teach", "Terminate", "Think", "Type", "Unite", "Vanish", "Worship"
|
|
||||||
];
|
|
||||||
var adverbs = [
|
|
||||||
"Absently", "Accurately", "Accusingly", "Adorably", "AllTheTime", "Alone", "Always", "Amazingly", "Angrily",
|
|
||||||
"Anxiously", "Anywhere", "Appallingly", "Apparently", "Articulately", "Astonishingly", "Badly", "Barely",
|
|
||||||
"Beautifully", "Blindly", "Bravely", "Brightly", "Briskly", "Brutally", "Calmly", "Carefully", "Casually",
|
|
||||||
"Cautiously", "Cleverly", "Constantly", "Correctly", "Crazily", "Curiously", "Cynically", "Daily",
|
|
||||||
"Dangerously", "Deliberately", "Delicately", "Desperately", "Discreetly", "Eagerly", "Easily", "Euphoricly",
|
|
||||||
"Evenly", "Everywhere", "Exactly", "Expectantly", "Extensively", "FAIL", "Ferociously", "Fiercely", "Finely",
|
|
||||||
"Flatly", "Frequently", "Frighteningly", "Gently", "Gloriously", "Grimly", "Guiltily", "Happily",
|
|
||||||
"Hard", "Hastily", "Heroically", "High", "Highly", "Hourly", "Humbly", "Hysterically", "Immensely",
|
|
||||||
"Impartially", "Impolitely", "Indifferently", "Intensely", "Jealously", "Jovially", "Kindly", "Lazily",
|
|
||||||
"Lightly", "Loudly", "Lovingly", "Loyally", "Magnificently", "Malevolently", "Merrily", "Mightily", "Miserably",
|
|
||||||
"Mysteriously", "NOT", "Nervously", "Nicely", "Nowhere", "Objectively", "Obnoxiously", "Obsessively",
|
|
||||||
"Obviously", "Often", "Painfully", "Patiently", "Playfully", "Politely", "Poorly", "Precisely", "Promptly",
|
|
||||||
"Quickly", "Quietly", "Randomly", "Rapidly", "Rarely", "Recklessly", "Regularly", "Remorsefully", "Responsibly",
|
|
||||||
"Rudely", "Ruthlessly", "Sadly", "Scornfully", "Seamlessly", "Seldom", "Selfishly", "Seriously", "Shakily",
|
|
||||||
"Sharply", "Sideways", "Silently", "Sleepily", "Slightly", "Slowly", "Slyly", "Smoothly", "Softly", "Solemnly", "Steadily", "Sternly", "Strangely", "Strongly", "Stunningly", "Surely", "Tenderly", "Thoughtfully",
|
|
||||||
"Tightly", "Uneasily", "Vanishingly", "Violently", "Warmly", "Weakly", "Wearily", "Weekly", "Weirdly", "Well",
|
|
||||||
"Well", "Wickedly", "Wildly", "Wisely", "Wonderfully", "Yearly"
|
|
||||||
];
|
|
||||||
var adjectives = [
|
|
||||||
"Abominable", "Accurate", "Adorable", "All", "Alleged", "Ancient", "Angry", "Angry", "Anxious", "Appalling",
|
|
||||||
"Apparent", "Astonishing", "Attractive", "Awesome", "Baby", "Bad", "Beautiful", "Benign", "Big", "Bitter",
|
|
||||||
"Blind", "Blue", "Bold", "Brave", "Bright", "Brisk", "Calm", "Camouflaged", "Casual", "Cautious",
|
|
||||||
"Choppy", "Chosen", "Clever", "Cold", "Cool", "Crawly", "Crazy", "Creepy", "Cruel", "Curious", "Cynical",
|
|
||||||
"Dangerous", "Dark", "Delicate", "Desperate", "Difficult", "Discreet", "Disguised", "Dizzy",
|
|
||||||
"Dumb", "Eager", "Easy", "Edgy", "Electric", "Elegant", "Emancipated", "Enormous", "Euphoric", "Evil",
|
|
||||||
"FAIL", "Fast", "Ferocious", "Fierce", "Fine", "Flawed", "Flying", "Foolish", "Foxy",
|
|
||||||
"Freezing", "Funny", "Furious", "Gentle", "Glorious", "Golden", "Good", "Green", "Green", "Guilty",
|
|
||||||
"Hairy", "Happy", "Hard", "Hasty", "Hazy", "Heroic", "Hostile", "Hot", "Humble", "Humongous",
|
|
||||||
"Humorous", "Hysterical", "Idealistic", "Ignorant", "Immense", "Impartial", "Impolite", "Indifferent",
|
|
||||||
"Infuriated", "Insightful", "Intense", "Interesting", "Intimidated", "Intriguing", "Jealous", "Jolly", "Jovial",
|
|
||||||
"Jumpy", "Kind", "Laughing", "Lazy", "Liquid", "Lonely", "Longing", "Loud", "Loving", "Loyal", "Macabre", "Mad",
|
|
||||||
"Magical", "Magnificent", "Malevolent", "Medieval", "Memorable", "Mere", "Merry", "Mighty",
|
|
||||||
"Mischievous", "Miserable", "Modified", "Moody", "Most", "Mysterious", "Mystical", "Needy",
|
|
||||||
"Nervous", "Nice", "Objective", "Obnoxious", "Obsessive", "Obvious", "Opinionated", "Orange",
|
|
||||||
"Painful", "Passionate", "Perfect", "Pink", "Playful", "Poisonous", "Polite", "Poor", "Popular", "Powerful",
|
|
||||||
"Precise", "Preserved", "Pretty", "Purple", "Quick", "Quiet", "Random", "Rapid", "Rare", "Real",
|
|
||||||
"Reassuring", "Reckless", "Red", "Regular", "Remorseful", "Responsible", "Rich", "Rude", "Ruthless",
|
|
||||||
"Sad", "Scared", "Scary", "Scornful", "Screaming", "Selfish", "Serious", "Shady", "Shaky", "Sharp",
|
|
||||||
"Shiny", "Shy", "Simple", "Sleepy", "Slow", "Sly", "Small", "Smart", "Smelly", "Smiling", "Smooth",
|
|
||||||
"Smug", "Sober", "Soft", "Solemn", "Square", "Square", "Steady", "Strange", "Strong",
|
|
||||||
"Stunning", "Subjective", "Successful", "Surly", "Sweet", "Tactful", "Tense",
|
|
||||||
"Thoughtful", "Tight", "Tiny", "Tolerant", "Uneasy", "Unique", "Unseen", "Warm", "Weak",
|
|
||||||
"Weird", "WellCooked", "Wild", "Wise", "Witty", "Wonderful", "Worried", "Yellow", "Young",
|
|
||||||
"Zealous"
|
|
||||||
];
|
|
||||||
//var pronouns = [
|
|
||||||
//];
|
|
||||||
//var conjunctions = [
|
|
||||||
//"And", "Or", "For", "Above", "Before", "Against", "Between"
|
|
||||||
//];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maps a string (category name) to the array of words from that category.
|
|
||||||
*/
|
|
||||||
var CATEGORIES =
|
|
||||||
{
|
|
||||||
//"_NOUN_": nouns,
|
|
||||||
"_PLURALNOUN_": pluralNouns,
|
|
||||||
//"_PLACE_": places,
|
|
||||||
"_VERB_": verbs,
|
|
||||||
"_ADVERB_": adverbs,
|
|
||||||
"_ADJECTIVE_": adjectives
|
|
||||||
//"_PRONOUN_": pronouns,
|
|
||||||
//"_CONJUNCTION_": conjunctions,
|
|
||||||
};
|
|
||||||
|
|
||||||
var PATTERNS = [
|
|
||||||
"_ADJECTIVE__PLURALNOUN__VERB__ADVERB_"
|
|
||||||
|
|
||||||
// BeautifulFungiOrSpaghetti
|
|
||||||
//"_ADJECTIVE__PLURALNOUN__CONJUNCTION__PLURALNOUN_",
|
|
||||||
|
|
||||||
// AmazinglyScaryToy
|
|
||||||
//"_ADVERB__ADJECTIVE__NOUN_",
|
|
||||||
|
|
||||||
// NeitherTrashNorRifle
|
|
||||||
//"Neither_NOUN_Nor_NOUN_",
|
|
||||||
//"Either_NOUN_Or_NOUN_",
|
|
||||||
|
|
||||||
// EitherCopulateOrInvestigate
|
|
||||||
//"Either_VERB_Or_VERB_",
|
|
||||||
//"Neither_VERB_Nor_VERB_",
|
|
||||||
|
|
||||||
//"The_ADJECTIVE__ADJECTIVE__NOUN_",
|
|
||||||
//"The_ADVERB__ADJECTIVE__NOUN_",
|
|
||||||
//"The_ADVERB__ADJECTIVE__NOUN_s",
|
|
||||||
//"The_ADVERB__ADJECTIVE__PLURALNOUN__VERB_",
|
|
||||||
|
|
||||||
// WolvesComputeBadly
|
|
||||||
//"_PLURALNOUN__VERB__ADVERB_",
|
|
||||||
|
|
||||||
// UniteFacilitateAndMerge
|
|
||||||
//"_VERB__VERB_And_VERB_",
|
|
||||||
|
|
||||||
//NastyWitchesAtThePub
|
|
||||||
//"_ADJECTIVE__PLURALNOUN_AtThe_PLACE_",
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a random element from the array 'arr'
|
|
||||||
*/
|
|
||||||
function randomElement(arr)
|
|
||||||
{
|
|
||||||
return arr[Math.floor(Math.random() * arr.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns true if the string 's' contains one of the
|
|
||||||
* template strings.
|
|
||||||
*/
|
|
||||||
function hasTemplate(s)
|
|
||||||
{
|
|
||||||
for (var template in CATEGORIES){
|
|
||||||
if (s.indexOf(template) >= 0){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates new room name.
|
|
||||||
*/
|
|
||||||
RoomNameGeneratorProto.generateRoomWithoutSeparator = function()
|
|
||||||
{
|
|
||||||
// Note that if more than one pattern is available, the choice of 'name' won't be random (names from patterns
|
|
||||||
// with fewer options will have higher probability of being chosen that names from patterns with more options).
|
|
||||||
var name = randomElement(PATTERNS);
|
|
||||||
var word;
|
|
||||||
while (hasTemplate(name)){
|
|
||||||
for (var template in CATEGORIES){
|
|
||||||
word = randomElement(CATEGORIES[template]);
|
|
||||||
name = name.replace(template, word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
};
|
|
||||||
|
|
||||||
return RoomNameGeneratorProto;
|
|
||||||
}();
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
var SettingsMenu = (function(my) {
|
|
||||||
|
|
||||||
var email = '';
|
|
||||||
var displayName = '';
|
|
||||||
var userId;
|
|
||||||
|
|
||||||
if(supportsLocalStorage()) {
|
|
||||||
if(!window.localStorage.jitsiMeetId) {
|
|
||||||
window.localStorage.jitsiMeetId = generateUniqueId();
|
|
||||||
console.log("generated id", window.localStorage.jitsiMeetId);
|
|
||||||
}
|
|
||||||
userId = window.localStorage.jitsiMeetId || '';
|
|
||||||
email = window.localStorage.email || '';
|
|
||||||
displayName = window.localStorage.displayname || '';
|
|
||||||
} else {
|
|
||||||
console.log("local storage is not supported");
|
|
||||||
userId = generateUniqueId();
|
|
||||||
}
|
|
||||||
|
|
||||||
my.update = function() {
|
|
||||||
var newDisplayName = Util.escapeHtml($('#setDisplayName').get(0).value);
|
|
||||||
if(newDisplayName) {
|
|
||||||
displayName = newDisplayName;
|
|
||||||
connection.emuc.addDisplayNameToPresence(displayName);
|
|
||||||
window.localStorage.displayname = displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newEmail = Util.escapeHtml($('#setEmail').get(0).value);
|
|
||||||
connection.emuc.addEmailToPresence(newEmail);
|
|
||||||
email = newEmail;
|
|
||||||
window.localStorage.email = newEmail;
|
|
||||||
|
|
||||||
connection.emuc.sendPresence();
|
|
||||||
Avatar.setUserAvatar(connection.emuc.myroomjid, email);
|
|
||||||
};
|
|
||||||
|
|
||||||
my.isVisible = function() {
|
|
||||||
return $('#settingsmenu').is(':visible');
|
|
||||||
};
|
|
||||||
|
|
||||||
my.getUID = function() {
|
|
||||||
return userId;
|
|
||||||
};
|
|
||||||
|
|
||||||
my.getEmail = function() {
|
|
||||||
return email;
|
|
||||||
};
|
|
||||||
|
|
||||||
my.getDisplayName = function() {
|
|
||||||
return displayName;
|
|
||||||
};
|
|
||||||
|
|
||||||
my.setDisplayName = function(newDisplayName) {
|
|
||||||
displayName = newDisplayName;
|
|
||||||
window.localStorage.displayname = displayName;
|
|
||||||
$('#setDisplayName').get(0).value = displayName;
|
|
||||||
};
|
|
||||||
|
|
||||||
function supportsLocalStorage() {
|
|
||||||
try {
|
|
||||||
return 'localStorage' in window && window.localStorage !== null;
|
|
||||||
} catch (e) {
|
|
||||||
console.log("localstorage is not supported");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateUniqueId() {
|
|
||||||
function _p8() {
|
|
||||||
return (Math.random().toString(16)+"000000000").substr(2,8);
|
|
||||||
}
|
|
||||||
return _p8() + _p8() + _p8() + _p8();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).bind('displaynamechanged', function(event, peerJid, newDisplayName) {
|
|
||||||
if(peerJid === 'localVideoContainer' ||
|
|
||||||
peerJid === connection.emuc.myroomjid) {
|
|
||||||
SettingsMenu.setDisplayName(newDisplayName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return my;
|
|
||||||
}(SettingsMenu || {}));
|
|
48
smileys.js
48
smileys.js
|
@ -1,48 +0,0 @@
|
||||||
var smileys = {
|
|
||||||
"smiley1": ':)',
|
|
||||||
"smiley2": ':(',
|
|
||||||
"smiley3": ':D',
|
|
||||||
"smiley4": '(y)',
|
|
||||||
"smiley5": ' :P',
|
|
||||||
"smiley6": '(wave)',
|
|
||||||
"smiley7": '(blush)',
|
|
||||||
"smiley8": '(chuckle)',
|
|
||||||
"smiley9": '(shocked)',
|
|
||||||
"smiley10": ':*',
|
|
||||||
"smiley11": '(n)',
|
|
||||||
"smiley12": '(search)',
|
|
||||||
"smiley13": ' <3',
|
|
||||||
"smiley14": '(oops)',
|
|
||||||
"smiley15": '(angry)',
|
|
||||||
"smiley16": '(angel)',
|
|
||||||
"smiley17": '(sick)',
|
|
||||||
"smiley18": ';(',
|
|
||||||
"smiley19": '(bomb)',
|
|
||||||
"smiley20": '(clap)',
|
|
||||||
"smiley21": ' ;)'
|
|
||||||
};
|
|
||||||
|
|
||||||
var regexs = {
|
|
||||||
'smiley2': /(:-\(\(|:-\(|:\(\(|:\(|\(sad\))/gi,
|
|
||||||
'smiley3': /(:-\)\)|:\)\)|\(lol\)|:-D|:D)/gi,
|
|
||||||
'smiley1': /(:-\)|:\))/gi,
|
|
||||||
'smiley4': /(\(y\)|\(Y\)|\(ok\))/gi,
|
|
||||||
'smiley5': /(:-P|:P|:-p|:p)/gi,
|
|
||||||
'smiley6': /(\(wave\))/gi,
|
|
||||||
'smiley7': /(\(blush\))/gi,
|
|
||||||
'smiley8': /(\(chuckle\))/gi,
|
|
||||||
'smiley9': /(:-0|\(shocked\))/gi,
|
|
||||||
'smiley10': /(:-\*|:\*|\(kiss\))/gi,
|
|
||||||
'smiley11': /(\(n\))/gi,
|
|
||||||
'smiley12': /(\(search\))/g,
|
|
||||||
'smiley13': /(<3|<3|&lt;3|\(L\)|\(l\)|\(H\)|\(h\))/gi,
|
|
||||||
'smiley14': /(\(oops\))/gi,
|
|
||||||
'smiley15': /(\(angry\))/gi,
|
|
||||||
'smiley16': /(\(angel\))/gi,
|
|
||||||
'smiley17': /(\(sick\))/gi,
|
|
||||||
'smiley18': /(;-\(\(|;\(\(|;-\(|;\(|:'\(|:'-\(|:~-\(|:~\(|\(upset\))/gi,
|
|
||||||
'smiley19': /(\(bomb\))/gi,
|
|
||||||
'smiley20': /(\(clap\))/gi,
|
|
||||||
'smiley21': /(;-\)|;\)|;-\)\)|;\)\)|;-D|;D|\(wink\))/gi
|
|
||||||
};
|
|
||||||
|
|
10
util.js
10
util.js
|
@ -47,16 +47,6 @@ var Util = (function (my) {
|
||||||
return $('<div/>').text(unsafeText).html();
|
return $('<div/>').text(unsafeText).html();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the available video width.
|
|
||||||
*/
|
|
||||||
my.getAvailableVideoWidth = function () {
|
|
||||||
var rightPanelWidth
|
|
||||||
= PanelToggler.isVisible() ? PanelToggler.getPanelSize()[0] : 0;
|
|
||||||
|
|
||||||
return window.innerWidth - rightPanelWidth;
|
|
||||||
};
|
|
||||||
|
|
||||||
my.imageToGrayScale = function (canvas) {
|
my.imageToGrayScale = function (canvas) {
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
|
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
|
|
Loading…
Reference in New Issue