Creates UI module.
This commit is contained in:
parent
4a991f7187
commit
69b0e2ad32
4
Makefile
4
Makefile
|
@ -20,3 +20,7 @@ clean:
|
|||
|
||||
deploy:
|
||||
@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 =
|
||||
{
|
||||
displayName: VideoLayout.inputDisplayNameHandler,
|
||||
displayName: UI.inputDisplayNameHandler,
|
||||
muteAudio: toggleAudio,
|
||||
muteVideo: toggleVideo,
|
||||
toggleFilmStrip: BottomToolbar.toggleFilmStrip,
|
||||
toggleChat: BottomToolbar.toggleChat,
|
||||
toggleContactList: BottomToolbar.toggleContactList
|
||||
toggleFilmStrip: UI.toggleFilmStrip,
|
||||
toggleChat: UI.toggleChat,
|
||||
toggleContactList: UI.toggleContactList
|
||||
};
|
||||
|
||||
|
||||
|
|
632
app.js
632
app.js
|
@ -2,12 +2,9 @@
|
|||
/* application specific logic */
|
||||
var connection = null;
|
||||
var authenticatedUser = false;
|
||||
var authenticationWindow = null;
|
||||
var activecall = null;
|
||||
var nickname = null;
|
||||
var sharedKey = '';
|
||||
var focusMucJid = null;
|
||||
var roomUrl = null;
|
||||
var roomName = null;
|
||||
var ssrc2jid = {};
|
||||
var bridgeIsDown = false;
|
||||
|
@ -59,10 +56,8 @@ var getVideoPosition;
|
|||
var sessionTerminated = false;
|
||||
|
||||
function init() {
|
||||
Toolbar.setupButtonsFromConfig();
|
||||
|
||||
RTC.addStreamListener(maybeDoJoin, StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
|
||||
RTC.addStreamListener(VideoLayout.onLocalStreamCreated, StreamEventTypes.EVENT_TYPE_LOCAL_CREATED)
|
||||
RTC.start();
|
||||
|
||||
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');
|
||||
|
||||
var email = SettingsMenu.getEmail();
|
||||
var displayName = SettingsMenu.getDisplayName();
|
||||
var settings = UI.getSettings();
|
||||
var email = settings.email;
|
||||
var displayName = settings.displayName;
|
||||
if(email) {
|
||||
connection.emuc.addEmailToPresence(email);
|
||||
} else {
|
||||
connection.emuc.addUserIdToPresence(SettingsMenu.getUID());
|
||||
connection.emuc.addUserIdToPresence(settings.uid);
|
||||
}
|
||||
if(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() {
|
||||
if (!roomName) {
|
||||
generateRoomName();
|
||||
UI.generateRoomName();
|
||||
}
|
||||
|
||||
Moderator.allocateConferenceFocus(
|
||||
|
@ -244,7 +208,6 @@ function waitForRemoteVideo(selector, ssrc, stream, jid) {
|
|||
jid2Ssrc[Strophe.getResourceFromJid(jid)] = ssrc;
|
||||
} else {
|
||||
console.warn("No ssrc given for jid", jid);
|
||||
// messageHandler.showError('Warning', 'No ssrc was given for the video.');
|
||||
}
|
||||
|
||||
$(document).trigger('videoactive.jingle', [selector]);
|
||||
|
@ -328,43 +291,7 @@ function waitForPresence(data, sid) {
|
|||
|
||||
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;
|
||||
|
||||
if (container) {
|
||||
VideoLayout.addRemoteStreamElement( container,
|
||||
sid,
|
||||
data.stream,
|
||||
data.peerjid,
|
||||
thessrc);
|
||||
}
|
||||
|
||||
// an attempt to work around https://github.com/jitsi/jitmeet/issues/32
|
||||
if (isVideo &&
|
||||
data.peerjid && sess.peerjid === data.peerjid &&
|
||||
|
@ -393,19 +320,19 @@ function sendKeyframe(pc) {
|
|||
},
|
||||
function (error) {
|
||||
console.log('triggerKeyframe setLocalDescription failed', error);
|
||||
messageHandler.showError();
|
||||
UI.messageHandler.showError();
|
||||
}
|
||||
);
|
||||
},
|
||||
function (error) {
|
||||
console.log('triggerKeyframe createAnswer failed', error);
|
||||
messageHandler.showError();
|
||||
UI.messageHandler.showError();
|
||||
}
|
||||
);
|
||||
},
|
||||
function (error) {
|
||||
console.log('triggerKeyframe setRemoteDescription failed', error);
|
||||
messageHandler.showError();
|
||||
UI.messageHandler.showError();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -433,7 +360,7 @@ function muteVideo(pc, unmute) {
|
|||
},
|
||||
function (error) {
|
||||
console.log('mute SLD error');
|
||||
messageHandler.showError('Error',
|
||||
UI.messageHandler.showError('Error',
|
||||
'Oops! Something went wrong and we failed to ' +
|
||||
'mute! (SLD Failure)');
|
||||
}
|
||||
|
@ -441,13 +368,13 @@ function muteVideo(pc, unmute) {
|
|||
},
|
||||
function (error) {
|
||||
console.log(error);
|
||||
messageHandler.showError();
|
||||
UI.messageHandler.showError();
|
||||
}
|
||||
);
|
||||
},
|
||||
function (error) {
|
||||
console.log('muteVideo SRD error');
|
||||
messageHandler.showError('Error',
|
||||
UI.messageHandler.showError('Error',
|
||||
'Oops! Something went wrong and we failed to stop video!' +
|
||||
'(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) {
|
||||
// put our ssrcs into presence so other clients can identify our stream
|
||||
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) {
|
||||
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) {
|
||||
|
@ -701,7 +473,7 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
|
|||
//check if the video bridge is available
|
||||
if($(pres).find(">bridgeIsDown").length > 0 && !bridgeIsDown) {
|
||||
bridgeIsDown = true;
|
||||
messageHandler.showError("Error",
|
||||
UI.messageHandler.showError("Error",
|
||||
"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
|
||||
if($(pres).find(">bridgeIsDown").length > 0 && !bridgeIsDown) {
|
||||
bridgeIsDown = true;
|
||||
messageHandler.showError("Error",
|
||||
UI.messageHandler.showError("Error",
|
||||
"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) {
|
||||
id = email.text();
|
||||
}
|
||||
Avatar.setUserAvatar(jid, id);
|
||||
|
||||
});
|
||||
|
||||
$(document).bind('presence.status.muc', function (event, jid, info, pres) {
|
||||
|
||||
VideoLayout.setPresenceStatus(
|
||||
'participant_' + Strophe.getResourceFromJid(jid), info.status);
|
||||
UI.setUserAvatar(jid, id);
|
||||
|
||||
});
|
||||
|
||||
|
@ -782,80 +547,15 @@ $(document).bind('kicked.muc', function (event, jid) {
|
|||
sessionTerminated = true;
|
||||
disposeConference(false);
|
||||
connection.emuc.doLeave();
|
||||
messageHandler.openMessageDialog("Session Terminated",
|
||||
UI.messageHandler.openMessageDialog("Session Terminated",
|
||||
"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) {
|
||||
console.log('password is required');
|
||||
|
||||
messageHandler.openTwoButtonDialog(null,
|
||||
UI.messageHandler.openTwoButtonDialog(null,
|
||||
'<h2>Password required</h2>' +
|
||||
'<input id="passwordrequired.username" type="text" placeholder="user@domain.net" autofocus>' +
|
||||
'<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.
|
||||
* @param videoSrc eg.
|
||||
|
@ -1060,7 +715,7 @@ function setAudioMuted(mute) {
|
|||
// isMuted is the opposite of audioEnabled
|
||||
connection.emuc.addAudioInfoToPresence(mute);
|
||||
connection.emuc.sendPresence();
|
||||
VideoLayout.showLocalAudioIndicator(mute);
|
||||
UI.showLocalAudioIndicator(mute);
|
||||
|
||||
buttonClick("#mute", "icon-microphone icon-mic-disabled");
|
||||
}
|
||||
|
@ -1079,11 +734,6 @@ function isAudioMuted()
|
|||
return true;
|
||||
}
|
||||
|
||||
// Starts or stops the recording for the conference.
|
||||
function toggleRecording() {
|
||||
Recording.toggleRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the video horizontal and vertical indents,
|
||||
* so that if fits its parent.
|
||||
|
@ -1163,151 +813,17 @@ function getCameraVideoSize(videoWidth,
|
|||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
document.title = interfaceConfig.APP_NAME;
|
||||
|
||||
if(APIConnector.isEnabled())
|
||||
APIConnector.init();
|
||||
|
||||
if(config.enableWelcomePage && window.location.pathname == "/" &&
|
||||
(!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);
|
||||
UI.start();
|
||||
statistics.addConnectionStatsListener(ConnectionQuality.updateLocalStats);
|
||||
statistics.addRemoteStatsStopListener(ConnectionQuality.stopSendingStats);
|
||||
statistics.start();
|
||||
|
||||
Moderator.init();
|
||||
|
||||
// Set the defaults for prompt dialogs.
|
||||
jQuery.prompt.setDefaults({persistent: false});
|
||||
|
||||
// Set default desktop sharing method
|
||||
setDesktopSharing(config.desktopSharing);
|
||||
// Initialize Chrome extension inline installs
|
||||
|
@ -1318,62 +834,6 @@ $(document).ready(function () {
|
|||
// By default we use camera
|
||||
getVideoSize = getCameraVideoSize;
|
||||
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 () {
|
||||
|
@ -1404,9 +864,7 @@ $(window).bind('beforeunload', function () {
|
|||
});
|
||||
|
||||
function disposeConference(onUnload) {
|
||||
|
||||
Toolbar.showAuthenticateButton(false);
|
||||
|
||||
UI.onDisposeConference(onUnload);
|
||||
var handler = getConferenceHandler();
|
||||
if (handler && handler.peerconnection) {
|
||||
// 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
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -1514,19 +941,6 @@ function closePageWarning() {
|
|||
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',
|
||||
function (event, session, error)
|
||||
|
@ -1540,7 +954,7 @@ $(document).bind('fatalError.jingle',
|
|||
{
|
||||
sessionTerminated = true;
|
||||
connection.emuc.doLeave();
|
||||
messageHandler.showError( "Sorry",
|
||||
UI.messageHandler.showError( "Sorry",
|
||||
"Internal application error[setRemoteDescription]");
|
||||
}
|
||||
);
|
||||
|
@ -1550,7 +964,7 @@ function callSipButtonClicked()
|
|||
var defaultNumber
|
||||
= config.defaultSipNumber ? config.defaultSipNumber : '';
|
||||
|
||||
messageHandler.openTwoButtonDialog(null,
|
||||
UI.messageHandler.openTwoButtonDialog(null,
|
||||
'<h2>Enter SIP number</h2>' +
|
||||
'<input id="sipNumber" type="text"' +
|
||||
' 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) {
|
||||
stats = data;
|
||||
VideoLayout.updateLocalConnectionStats(100 - stats.packetLoss.total,stats);
|
||||
UI.updateLocalConnectionStats(100 - stats.packetLoss.total,stats);
|
||||
if(sendIntervalId == null)
|
||||
{
|
||||
startSendingStats();
|
||||
|
@ -97,12 +97,12 @@ var ConnectionQuality = (function () {
|
|||
ConnectionQuality.updateRemoteStats = function (jid, data) {
|
||||
if(data == null || data.packetLoss_total == null)
|
||||
{
|
||||
VideoLayout.updateConnectionStats(jid, null, null);
|
||||
UI.updateConnectionStats(jid, null, null);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
sendIntervalId = null;
|
||||
//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).
|
||||
* @type {boolean}
|
||||
|
@ -86,7 +86,7 @@ function isUpdateRequired(minVersion, extVersion)
|
|||
catch (e)
|
||||
{
|
||||
console.error("Failed to parse extension version", e);
|
||||
messageHandler.showError('Error',
|
||||
UI.messageHandler.showError('Error',
|
||||
'Error when trying to detect desktopsharing extension.');
|
||||
return true;
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ function obtainScreenFromExtension(streamCallback, failCallback) {
|
|||
function (arg) {
|
||||
console.log("Failed to install the extension", arg);
|
||||
failCallback(arg);
|
||||
messageHandler.showError('Error',
|
||||
UI.messageHandler.showError('Error',
|
||||
'Failed to install desktop sharing extension');
|
||||
}
|
||||
);
|
||||
|
@ -247,7 +247,7 @@ function streamSwitchDone() {
|
|||
//window.setTimeout(
|
||||
// function () {
|
||||
switchInProgress = false;
|
||||
Toolbar.changeDesktopSharingButtonState(isUsingScreenStream);
|
||||
UI.changeDesktopSharingButtonState(isUsingScreenStream);
|
||||
// }, 100
|
||||
//);
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ function newStreamCreated(stream) {
|
|||
|
||||
connection.jingle.localVideo = stream;
|
||||
|
||||
VideoLayout.changeLocalVideo(stream, !isUsingScreenStream);
|
||||
UI.changeLocalVideo(stream, !isUsingScreenStream);
|
||||
|
||||
var conferenceHandler = getConferenceHandler();
|
||||
if (conferenceHandler) {
|
||||
|
@ -267,7 +267,7 @@ function newStreamCreated(stream) {
|
|||
} else {
|
||||
// We are done immediately
|
||||
console.error("No conference handler");
|
||||
messageHandler.showError('Error',
|
||||
UI.messageHandler.showError('Error',
|
||||
'Unable to switch video stream.');
|
||||
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/toastr.js?v=1"></script><!-- notifications lib -->
|
||||
<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="estos_log.js?v=2"></script><!-- simple stanza logger -->
|
||||
<script src="desktopsharing.js?v=3"></script><!-- desktop sharing -->
|
||||
<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="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="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="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="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="jitsipopover.js?v=3"></script>
|
||||
<script src="message_handler.js?v=2"></script>
|
||||
<script src="api_connector.js?v=2"></script>
|
||||
<script src="settings_menu.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 -->
|
||||
<script src="keyboard_shortcut.js?v=1"></script>
|
||||
<link rel="stylesheet" href="css/font.css?v=6"/>
|
||||
<link rel="stylesheet" href="css/toastr.css?v=1">
|
||||
<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">
|
||||
<script src="libs/jquery-impromptu.js"></script>
|
||||
<script src="libs/jquery.autosize.js"></script>
|
||||
<script src="libs/prezi_player.js?v=2"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="welcome_page">
|
||||
|
@ -179,36 +158,36 @@
|
|||
<div style="position: relative;" id="header_container">
|
||||
<div id="header">
|
||||
<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>
|
||||
</a>
|
||||
<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>
|
||||
</a>
|
||||
<span id="authentication" style="display: none">
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
<span id="recording" style="display: none">
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
<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>
|
||||
</a>
|
||||
<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>
|
||||
</a>
|
||||
<div class="header_button_separator"></div>
|
||||
<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">
|
||||
<span id="unreadMessages"></span>
|
||||
</i>
|
||||
|
@ -216,38 +195,38 @@
|
|||
</span>
|
||||
<span id="prezi_button">
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
<span id="etherpadButton">
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
<div class="header_button_separator"></div>
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
<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>
|
||||
</a>
|
||||
<span id="sipCallButton" style="display: none">
|
||||
<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>
|
||||
</span>
|
||||
<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>
|
||||
</a>
|
||||
<div class="header_button_separator"></div>
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
|
@ -264,8 +243,8 @@
|
|||
<input id="connect" type="submit" value="Connect" />
|
||||
</form>
|
||||
</div>
|
||||
<div id="reloadPresentation"><a onclick='Prezi.reloadPresentation();'><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
|
||||
<div id="videospace" onmousemove="ToolbarToggler.showToolbar();">
|
||||
<div id="reloadPresentation"><a id="reloadPresentationLink"><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
|
||||
<div id="videospace">
|
||||
<div id="largeVideoContainer" class="videocontainer">
|
||||
<div id="presentation"></div>
|
||||
<div id="etherpad"></div>
|
||||
|
@ -297,7 +276,7 @@
|
|||
</div>
|
||||
<span id="bottomToolbar">
|
||||
<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">
|
||||
<span id="bottomUnreadMessages"></span>
|
||||
</i>
|
||||
|
@ -305,7 +284,7 @@
|
|||
</span>
|
||||
<div class="bottom_button_separator"></div>
|
||||
<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">
|
||||
<span id="numberOfParticipants"></span>
|
||||
</i>
|
||||
|
@ -313,7 +292,7 @@
|
|||
</span>
|
||||
<div class="bottom_button_separator"></div>
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
|
@ -332,7 +311,7 @@
|
|||
<audio id="chatNotification" src="sounds/incomingMessage.wav" preload="auto"></audio>
|
||||
<textarea id="usermsg" placeholder='Enter text...' autofocus></textarea>
|
||||
<div id="smileysarea">
|
||||
<div id="smileys" onclick="Chat.toggleSmileys()">
|
||||
<div id="smileys" id="toggle_smileys">
|
||||
<img src="images/smile.svg"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -348,7 +327,7 @@
|
|||
<div class="arrow-up"></div>
|
||||
<input type="text" id="setDisplayName" placeholder="Name">
|
||||
<input type="text" id="setEmail" placeholder="E-Mail">
|
||||
<button onclick="SettingsMenu.update()" id="updateSettings">Update</button>
|
||||
<button id="updateSettings">Update</button>
|
||||
</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>
|
||||
</div>
|
||||
|
|
|
@ -4,12 +4,12 @@ var KeyboardShortcut = (function(my) {
|
|||
67: {
|
||||
character: "C",
|
||||
id: "toggleChatPopover",
|
||||
function: BottomToolbar.toggleChat
|
||||
function: UI.toggleChat
|
||||
},
|
||||
70: {
|
||||
character: "F",
|
||||
id: "filmstripPopover",
|
||||
function: BottomToolbar.toggleFilmStrip
|
||||
function: UI.toggleFilmStrip
|
||||
},
|
||||
77: {
|
||||
character: "M",
|
||||
|
@ -45,7 +45,7 @@ var KeyboardShortcut = (function(my) {
|
|||
}
|
||||
//esc while the smileys are visible hides them
|
||||
} else if (keycode === 27 && $('#smileysContainer').is(':visible')) {
|
||||
Chat.toggleSmileys();
|
||||
UI.toggleSmileys();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -92,6 +92,12 @@ function ColibriFocus(connection, bridgejid) {
|
|||
this.endpointsInfo = null;
|
||||
}
|
||||
|
||||
function conferenceCreated(focus)
|
||||
{
|
||||
statistics.onConfereceCreated(getConferenceHandler());
|
||||
RTC.onConfereceCreated(focus);
|
||||
}
|
||||
|
||||
// creates a conferences with an initial set of peers
|
||||
ColibriFocus.prototype.makeConference = function (peers, errorCallback) {
|
||||
var self = this;
|
||||
|
@ -411,7 +417,7 @@ ColibriFocus.prototype.createdConference = function (result) {
|
|||
console.log('remote channels', this.channels);
|
||||
|
||||
// Notify that the focus has created the conference on the bridge
|
||||
$(document).trigger('conferenceCreated.jingle', [self]);
|
||||
conferenceCreated(self);
|
||||
|
||||
var bridgeSDP = new SDP(
|
||||
'v=0\r\n' +
|
||||
|
@ -561,8 +567,7 @@ ColibriFocus.prototype.createdConference = function (result) {
|
|||
}
|
||||
|
||||
// Notify we've created the conference
|
||||
$(document).trigger(
|
||||
'conferenceCreated.jingle', self);
|
||||
conferenceCreated(self);
|
||||
},
|
||||
function (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 */
|
||||
|
||||
|
||||
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', {
|
||||
connection: null,
|
||||
sessions: {},
|
||||
|
@ -110,7 +129,7 @@ Strophe.addConnectionPlugin('jingle', {
|
|||
// the callback should either
|
||||
// .sendAnswer and .accept
|
||||
// or .sendTerminate -- not necessarily synchronus
|
||||
$(document).trigger('callincoming.jingle', [sess.sid]);
|
||||
CallIncomingJingle(sess.sid);
|
||||
break;
|
||||
case 'session-accept':
|
||||
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 */
|
||||
/**
|
||||
* Moderate connection plugin.
|
||||
|
@ -32,10 +32,6 @@ Strophe.addConnectionPlugin('moderate', {
|
|||
},
|
||||
function (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) {
|
||||
|
|
41
moderator.js
41
moderator.js
|
@ -1,5 +1,5 @@
|
|||
/* 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
|
||||
* only to moderator users.
|
||||
|
@ -13,43 +13,24 @@ var Moderator = (function (my) {
|
|||
var externalAuthEnabled = false;
|
||||
|
||||
my.isModerator = function () {
|
||||
return connection.emuc.isModerator();
|
||||
return connection && connection.emuc.isModerator();
|
||||
};
|
||||
|
||||
my.isPeerModerator = function (peerJid) {
|
||||
return connection.emuc.getMemberRole(peerJid) === 'moderator';
|
||||
return connection && connection.emuc.getMemberRole(peerJid) === 'moderator';
|
||||
};
|
||||
|
||||
my.isExternalAuthEnabled = function () {
|
||||
return externalAuthEnabled;
|
||||
};
|
||||
|
||||
my.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();
|
||||
}
|
||||
my.init = function () {
|
||||
Moderator.onLocalRoleChange = function (from, member, pres) {
|
||||
UI.onModeratorStatusChanged(Moderator.isModerator());
|
||||
};
|
||||
};
|
||||
|
||||
my.init = function () {
|
||||
$(document).bind(
|
||||
'local.role.changed.muc',
|
||||
function (event, jid, info, pres) {
|
||||
Moderator.onModeratorStatusChanged(Moderator.isModerator());
|
||||
}
|
||||
);
|
||||
|
||||
$(document).bind(
|
||||
'left.muc',
|
||||
function (event, jid) {
|
||||
my.onMucLeft = function (jid) {
|
||||
console.info("Someone left is it focus ? " + jid);
|
||||
var resource = Strophe.getResourceFromJid(jid);
|
||||
if (resource === 'focus' && !sessionTerminated) {
|
||||
|
@ -61,8 +42,6 @@ var Moderator = (function (my) {
|
|||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
my.setFocusUserJid = function (focusJid) {
|
||||
if (!focusUserJid) {
|
||||
|
@ -185,13 +164,13 @@ var Moderator = (function (my) {
|
|||
// Not authorized to create new room
|
||||
if ($(error).find('>error>not-authorized').length) {
|
||||
console.warn("Unauthorized to start the conference");
|
||||
$(document).trigger('auth_required.moderator');
|
||||
UI.onAuthenticationRequired();
|
||||
return;
|
||||
}
|
||||
var waitMs = getNextErrorTimeout();
|
||||
console.error("Focus error, retry after " + waitMs, error);
|
||||
// Show message
|
||||
messageHandler.notify(
|
||||
UI.messageHandler.notify(
|
||||
'Conference focus', 'disconnected',
|
||||
Moderator.getFocusComponent() +
|
||||
' not available - retry in ' + (waitMs / 1000) + ' sec');
|
||||
|
|
|
@ -32,7 +32,7 @@ var DataChannels =
|
|||
// selections so that it can do adaptive simulcast,
|
||||
// we want the notification to trigger even if userJid is undefined,
|
||||
// or null.
|
||||
var userJid = VideoLayout.getLargeVideoState().userJid;
|
||||
var userJid = UI.getLargeVideoState().userJid;
|
||||
// we want the notification to trigger even if userJid is undefined,
|
||||
// or null.
|
||||
onSelectedEndpointChanged(userJid);
|
||||
|
|
|
@ -245,7 +245,7 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
|
|||
});
|
||||
} else {
|
||||
|
||||
RTCUtils.getUserMedia(constraints,
|
||||
this.getUserMedia(constraints,
|
||||
function (stream) {
|
||||
console.log('onUserMediaSuccess');
|
||||
success_callback(stream);
|
||||
|
@ -296,7 +296,7 @@ RTCUtils.prototype.obtainAudioAndVideoPermissions = function() {
|
|||
media: error.media || 'video',
|
||||
name : error.name
|
||||
});
|
||||
messageHandler.showError("Error",
|
||||
UI.messageHandler.showError("Error",
|
||||
"Failed to obtain permissions to use the local microphone" +
|
||||
"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.
|
||||
*/
|
||||
|
@ -10,7 +12,7 @@ var AudioLevels = (function(my) {
|
|||
* Updates the audio level canvas for the given peerJid. If the canvas
|
||||
* didn't exist we create it.
|
||||
*/
|
||||
my.updateAudioLevelCanvas = function (peerJid) {
|
||||
my.updateAudioLevelCanvas = function (peerJid, VideoLayout) {
|
||||
var resourceJid = null;
|
||||
var videoSpanId = null;
|
||||
if (!peerJid)
|
||||
|
@ -66,7 +68,7 @@ var AudioLevels = (function(my) {
|
|||
* which we draw the audio level
|
||||
* @param audioLevel the newAudio level to render
|
||||
*/
|
||||
my.updateAudioLevel = function (resourceJid, audioLevel) {
|
||||
my.updateAudioLevel = function (resourceJid, audioLevel, largeVideoResourceJid) {
|
||||
drawAudioLevelCanvas(resourceJid, audioLevel);
|
||||
|
||||
var videoSpanId = getVideoSpanId(resourceJid);
|
||||
|
@ -91,7 +93,7 @@ var AudioLevels = (function(my) {
|
|||
resourceJid = Strophe.getResourceFromJid(connection.emuc.myroomjid);
|
||||
}
|
||||
|
||||
if(resourceJid === VideoLayout.getLargeVideoState().userResourceJid) {
|
||||
if(resourceJid === largeVideoResourceJid) {
|
||||
AudioLevels.updateActiveSpeakerAudioLevel(audioLevel);
|
||||
}
|
||||
};
|
||||
|
@ -258,3 +260,5 @@ var AudioLevels = (function(my) {
|
|||
return my;
|
||||
|
||||
})(AudioLevels || {});
|
||||
|
||||
module.exports = AudioLevels;
|
|
@ -107,3 +107,5 @@ var CanvasUtil = (function(my) {
|
|||
|
||||
return my;
|
||||
})(CanvasUtil || {});
|
||||
|
||||
module.exports = CanvasUtil;
|
|
@ -1,15 +1,50 @@
|
|||
var Avatar = (function(my) {
|
||||
var users = {};
|
||||
var activeSpeakerJid;
|
||||
var Settings = require("../side_pannels/settings/Settings");
|
||||
|
||||
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
|
||||
* and thumbnail
|
||||
* @param jid jid of the user
|
||||
* @param id email or userID to be used as a hash
|
||||
*/
|
||||
my.setUserAvatar = function(jid, id) {
|
||||
if(id) {
|
||||
if(users[jid] === id) {
|
||||
setUserAvatar: function (jid, id) {
|
||||
if (id) {
|
||||
if (users[jid] === id) {
|
||||
return;
|
||||
}
|
||||
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
|
||||
// local video container
|
||||
if(jid === connection.emuc.myroomjid) {
|
||||
if (jid === connection.emuc.myroomjid) {
|
||||
$('#avatar').get(0).src = thumbUrl;
|
||||
thumbnail = $('#localVideoContainer');
|
||||
}
|
||||
|
||||
// set the avatar in the contact list
|
||||
var contact = $('#' + resourceJid + '>img');
|
||||
if(contact && contact.length > 0) {
|
||||
if (contact && contact.length > 0) {
|
||||
contact.get(0).src = contactListUrl;
|
||||
}
|
||||
|
||||
// set the avatar in the thumbnail
|
||||
if(avatar && avatar.length > 0) {
|
||||
if (avatar && avatar.length > 0) {
|
||||
avatar[0].src = thumbUrl;
|
||||
} else {
|
||||
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
|
||||
// avatar
|
||||
if(jid === activeSpeakerJid) {
|
||||
Avatar.updateActiveSpeakerAvatarSrc(jid);
|
||||
if (jid === activeSpeakerJid) {
|
||||
this.updateActiveSpeakerAvatarSrc(jid);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
* video because there is no dominant speaker and no focused speaker
|
||||
*/
|
||||
my.showUserAvatar = function(jid, show) {
|
||||
if(users[jid]) {
|
||||
showUserAvatar: function (jid, show) {
|
||||
if (users[jid]) {
|
||||
var resourceJid = Strophe.getResourceFromJid(jid);
|
||||
var video = $('#participant_' + resourceJid + '>video');
|
||||
var avatar = $('#avatar_' + resourceJid);
|
||||
|
||||
if(jid === connection.emuc.myroomjid) {
|
||||
if (jid === connection.emuc.myroomjid) {
|
||||
video = $('#localVideoWrapper>video');
|
||||
}
|
||||
if(show === undefined || show === null) {
|
||||
if (show === undefined || show === null) {
|
||||
show = isUserMuted(jid);
|
||||
}
|
||||
|
||||
//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
|
||||
//currently shown
|
||||
if (activeSpeakerJid === jid && VideoLayout.isLargeVideoOnTop()) {
|
||||
if (activeSpeakerJid === jid && require("../videolayout/VideoLayout").isLargeVideoOnTop()) {
|
||||
setVisibility($("#largeVideo"), !show);
|
||||
setVisibility($('#activeSpeaker'), show);
|
||||
setVisibility(avatar, false);
|
||||
|
@ -87,62 +122,33 @@ var Avatar = (function(my) {
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the src of the active speaker avatar
|
||||
* @param jid of the current active speaker
|
||||
*/
|
||||
my.updateActiveSpeakerAvatarSrc = function(jid) {
|
||||
if(!jid) {
|
||||
updateActiveSpeakerAvatarSrc: function (jid) {
|
||||
if (!jid) {
|
||||
jid = connection.emuc.findJidFromResource(
|
||||
VideoLayout.getLargeVideoState().userResourceJid);
|
||||
require("../videolayout/VideoLayout").getLargeVideoState().userResourceJid);
|
||||
}
|
||||
var avatar = $("#activeSpeakerAvatar")[0];
|
||||
var url = getGravatarUrl(users[jid],
|
||||
interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE);
|
||||
if(jid === activeSpeakerJid && avatar.src === url) {
|
||||
if (jid === activeSpeakerJid && avatar.src === url) {
|
||||
return;
|
||||
}
|
||||
activeSpeakerJid = jid;
|
||||
var isMuted = isUserMuted(jid);
|
||||
if(jid && isMuted !== null) {
|
||||
if (jid && isMuted !== null) {
|
||||
avatar.src = url;
|
||||
setVisibility($("#largeVideo"), !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) {
|
||||
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 || {}));
|
||||
module.exports = 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..
|
||||
*/
|
||||
|
@ -215,8 +222,9 @@ var PanelToggler = (function(my) {
|
|||
'#settingsmenu',
|
||||
null,
|
||||
function() {
|
||||
$('#setDisplayName').get(0).value = SettingsMenu.getDisplayName();
|
||||
$('#setEmail').get(0).value = SettingsMenu.getEmail();
|
||||
var settings = Settings.getSettings();
|
||||
$('#setDisplayName').get(0).value = settings.displayName;
|
||||
$('#setEmail').get(0).value = settings.email;
|
||||
},
|
||||
null);
|
||||
};
|
||||
|
@ -243,3 +251,5 @@ var PanelToggler = (function(my) {
|
|||
return my;
|
||||
|
||||
}(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"
|
||||
*/
|
||||
|
@ -44,6 +45,7 @@ function smilify(body)
|
|||
return body;
|
||||
}
|
||||
|
||||
var regexs = Smileys["regexs"];
|
||||
for(var smiley in regexs) {
|
||||
if(regexs.hasOwnProperty(smiley)) {
|
||||
body = body.replace(regexs[smiley],
|
||||
|
@ -53,3 +55,8 @@ function smilify(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
|
||||
* the glow
|
||||
* @param delta indicates whether a new user has joined (1) or someone has
|
||||
* left(-1)
|
||||
*/
|
||||
function updateNumberOfParticipants(delta) {
|
||||
function updateNumberOfParticipants(delta) {
|
||||
//when the user is alone we don't show the number of participants
|
||||
if(numberOfContacts === 0) {
|
||||
$("#numberOfParticipants").text('');
|
||||
|
@ -129,38 +18,38 @@ var ContactList = (function (my) {
|
|||
numberOfContacts += delta;
|
||||
$("#numberOfParticipants").text(numberOfContacts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Creates the avatar element.
|
||||
*
|
||||
* @return the newly created avatar element
|
||||
*/
|
||||
function createAvatar(id) {
|
||||
function createAvatar(id) {
|
||||
var avatar = document.createElement('img');
|
||||
avatar.className = "icon-avatar avatar";
|
||||
avatar.src = "https://www.gravatar.com/avatar/" + id + "?d=wavatar&size=30";
|
||||
|
||||
return avatar;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Creates the display name paragraph.
|
||||
*
|
||||
* @param displayName the display name to set
|
||||
*/
|
||||
function createDisplayNameParagraph(displayName) {
|
||||
function createDisplayNameParagraph(displayName) {
|
||||
var p = document.createElement('p');
|
||||
p.innerText = displayName;
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Indicates that the display name has changed.
|
||||
*/
|
||||
$(document).bind( 'displaynamechanged',
|
||||
$(document).bind( 'displaynamechanged',
|
||||
function (event, peerJid, displayName) {
|
||||
if (peerJid === 'localVideoContainer')
|
||||
peerJid = connection.emuc.myroomjid;
|
||||
|
@ -173,14 +62,127 @@ var ContactList = (function (my) {
|
|||
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 + '"]');
|
||||
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');
|
||||
} else {
|
||||
contact.removeClass('clickable');
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return my;
|
||||
}(ContactList || {}));
|
||||
module.exports = 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) {
|
||||
my.init = function () {
|
||||
for(var k in buttonHandlers)
|
||||
$("#" + k).click(buttonHandlers[k]);
|
||||
};
|
||||
|
||||
my.toggleChat = function() {
|
||||
PanelToggler.toggleChat();
|
||||
};
|
||||
|
@ -20,3 +39,5 @@ var BottomToolbar = (function (my) {
|
|||
|
||||
return my;
|
||||
}(BottomToolbar || {}));
|
||||
|
||||
module.exports = BottomToolbar;
|
|
@ -1,7 +1,205 @@
|
|||
/* global $, buttonClick, config, lockRoom, messageHandler, Moderator, roomUrl,
|
||||
/* global $, buttonClick, config, lockRoom, Moderator,
|
||||
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) {
|
||||
|
||||
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.
|
||||
*/
|
||||
|
@ -41,7 +239,7 @@ var Toolbar = (function (my) {
|
|||
"Remove",
|
||||
function (e, v) {
|
||||
if (v) {
|
||||
setSharedKey('');
|
||||
Toolbar.setSharedKey('');
|
||||
lockRoom(false);
|
||||
}
|
||||
});
|
||||
|
@ -57,7 +255,7 @@ var Toolbar = (function (my) {
|
|||
var lockKey = document.getElementById('lockKey');
|
||||
|
||||
if (lockKey.value) {
|
||||
setSharedKey(Util.escapeHtml(lockKey.value));
|
||||
Toolbar.setSharedKey(Util.escapeHtml(lockKey.value));
|
||||
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.
|
||||
*/
|
||||
|
@ -291,3 +448,5 @@ var Toolbar = (function (my) {
|
|||
|
||||
return my;
|
||||
}(Toolbar || {}));
|
||||
|
||||
module.exports = Toolbar;
|
|
@ -1,45 +1,12 @@
|
|||
/* global $, interfaceConfig, Moderator, showDesktopSharingButton */
|
||||
var ToolbarToggler = (function (my) {
|
||||
var toolbarTimeoutObject,
|
||||
|
||||
var toolbarTimeoutObject,
|
||||
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.
|
||||
*/
|
||||
var hideToolbar = function () {
|
||||
function hideToolbar() {
|
||||
var header = $("#header"),
|
||||
bottomToolbar = $("#bottomToolbar");
|
||||
var isToolbarHover = false;
|
||||
|
@ -67,7 +34,41 @@ var ToolbarToggler = (function (my) {
|
|||
else {
|
||||
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
|
||||
*/
|
||||
my.dockToolbar = function (isDock) {
|
||||
dockToolbar: function (isDock) {
|
||||
if (isDock) {
|
||||
// First make sure the toolbar is shown.
|
||||
if (!$('#header').is(':visible')) {
|
||||
ToolbarToggler.showToolbar();
|
||||
this.showToolbar();
|
||||
}
|
||||
|
||||
// Then clear the time out, to dock the toolbar.
|
||||
|
@ -90,14 +91,14 @@ var ToolbarToggler = (function (my) {
|
|||
}
|
||||
else {
|
||||
if (!$('#header').is(':visible')) {
|
||||
ToolbarToggler.showToolbar();
|
||||
this.showToolbar();
|
||||
}
|
||||
else {
|
||||
toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return my;
|
||||
}(ToolbarToggler || {}));
|
||||
module.exports = ToolbarToggler;
|
|
@ -119,3 +119,5 @@ var JitsiPopover = (function () {
|
|||
|
||||
|
||||
})();
|
||||
|
||||
module.exports = JitsiPopover;
|
|
@ -149,4 +149,6 @@ var messageHandler = (function(my) {
|
|||
return my;
|
||||
}(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)
|
||||
{
|
||||
if(stream.getAudioTracks().length === 0)
|
||||
if(stream.getOriginalStream().getAudioTracks().length === 0)
|
||||
return;
|
||||
|
||||
localStats = new LocalStats(stream, 100, this,
|
||||
localStats = new LocalStats(stream.getOriginalStream(), 100, statistics,
|
||||
eventEmitter);
|
||||
localStats.start();
|
||||
}
|
||||
|
|
112
muc.js
112
muc.js
|
@ -49,6 +49,7 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
onPresence: function (pres) {
|
||||
var from = pres.getAttribute('from');
|
||||
var type = pres.getAttribute('type');
|
||||
console.debug("Presence " + from + " - " + type);
|
||||
if (type != null) {
|
||||
return true;
|
||||
}
|
||||
|
@ -56,7 +57,9 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
// Parse etherpad tag.
|
||||
var etherpad = $(pres).find('>etherpad');
|
||||
if (etherpad.length) {
|
||||
$(document).trigger('etherpadadded.muc', [from, etherpad.text()]);
|
||||
if (config.etherpad_base && !Moderator.isModerator()) {
|
||||
UI.initEtherpad(etherpad.text());
|
||||
}
|
||||
}
|
||||
|
||||
// Parse prezi tag.
|
||||
|
@ -138,24 +141,40 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
if (member.affiliation == 'owner') this.isOwner = true;
|
||||
if (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) {
|
||||
this.joined = true;
|
||||
$(document).trigger('joined.muc', [from, member]);
|
||||
UI.onMucJoined(from, member);
|
||||
this.list_members.push(from);
|
||||
}
|
||||
} else if (this.members[from] === undefined) {
|
||||
// new participant
|
||||
this.members[from] = member;
|
||||
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 {
|
||||
// Presence update for existing participant
|
||||
// Watch role change:
|
||||
if (this.members[from].role != member.role) {
|
||||
this.members[from].role = member.role
|
||||
$(document).trigger('role.changed.muc', [from, member, pres]);
|
||||
this.members[from].role = member.role;
|
||||
UI.onMucRoleChanged(member.role, member.displayName);
|
||||
}
|
||||
}
|
||||
// Always trigger presence to update bindings
|
||||
|
@ -164,7 +183,7 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
|
||||
// Trigger status message update
|
||||
if (member.status) {
|
||||
$(document).trigger('presence.status.muc', [from, member, pres]);
|
||||
UI.onMucPresenceStatus(from, member);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -175,7 +194,7 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
if (!$(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="110"]').length) {
|
||||
delete this.members[from];
|
||||
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
|
||||
// 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];
|
||||
delete this.members[i];
|
||||
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) {
|
||||
|
@ -195,7 +214,11 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
onPresenceError: function (pres) {
|
||||
var from = pres.getAttribute('from');
|
||||
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(
|
||||
'>error[type="cancel"]>not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]').length) {
|
||||
var toDomain = Strophe.getDomainFromJid(pres.getAttribute('to'));
|
||||
|
@ -205,13 +228,13 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
$(document).trigger('passwordrequired.main');
|
||||
} else {
|
||||
console.warn('onPresError ', pres);
|
||||
messageHandler.openReportDialog(null,
|
||||
UI.messageHandler.openReportDialog(null,
|
||||
'Oops! Something went wrong and we couldn`t connect to the conference.',
|
||||
pres);
|
||||
}
|
||||
} else {
|
||||
console.warn('onPresError ', pres);
|
||||
messageHandler.openReportDialog(null,
|
||||
UI.messageHandler.openReportDialog(null,
|
||||
'Oops! Something went wrong and we couldn`t connect to the conference.',
|
||||
pres);
|
||||
}
|
||||
|
@ -244,7 +267,7 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
var type = msg.getAttribute("type");
|
||||
if(type == "error")
|
||||
{
|
||||
Chat.chatAddError($(msg).find('>text').text(), txt);
|
||||
UI.chatAddError($(msg).find('>text').text(), txt);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -253,7 +276,7 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
{
|
||||
var subjectText = subject.text();
|
||||
if(subjectText || subjectText == "") {
|
||||
Chat.chatSetSubject(subjectText);
|
||||
UI.chatSetSubject(subjectText);
|
||||
console.log("Subject is changed to " + subjectText);
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +284,7 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
|
||||
if (txt) {
|
||||
console.log('chat', nick, txt);
|
||||
Chat.updateChatConversation(from, nick, txt);
|
||||
UI.updateChatConversation(from, nick, txt);
|
||||
if(APIConnector.isEnabled() && APIConnector.isEventEnabled("incomingMessage"))
|
||||
{
|
||||
if(from != this.myroomjid)
|
||||
|
@ -271,7 +294,7 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
}
|
||||
return true;
|
||||
},
|
||||
lockRoom: function (key) {
|
||||
lockRoom: function (key, onSuccess, onError, onNotSupported) {
|
||||
//http://xmpp.org/extensions/xep-0045.html#roomconfig
|
||||
var ob = this;
|
||||
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();
|
||||
// FIXME: is muc#roomconfig_passwordprotectedroom required?
|
||||
this.connection.sendIQ(formsubmit,
|
||||
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);
|
||||
setSharedKey('');
|
||||
}
|
||||
);
|
||||
onSuccess,
|
||||
onError);
|
||||
} else {
|
||||
console.warn('room passwords not supported');
|
||||
messageHandler.showError('Warning',
|
||||
'Room passwords are currently not supported.');
|
||||
setSharedKey('');
|
||||
|
||||
onNotSupported();
|
||||
}
|
||||
},
|
||||
function (err) {
|
||||
console.warn('setting password failed', err);
|
||||
messageHandler.showError('Lock failed',
|
||||
'Failed to lock conference.',
|
||||
err);
|
||||
setSharedKey('');
|
||||
}
|
||||
);
|
||||
}, onError);
|
||||
},
|
||||
kick: function (jid) {
|
||||
var kickIQ = $iq({to: this.roomjid, type: 'set'})
|
||||
|
@ -427,6 +419,7 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
}
|
||||
|
||||
pres.up();
|
||||
// console.debug(pres.toString());
|
||||
connection.send(pres);
|
||||
},
|
||||
addDisplayNameToPresence: function (displayName) {
|
||||
|
@ -509,5 +502,24 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
return this.members[peerJid].role;
|
||||
}
|
||||
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)
|
||||
{
|
||||
messageHandler.openTwoButtonDialog(null,
|
||||
UI.messageHandler.openTwoButtonDialog(null,
|
||||
'<h2>Enter recording token</h2>' +
|
||||
'<input id="recordingToken" type="text" placeholder="token" autofocus>',
|
||||
false,
|
||||
|
@ -70,7 +70,7 @@ var Recording = (function (my) {
|
|||
}
|
||||
|
||||
var oldState = recordingEnabled;
|
||||
Toolbar.setRecordingButtonState(!oldState);
|
||||
UI.setRecordingButtonState(!oldState);
|
||||
my.setRecording(!oldState,
|
||||
recordingToken,
|
||||
function (state) {
|
||||
|
@ -99,7 +99,7 @@ var Recording = (function (my) {
|
|||
my.setRecordingToken(null);
|
||||
}
|
||||
// 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();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the available video width.
|
||||
*/
|
||||
my.getAvailableVideoWidth = function () {
|
||||
var rightPanelWidth
|
||||
= PanelToggler.isVisible() ? PanelToggler.getPanelSize()[0] : 0;
|
||||
|
||||
return window.innerWidth - rightPanelWidth;
|
||||
};
|
||||
|
||||
my.imageToGrayScale = function (canvas) {
|
||||
var context = canvas.getContext('2d');
|
||||
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||
|
|
Loading…
Reference in New Issue