Adds functionality for authentication with external system.
This commit is contained in:
parent
cc38c2641b
commit
f4004656a3
92
app.js
92
app.js
|
@ -2,11 +2,12 @@
|
||||||
/* application specific logic */
|
/* application specific logic */
|
||||||
var connection = null;
|
var connection = null;
|
||||||
var authenticatedUser = false;
|
var authenticatedUser = false;
|
||||||
|
var authenticationWindow = null;
|
||||||
var activecall = null;
|
var activecall = null;
|
||||||
var RTC = null;
|
var RTC = null;
|
||||||
var nickname = null;
|
var nickname = null;
|
||||||
var sharedKey = '';
|
var sharedKey = '';
|
||||||
var focusJid = null;
|
var focusMucJid = null;
|
||||||
var roomUrl = null;
|
var roomUrl = null;
|
||||||
var roomName = null;
|
var roomName = null;
|
||||||
var ssrc2jid = {};
|
var ssrc2jid = {};
|
||||||
|
@ -164,6 +165,8 @@ function connect(jid, password) {
|
||||||
}
|
}
|
||||||
document.getElementById('connect').disabled = true;
|
document.getElementById('connect').disabled = true;
|
||||||
|
|
||||||
|
console.info("My Jabber ID: " + connection.jid);
|
||||||
|
|
||||||
if(password)
|
if(password)
|
||||||
authenticatedUser = true;
|
authenticatedUser = true;
|
||||||
maybeDoJoin();
|
maybeDoJoin();
|
||||||
|
@ -755,6 +758,10 @@ $(document).bind('joined.muc', function (event, jid, info) {
|
||||||
// Once we've joined the muc show the toolbar
|
// Once we've joined the muc show the toolbar
|
||||||
ToolbarToggler.showToolbar();
|
ToolbarToggler.showToolbar();
|
||||||
|
|
||||||
|
// Show authenticate button if needed
|
||||||
|
Toolbar.showAuthenticateButton(
|
||||||
|
Moderator.isExternalAuthEnabled() && !Moderator.isModerator());
|
||||||
|
|
||||||
var displayName = !config.displayJids
|
var displayName = !config.displayJids
|
||||||
? info.displayName : Strophe.getResourceFromJid(jid);
|
? info.displayName : Strophe.getResourceFromJid(jid);
|
||||||
|
|
||||||
|
@ -767,10 +774,8 @@ $(document).bind('entered.muc', function (event, jid, info, pres) {
|
||||||
console.log('entered', jid, info);
|
console.log('entered', jid, info);
|
||||||
if (info.isFocus)
|
if (info.isFocus)
|
||||||
{
|
{
|
||||||
focusJid = jid;
|
focusMucJid = jid;
|
||||||
console.info("Ignore focus: " + jid +", real JID: " + info.jid);
|
console.info("Ignore focus: " + jid +", real JID: " + info.jid);
|
||||||
// We don't want this notification for the focus.
|
|
||||||
// messageHandler.notify('Focus', 'connected', 'connected');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,6 +949,44 @@ $(document).bind('kicked.muc', function (event, jid) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(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) {
|
$(document).bind('passwordrequired.muc', function (event, jid) {
|
||||||
console.log('on password required', jid);
|
console.log('on password required', jid);
|
||||||
|
|
||||||
|
@ -996,6 +1039,44 @@ $(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;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if video identified by given src is desktop stream.
|
* Checks if video identified by given src is desktop stream.
|
||||||
* @param videoSrc eg.
|
* @param videoSrc eg.
|
||||||
|
@ -1474,6 +1555,9 @@ $(window).bind('beforeunload', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
function disposeConference(onUnload) {
|
function disposeConference(onUnload) {
|
||||||
|
|
||||||
|
Toolbar.showAuthenticateButton(false);
|
||||||
|
|
||||||
var handler = getConferenceHandler();
|
var handler = getConferenceHandler();
|
||||||
if (handler && handler.peerconnection) {
|
if (handler && handler.peerconnection) {
|
||||||
// FIXME: probably removing streams is not required and close() should
|
// FIXME: probably removing streams is not required and close() should
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
.icon-recEnable:before {
|
.icon-recEnable:before {
|
||||||
content: "\e614";
|
content: "\e614";
|
||||||
}
|
}
|
||||||
|
.icon-authenticate:before {
|
||||||
|
content: "\e1ae";
|
||||||
|
}
|
||||||
.icon-kick1:before {
|
.icon-kick1:before {
|
||||||
content: "\e60f";
|
content: "\e60f";
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,12 @@
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="toggleVideoPopover" content="Start / stop camera" onclick='toggleVideo();'>
|
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="toggleVideoPopover" content="Start / stop camera" onclick='toggleVideo();'>
|
||||||
<i id="video" class="icon-camera"></i>
|
<i id="video" class="icon-camera"></i>
|
||||||
</a>
|
</a>
|
||||||
|
<span id="authentication" style="display: none">
|
||||||
|
<div class="header_button_separator"></div>
|
||||||
|
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Authenticate" onclick='authenticateClicked();'>
|
||||||
|
<i id="authButton" class="icon-avatar"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
<span id="recording" style="display: none">
|
<span id="recording" style="display: none">
|
||||||
<div class="header_button_separator"></div>
|
<div class="header_button_separator"></div>
|
||||||
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Record" onclick='toggleRecording();'>
|
<a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Record" onclick='toggleRecording();'>
|
||||||
|
|
|
@ -80,6 +80,32 @@ var messageHandler = (function(my) {
|
||||||
myPrompt.on('impromptu:statechanged', stateChangedFunction);
|
myPrompt.on('impromptu:statechanged', stateChangedFunction);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens new popup window for given <tt>url</tt> centered over current
|
||||||
|
* window.
|
||||||
|
*
|
||||||
|
* @param url the URL to be displayed in the popup window
|
||||||
|
* @param w the width of the popup window
|
||||||
|
* @param h the height of the popup window
|
||||||
|
* @param onPopupClosed optional callback function called when popup window
|
||||||
|
* has been closed.
|
||||||
|
*/
|
||||||
|
my.openCenteredPopup = function (url, w, h, onPopupClosed) {
|
||||||
|
var l = window.screenX + (window.innerWidth / 2) - (w / 2);
|
||||||
|
var t = window.screenY + (window.innerHeight / 2) - (h / 2);
|
||||||
|
var popup = window.open(
|
||||||
|
url, '_blank',
|
||||||
|
'top=' + t + ', left=' + l + ', width=' + w + ', height=' + h + '');
|
||||||
|
if (onPopupClosed) {
|
||||||
|
var pollTimer = window.setInterval(function () {
|
||||||
|
if (popup.closed !== false) {
|
||||||
|
window.clearInterval(pollTimer);
|
||||||
|
onPopupClosed();
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a dialog prompting the user to send an error report.
|
* Shows a dialog prompting the user to send an error report.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global $, $iq, config, connection, focusJid, forceMuted, messageHandler,
|
/* global $, $iq, config, connection, focusMucJid, forceMuted, messageHandler,
|
||||||
setAudioMuted, Strophe, toggleAudio */
|
setAudioMuted, Strophe, toggleAudio */
|
||||||
/**
|
/**
|
||||||
* Moderate connection plugin.
|
* Moderate connection plugin.
|
||||||
|
@ -17,7 +17,7 @@ Strophe.addConnectionPlugin('moderate', {
|
||||||
},
|
},
|
||||||
setMute: function (jid, mute) {
|
setMute: function (jid, mute) {
|
||||||
console.info("set mute", mute);
|
console.info("set mute", mute);
|
||||||
var iqToFocus = $iq({to: focusJid, type: 'set'})
|
var iqToFocus = $iq({to: focusMucJid, type: 'set'})
|
||||||
.c('mute', {
|
.c('mute', {
|
||||||
xmlns: 'http://jitsi.org/jitmeet/audio',
|
xmlns: 'http://jitsi.org/jitmeet/audio',
|
||||||
jid: jid
|
jid: jid
|
||||||
|
@ -40,7 +40,7 @@ Strophe.addConnectionPlugin('moderate', {
|
||||||
},
|
},
|
||||||
onMute: function (iq) {
|
onMute: function (iq) {
|
||||||
var from = iq.getAttribute('from');
|
var from = iq.getAttribute('from');
|
||||||
if (from !== focusJid) {
|
if (from !== focusMucJid) {
|
||||||
console.warn("Ignored mute from non focus peer");
|
console.warn("Ignored mute from non focus peer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
71
moderator.js
71
moderator.js
|
@ -9,11 +9,21 @@ var Moderator = (function (my) {
|
||||||
var focusUserJid;
|
var focusUserJid;
|
||||||
var getNextTimeout = Util.createExpBackoffTimer(1000);
|
var getNextTimeout = Util.createExpBackoffTimer(1000);
|
||||||
var getNextErrorTimeout = Util.createExpBackoffTimer(1000);
|
var getNextErrorTimeout = Util.createExpBackoffTimer(1000);
|
||||||
|
// External authentication stuff
|
||||||
|
var externalAuthEnabled = false;
|
||||||
|
|
||||||
my.isModerator = function () {
|
my.isModerator = function () {
|
||||||
return connection.emuc.isModerator();
|
return connection.emuc.isModerator();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
my.isPeerModerator = function (peerJid) {
|
||||||
|
return connection.emuc.getMemberRole(peerJid) === 'moderator';
|
||||||
|
};
|
||||||
|
|
||||||
|
my.isExternalAuthEnabled = function () {
|
||||||
|
return externalAuthEnabled;
|
||||||
|
};
|
||||||
|
|
||||||
my.onModeratorStatusChanged = function (isModerator) {
|
my.onModeratorStatusChanged = function (isModerator) {
|
||||||
|
|
||||||
Toolbar.showSipCallButton(isModerator);
|
Toolbar.showSipCallButton(isModerator);
|
||||||
|
@ -27,25 +37,12 @@ var Moderator = (function (my) {
|
||||||
if (isModerator && config.etherpad_base) {
|
if (isModerator && config.etherpad_base) {
|
||||||
Etherpad.init();
|
Etherpad.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).trigger('local.role.moderator', [isModerator]);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
my.init = function () {
|
my.init = function () {
|
||||||
$(document).bind(
|
|
||||||
'role.changed.muc',
|
|
||||||
function (event, jid, info, pres) {
|
|
||||||
console.info(
|
|
||||||
"Role changed for " + jid + ", new role: " + info.role);
|
|
||||||
VideoLayout.showModeratorIndicator();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
$(document).bind(
|
$(document).bind(
|
||||||
'local.role.changed.muc',
|
'local.role.changed.muc',
|
||||||
function (event, jid, info, pres) {
|
function (event, jid, info, pres) {
|
||||||
console.info("My role changed, new role: " + info.role);
|
|
||||||
VideoLayout.showModeratorIndicator();
|
|
||||||
Moderator.onModeratorStatusChanged(Moderator.isModerator());
|
Moderator.onModeratorStatusChanged(Moderator.isModerator());
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -141,6 +138,19 @@ var Moderator = (function (my) {
|
||||||
return elem;
|
return elem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
my.parseConfigOptions = function (resultIq) {
|
||||||
|
|
||||||
|
Moderator.setFocusUserJid(
|
||||||
|
$(resultIq).find('conference').attr('focusjid'));
|
||||||
|
|
||||||
|
var extAuthParam
|
||||||
|
= $(resultIq).find('>conference>property[name=\'externalAuth\']');
|
||||||
|
if (extAuthParam.length) {
|
||||||
|
externalAuthEnabled = extAuthParam.attr('value') === 'true';
|
||||||
|
}
|
||||||
|
console.info("External authentication enabled: " + externalAuthEnabled);
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME: we need to show the fact that we're waiting for the focus
|
// FIXME: we need to show the fact that we're waiting for the focus
|
||||||
// to the user(or that focus is not available)
|
// to the user(or that focus is not available)
|
||||||
my.allocateConferenceFocus = function (roomName, callback) {
|
my.allocateConferenceFocus = function (roomName, callback) {
|
||||||
|
@ -155,8 +165,9 @@ var Moderator = (function (my) {
|
||||||
// Reset both timers
|
// Reset both timers
|
||||||
getNextTimeout(true);
|
getNextTimeout(true);
|
||||||
getNextErrorTimeout(true);
|
getNextErrorTimeout(true);
|
||||||
Moderator.setFocusUserJid(
|
// Setup config options
|
||||||
$(result).find('conference').attr('focusjid'));
|
Moderator.parseConfigOptions(result);
|
||||||
|
// Exec callback
|
||||||
callback();
|
callback();
|
||||||
} else {
|
} else {
|
||||||
var waitMs = getNextTimeout();
|
var waitMs = getNextTimeout();
|
||||||
|
@ -171,6 +182,12 @@ var Moderator = (function (my) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
|
// 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');
|
||||||
|
return;
|
||||||
|
}
|
||||||
var waitMs = getNextErrorTimeout();
|
var waitMs = getNextErrorTimeout();
|
||||||
console.error("Focus error, retry after " + waitMs, error);
|
console.error("Focus error, retry after " + waitMs, error);
|
||||||
// Show message
|
// Show message
|
||||||
|
@ -188,6 +205,30 @@ var Moderator = (function (my) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
my.getAuthUrl = function (urlCallback) {
|
||||||
|
var iq = $iq({to: Moderator.getFocusComponent(), type: 'get'});
|
||||||
|
iq.c('auth-url', {
|
||||||
|
xmlns: 'http://jitsi.org/protocol/focus',
|
||||||
|
room: roomName
|
||||||
|
});
|
||||||
|
connection.sendIQ(
|
||||||
|
iq,
|
||||||
|
function (result) {
|
||||||
|
var url = $(result).find('auth-url').attr('url');
|
||||||
|
if (url) {
|
||||||
|
console.info("Got auth url: " + url);
|
||||||
|
urlCallback(url);
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
"Failed to get auth url fro mthe focus", result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
console.error("Get auth url error", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return my;
|
return my;
|
||||||
}(Moderator || {}));
|
}(Moderator || {}));
|
||||||
|
|
||||||
|
|
6
muc.js
6
muc.js
|
@ -503,5 +503,11 @@ Strophe.addConnectionPlugin('emuc', {
|
||||||
},
|
},
|
||||||
isModerator: function() {
|
isModerator: function() {
|
||||||
return this.role === 'moderator';
|
return this.role === 'moderator';
|
||||||
|
},
|
||||||
|
getMemberRole: function(peerJid) {
|
||||||
|
if (this.members[peerJid]) {
|
||||||
|
return this.members[peerJid].role;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global $, $iq, config, connection, focusJid, messageHandler, Moderator,
|
/* global $, $iq, config, connection, focusMucJid, messageHandler, Moderator,
|
||||||
Toolbar, Util */
|
Toolbar, Util */
|
||||||
var Recording = (function (my) {
|
var Recording = (function (my) {
|
||||||
var recordingToken = null;
|
var recordingToken = null;
|
||||||
|
@ -13,7 +13,7 @@ var Recording = (function (my) {
|
||||||
// with the new recording state, according to the IQ.
|
// with the new recording state, according to the IQ.
|
||||||
my.setRecording = function (state, token, callback) {
|
my.setRecording = function (state, token, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var elem = $iq({to: focusJid, type: 'set'});
|
var elem = $iq({to: focusMucJid, type: 'set'});
|
||||||
elem.c('conference', {
|
elem.c('conference', {
|
||||||
xmlns: 'http://jitsi.org/protocol/colibri'
|
xmlns: 'http://jitsi.org/protocol/colibri'
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global ssrc2jid */
|
/* global focusMucJid, ssrc2jid */
|
||||||
/* jshint -W117 */
|
/* jshint -W117 */
|
||||||
/**
|
/**
|
||||||
* Calculates packet lost percent using the number of lost packets and the
|
* Calculates packet lost percent using the number of lost packets and the
|
||||||
|
@ -324,7 +324,7 @@ StatsCollector.prototype.addStatsToBeLogged = function (reports) {
|
||||||
};
|
};
|
||||||
|
|
||||||
StatsCollector.prototype.logStats = function () {
|
StatsCollector.prototype.logStats = function () {
|
||||||
if (!focusJid) {
|
if (!focusMucJid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ StatsCollector.prototype.logStats = function () {
|
||||||
content = Base64.encode(content);
|
content = Base64.encode(content);
|
||||||
|
|
||||||
// XEP-0337-ish
|
// XEP-0337-ish
|
||||||
var message = $msg({to: focusJid, type: 'normal'});
|
var message = $msg({to: focusMucJid, type: 'normal'});
|
||||||
message.c('log', { xmlns: 'urn:xmpp:eventlog',
|
message.c('log', { xmlns: 'urn:xmpp:eventlog',
|
||||||
id: 'PeerConnectionStats'});
|
id: 'PeerConnectionStats'});
|
||||||
message.c('message').t(content).up();
|
message.c('message').t(content).up();
|
||||||
|
|
13
toolbar.js
13
toolbar.js
|
@ -221,6 +221,19 @@ var Toolbar = (function (my) {
|
||||||
buttonClick("#lockIcon", "icon-security icon-security-locked");
|
buttonClick("#lockIcon", "icon-security icon-security-locked");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows or hides authentication button
|
||||||
|
* @param show <tt>true</tt> to show or <tt>false</tt> to hide
|
||||||
|
*/
|
||||||
|
my.showAuthenticateButton = function (show) {
|
||||||
|
if (show) {
|
||||||
|
$('#authentication').css({display: "inline"});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#authentication').css({display: "none"});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Shows or hides the 'recording' button.
|
// Shows or hides the 'recording' button.
|
||||||
my.showRecordingButton = function (show) {
|
my.showRecordingButton = function (show) {
|
||||||
if (!config.enableRecording) {
|
if (!config.enableRecording) {
|
||||||
|
|
|
@ -485,7 +485,8 @@ var VideoLayout = (function (my) {
|
||||||
if ($('#' + videoSpanId).length > 0) {
|
if ($('#' + videoSpanId).length > 0) {
|
||||||
// If there's been a focus change, make sure we add focus related
|
// If there's been a focus change, make sure we add focus related
|
||||||
// interface!!
|
// interface!!
|
||||||
if (Moderator.isModerator() && $('#remote_popupmenu_' + resourceJid).length <= 0) {
|
if (Moderator.isModerator() && !Moderator.isPeerModerator(peerJid)
|
||||||
|
&& $('#remote_popupmenu_' + resourceJid).length <= 0) {
|
||||||
addRemoteVideoMenu(peerJid,
|
addRemoteVideoMenu(peerJid,
|
||||||
document.getElementById(videoSpanId));
|
document.getElementById(videoSpanId));
|
||||||
}
|
}
|
||||||
|
@ -905,38 +906,42 @@ var VideoLayout = (function (my) {
|
||||||
{
|
{
|
||||||
createModeratorIndicatorElement(indicatorSpan[0]);
|
createModeratorIndicatorElement(indicatorSpan[0]);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Object.keys(connection.emuc.members).forEach(function (jid) {
|
|
||||||
var member = connection.emuc.members[jid];
|
|
||||||
if (member.role === 'moderator') {
|
|
||||||
var moderatorId
|
|
||||||
= 'participant_' + Strophe.getResourceFromJid(jid);
|
|
||||||
|
|
||||||
var moderatorContainer
|
|
||||||
= document.getElementById(moderatorId);
|
|
||||||
|
|
||||||
if (Strophe.getResourceFromJid(jid) === 'focus') {
|
|
||||||
// Skip server side focus
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!moderatorContainer) {
|
|
||||||
console.error("No moderator container for " + jid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var indicatorSpan
|
|
||||||
= $('#' + moderatorId + ' .focusindicator');
|
|
||||||
|
|
||||||
if (!indicatorSpan || indicatorSpan.length === 0) {
|
|
||||||
indicatorSpan = document.createElement('span');
|
|
||||||
indicatorSpan.className = 'focusindicator';
|
|
||||||
|
|
||||||
moderatorContainer.appendChild(indicatorSpan);
|
|
||||||
|
|
||||||
createModeratorIndicatorElement(indicatorSpan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
Object.keys(connection.emuc.members).forEach(function (jid) {
|
||||||
|
var member = connection.emuc.members[jid];
|
||||||
|
if (member.role === 'moderator') {
|
||||||
|
var moderatorId
|
||||||
|
= 'participant_' + Strophe.getResourceFromJid(jid);
|
||||||
|
|
||||||
|
var moderatorContainer
|
||||||
|
= document.getElementById(moderatorId);
|
||||||
|
|
||||||
|
if (Strophe.getResourceFromJid(jid) === 'focus') {
|
||||||
|
// Skip server side focus
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!moderatorContainer) {
|
||||||
|
console.error("No moderator container for " + jid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var menuSpan = $('#' + moderatorId + '>span.remotevideomenu');
|
||||||
|
if (menuSpan.length) {
|
||||||
|
removeRemoteVideoMenu(moderatorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
var indicatorSpan
|
||||||
|
= $('#' + moderatorId + ' .focusindicator');
|
||||||
|
|
||||||
|
if (!indicatorSpan || indicatorSpan.length === 0) {
|
||||||
|
indicatorSpan = document.createElement('span');
|
||||||
|
indicatorSpan.className = 'focusindicator';
|
||||||
|
|
||||||
|
moderatorContainer.appendChild(indicatorSpan);
|
||||||
|
|
||||||
|
createModeratorIndicatorElement(indicatorSpan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1399,6 +1404,19 @@ var VideoLayout = (function (my) {
|
||||||
popupmenuElement.appendChild(paddingSpan);
|
popupmenuElement.appendChild(paddingSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes remote video menu element from video element identified by
|
||||||
|
* given <tt>videoElementId</tt>.
|
||||||
|
*
|
||||||
|
* @param videoElementId the id of local or remote video element.
|
||||||
|
*/
|
||||||
|
function removeRemoteVideoMenu(videoElementId) {
|
||||||
|
var menuSpan = $('#' + videoElementId + '>span.remotevideomenu');
|
||||||
|
if (menuSpan.length) {
|
||||||
|
menuSpan.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On contact list item clicked.
|
* On contact list item clicked.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue