Adds mute and kick functoinality avaialable for the focus of the conference.
This commit is contained in:
parent
ca1fc93b2d
commit
56424df0a0
176
app.js
176
app.js
|
@ -15,6 +15,7 @@ var ssrc2jid = {};
|
|||
*/
|
||||
var ssrc2videoType = {};
|
||||
var videoSrcToSsrc = {};
|
||||
var mutedAudios = {};
|
||||
|
||||
var localVideoSrc = null;
|
||||
var flipXLocalVideo = true;
|
||||
|
@ -35,6 +36,8 @@ var getVideoPosition;
|
|||
|
||||
/* window.onbeforeunload = closePageWarning; */
|
||||
|
||||
var preMuted = false;
|
||||
|
||||
function init() {
|
||||
RTC = setupRTC();
|
||||
if (RTC === null) {
|
||||
|
@ -179,6 +182,10 @@ function change_local_audio(stream) {
|
|||
RTC.attachMediaStream($('#localAudio'), stream);
|
||||
document.getElementById('localAudio').autoplay = true;
|
||||
document.getElementById('localAudio').volume = 0;
|
||||
if (preMuted) {
|
||||
toggleAudio();
|
||||
preMuted = false;
|
||||
}
|
||||
}
|
||||
|
||||
function change_local_video(stream, flipX) {
|
||||
|
@ -485,8 +492,13 @@ $(document).bind('callactive.jingle', function (event, videoelem, sid) {
|
|||
}
|
||||
});
|
||||
|
||||
$(document).bind('callterminated.jingle', function (event, sid, reason) {
|
||||
// FIXME
|
||||
$(document).bind('callterminated.jingle', function (event, sid, jid, reason) {
|
||||
// Leave the room if my call has been remotely terminated.
|
||||
if (connection.emuc.joined && focus == null && reason === 'kick') {
|
||||
connection.emuc.doLeave();
|
||||
openMessageDialog( "Session Terminated",
|
||||
"Ouch! You have been kicked out of the meet!");
|
||||
}
|
||||
});
|
||||
|
||||
$(document).bind('setLocalDescription.jingle', function (event, sid) {
|
||||
|
@ -579,15 +591,25 @@ $(document).bind('entered.muc', function (event, jid, info, pres) {
|
|||
});
|
||||
|
||||
$(document).bind('left.muc', function (event, jid) {
|
||||
console.log('left', jid);
|
||||
console.log('left.muc', jid);
|
||||
// Need to call this with a slight delay, otherwise the element couldn't be
|
||||
// found for some reason.
|
||||
window.setTimeout(function () {
|
||||
var container = document.getElementById(
|
||||
'participant_' + Strophe.getResourceFromJid(jid));
|
||||
if (container) {
|
||||
// hide here, wait for video to close before removing
|
||||
$(container).hide();
|
||||
resizeThumbnails();
|
||||
}
|
||||
}, 10);
|
||||
|
||||
connection.jingle.terminateByJid(jid);
|
||||
var container = document.getElementById('participant_' + Strophe.getResourceFromJid(jid));
|
||||
if (container) {
|
||||
// hide here, wait for video to close before removing
|
||||
$(container).hide();
|
||||
resizeThumbnails();
|
||||
}
|
||||
if (focus === null && connection.emuc.myroomjid === connection.emuc.list_members[0]) {
|
||||
|
||||
if (focus == null
|
||||
&& jid !== connection.emuc.myroomjid
|
||||
&& connection.emuc.myroomjid === connection.emuc.list_members[0]
|
||||
&& connection.emuc.list_members.length > 1) {
|
||||
console.log('welcome to our new focus... myself');
|
||||
focus = new ColibriFocus(connection, config.hosts.bridge);
|
||||
if (Object.keys(connection.emuc.members).length > 0) {
|
||||
|
@ -603,7 +625,8 @@ $(document).bind('left.muc', function (event, jid) {
|
|||
focus = new ColibriFocus(connection, config.hosts.bridge);
|
||||
}
|
||||
if (connection.emuc.getPrezi(jid)) {
|
||||
$(document).trigger('presentationremoved.muc', [jid, connection.emuc.getPrezi(jid)]);
|
||||
$(document).trigger('presentationremoved.muc',
|
||||
[jid, connection.emuc.getPrezi(jid)]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -686,6 +709,11 @@ $(document).bind('audiomuted.muc', function (event, jid, isMuted) {
|
|||
videoSpanId = 'participant_' + Strophe.getResourceFromJid(jid);
|
||||
}
|
||||
|
||||
if (focus) {
|
||||
mutedAudios[jid] = isMuted;
|
||||
updateRemoteVideoMenu(jid, isMuted);
|
||||
}
|
||||
|
||||
if (videoSpanId)
|
||||
showAudioIndicator(videoSpanId, isMuted);
|
||||
});
|
||||
|
@ -700,7 +728,7 @@ $(document).bind('videomuted.muc', function (event, jid, isMuted) {
|
|||
}
|
||||
|
||||
if (videoSpanId)
|
||||
showAudioIndicator(videoSpanId, isMuted);
|
||||
showVideoIndicator(videoSpanId, isMuted);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -821,8 +849,11 @@ function toggleVideo() {
|
|||
* Mutes / unmutes audio for the local participant.
|
||||
*/
|
||||
function toggleAudio() {
|
||||
if (!(connection && connection.jingle.localAudio))
|
||||
if (!(connection && connection.jingle.localAudio)) {
|
||||
preMuted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var localAudio = connection.jingle.localAudio;
|
||||
for (var idx = 0; idx < localAudio.getAudioTracks().length; idx++) {
|
||||
var audioEnabled = localAudio.getAudioTracks()[idx].enabled;
|
||||
|
@ -831,6 +862,8 @@ function toggleAudio() {
|
|||
connection.emuc.addAudioInfoToPresence(audioEnabled); //isMuted is the opposite of audioEnabled
|
||||
connection.emuc.sendPresence();
|
||||
}
|
||||
|
||||
buttonClick("#mute", "icon-microphone icon-mic-disabled");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1167,6 +1200,22 @@ function buttonClick(id, classname) {
|
|||
$(id).toggleClass(classname); // add the class to the clicked element
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a message to the user.
|
||||
*
|
||||
* @param titleString the title of the message
|
||||
* @param messageString the text of the message
|
||||
*/
|
||||
function openMessageDialog(titleString, messageString) {
|
||||
console.log("OPEN MESSAGE DIALOG");
|
||||
$.prompt(messageString,
|
||||
{
|
||||
title: titleString,
|
||||
persistent: false
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the lock room dialog.
|
||||
*/
|
||||
|
@ -1448,7 +1497,7 @@ function ensurePeerContainerExists(peerJid) {
|
|||
return;
|
||||
}
|
||||
|
||||
var container = addRemoteVideoContainer(videoSpanId);
|
||||
var container = addRemoteVideoContainer(peerJid, videoSpanId);
|
||||
|
||||
var nickfield = document.createElement('span');
|
||||
nickfield.className = "nick";
|
||||
|
@ -1457,11 +1506,15 @@ function ensurePeerContainerExists(peerJid) {
|
|||
resizeThumbnails();
|
||||
}
|
||||
|
||||
function addRemoteVideoContainer(id) {
|
||||
function addRemoteVideoContainer(peerJid, spanId) {
|
||||
var container = document.createElement('span');
|
||||
container.id = id;
|
||||
container.id = spanId;
|
||||
container.className = 'videocontainer';
|
||||
var remotes = document.getElementById('remoteVideos');
|
||||
|
||||
if (focus)
|
||||
addRemoteVideoMenu(peerJid, container);
|
||||
|
||||
remotes.appendChild(container);
|
||||
return container;
|
||||
}
|
||||
|
@ -1476,6 +1529,97 @@ function createFocusIndicatorElement(parentElement) {
|
|||
parentElement.appendChild(focusIndicator);
|
||||
}
|
||||
|
||||
function addRemoteVideoMenu(jid, parentElement) {
|
||||
var spanElement = document.createElement('span');
|
||||
spanElement.className = 'remotevideomenu';
|
||||
|
||||
parentElement.appendChild(spanElement);
|
||||
|
||||
var menuElement = document.createElement('i');
|
||||
menuElement.className = 'fa fa-angle-down';
|
||||
menuElement.title = 'Remote user controls';
|
||||
spanElement.appendChild(menuElement);
|
||||
|
||||
// <ul class="popupmenu">
|
||||
// <li><a href="#">Mute</a></li>
|
||||
// <li><a href="#">Eject</a></li>
|
||||
// </ul>
|
||||
var popupmenuElement = document.createElement('ul');
|
||||
popupmenuElement.className = 'popupmenu';
|
||||
popupmenuElement.id = 'remote_popupmenu_' + Strophe.getResourceFromJid(jid);
|
||||
spanElement.appendChild(popupmenuElement);
|
||||
|
||||
var muteMenuItem = document.createElement('li');
|
||||
var muteLinkItem = document.createElement('a');
|
||||
|
||||
var mutedIndicator = "<i class='icon-mic-disabled'></i>";
|
||||
|
||||
if (!mutedAudios[jid]) {
|
||||
muteLinkItem.innerHTML = mutedIndicator + 'Mute';
|
||||
muteLinkItem.className = 'mutelink';
|
||||
}
|
||||
else {
|
||||
muteLinkItem.innerHTML = mutedIndicator + ' Muted';
|
||||
muteLinkItem.className = 'mutelink disabled';
|
||||
}
|
||||
|
||||
muteLinkItem.onclick = function(){
|
||||
if ($(this).attr('disabled') != undefined) {
|
||||
event.preventDefault();
|
||||
}
|
||||
var isMute = !mutedAudios[jid];
|
||||
connection.moderate.setMute(jid, isMute);
|
||||
popupmenuElement.setAttribute('style', 'display:none;');
|
||||
|
||||
if (isMute) {
|
||||
this.innerHTML = mutedIndicator + ' Muted';
|
||||
this.className = 'mutelink disabled';
|
||||
}
|
||||
else {
|
||||
this.innerHTML = mutedIndicator + ' Mute';
|
||||
this.className = 'mutelink';
|
||||
}
|
||||
};
|
||||
|
||||
muteMenuItem.appendChild(muteLinkItem);
|
||||
popupmenuElement.appendChild(muteMenuItem);
|
||||
|
||||
var ejectIndicator = "<i class='fa fa-eject'></i>";
|
||||
|
||||
var ejectMenuItem = document.createElement('li');
|
||||
var ejectLinkItem = document.createElement('a');
|
||||
ejectLinkItem.innerHTML = ejectIndicator + ' Kick out';
|
||||
ejectLinkItem.onclick = function(){
|
||||
connection.moderate.eject(jid);
|
||||
popupmenuElement.setAttribute('style', 'display:none;');
|
||||
};
|
||||
|
||||
ejectMenuItem.appendChild(ejectLinkItem);
|
||||
popupmenuElement.appendChild(ejectMenuItem);
|
||||
}
|
||||
|
||||
function updateRemoteVideoMenu(jid, isMuted) {
|
||||
var muteMenuItem
|
||||
= $('#remote_popupmenu_'
|
||||
+ Strophe.getResourceFromJid(jid)
|
||||
+ '>li>a.mutelink');
|
||||
|
||||
var mutedIndicator = "<i class='icon-mic-disabled'></i>";
|
||||
|
||||
if (muteMenuItem.length) {
|
||||
var muteLink = muteMenuItem.get(0);
|
||||
|
||||
if (isMuted === 'true') {
|
||||
muteLink.innerHTML = mutedIndicator + ' Muted';
|
||||
muteLink.className = 'mutelink disabled';
|
||||
}
|
||||
else {
|
||||
muteLink.innerHTML = mutedIndicator + ' Mute';
|
||||
muteLink.className = 'mutelink';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the application in and out of full screen mode
|
||||
* (a.k.a. presentation mode in Chrome).
|
||||
|
|
|
@ -205,7 +205,6 @@ button {
|
|||
}
|
||||
|
||||
button, input, select, textarea {
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*Initialize*/
|
||||
ul.popupmenu {
|
||||
display:none;
|
||||
position: absolute;
|
||||
padding:0;
|
||||
margin: 0;
|
||||
bottom: 20px;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 5px;
|
||||
right: 10px;
|
||||
left: 0px;
|
||||
width: 100px;
|
||||
background-color: rgba(0,0,0,1);
|
||||
-webkit-box-shadow: 0 0 2px #000000, 0 0 10px #000000;
|
||||
border-radius:8px;
|
||||
}
|
||||
|
||||
ul.popupmenu:after {
|
||||
content: url('../images/popupPointer.png');
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -9px;
|
||||
left: 13px;
|
||||
}
|
||||
|
||||
ul.popupmenu li {
|
||||
list-style-type: none;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.popupmenu li:hover {
|
||||
background-color: rgba(82, 82, 82, .7);
|
||||
border-radius:2px;
|
||||
}
|
||||
|
||||
/*Link Appearance*/
|
||||
ul.popupmenu li a {
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
ul.popupmenu li a i {
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
span.remotevideomenu:hover ul.popupmenu {
|
||||
display:block !important;
|
||||
}
|
||||
|
||||
a.disabled {
|
||||
color: gray !important;
|
||||
pointer-events: none;
|
||||
}
|
|
@ -16,9 +16,8 @@
|
|||
left: 0;
|
||||
right: 0;
|
||||
width:auto;
|
||||
overflow: hidden;
|
||||
border:1px solid transparent;
|
||||
z-index: 2;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.videocontainer {
|
||||
|
@ -41,8 +40,8 @@
|
|||
content:"";
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
transform:scale(1.08, 1.08);
|
||||
-webkit-transform:scale(1.08, 1.08);
|
||||
/* transform:scale(1.08, 1.08);
|
||||
-webkit-transform:scale(1.08, 1.08); */
|
||||
transition-duration: 0.5s;
|
||||
-webkit-transition-duration: 0.5s;
|
||||
-webkit-animation-name: greyPulse;
|
||||
|
@ -107,7 +106,8 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
#remoteVideos .videocontainer>span.focusindicator {
|
||||
#remoteVideos .videocontainer>span.focusindicator,
|
||||
#remoteVideos .videocontainer>span.remotevideomenu {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
color: #FFFFFF;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -31,6 +31,7 @@
|
|||
<script src="prezi.js?v=2"></script><!-- prezi plugin -->
|
||||
<script src="smileys.js?v=1"></script><!-- smiley images -->
|
||||
<script src="replacement.js?v=5"></script><!-- link and smiley replacement -->
|
||||
<script src="moderatemuc.js?v=1"></script><!-- moderator plugin -->
|
||||
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/font.css"/>
|
||||
|
@ -38,6 +39,7 @@
|
|||
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=4" id="videolayout_default"/>
|
||||
<link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
|
||||
<link rel="stylesheet" href="css/modaldialog.css?v=3">
|
||||
<link rel="stylesheet" href="css/popup_menu.css?v=1">
|
||||
<!--
|
||||
Link used for inline installation of chrome desktop streaming extension,
|
||||
is updated automatically from the code with the value defined in config.js -->
|
||||
|
@ -49,7 +51,7 @@
|
|||
<body>
|
||||
<div id="header">
|
||||
<span id="toolbar">
|
||||
<a class="button" onclick='buttonClick("#mute", "icon-microphone icon-mic-disabled");toggleAudio();'>
|
||||
<a class="button" onclick='toggleAudio();'>
|
||||
<i id="mute" title="Mute / unmute" class="icon-microphone"></i></a>
|
||||
<div class="header_button_separator"></div>
|
||||
<a class="button" onclick='buttonClick("#video", "icon-camera icon-camera-disabled");toggleVideo();'>
|
||||
|
|
|
@ -848,3 +848,46 @@ ColibriFocus.prototype.terminate = function (session, reason) {
|
|||
delete this.remotessrc[session.peerjid];
|
||||
this.modifySources();
|
||||
};
|
||||
|
||||
ColibriFocus.prototype.sendTerminate = function (session, reason, text) {
|
||||
var term = $iq({to: session.peerjid, type: 'set'})
|
||||
.c('jingle',
|
||||
{xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'session-terminate',
|
||||
initiator: session.me,
|
||||
sid: session.sid})
|
||||
.c('reason')
|
||||
.c(reason || 'success');
|
||||
|
||||
if (text) {
|
||||
term.up().c('text').t(text);
|
||||
}
|
||||
|
||||
this.connection.sendIQ(term,
|
||||
function () {
|
||||
if (!session)
|
||||
return;
|
||||
|
||||
if (session.peerconnection) {
|
||||
session.peerconnection.close();
|
||||
session.peerconnection = null;
|
||||
}
|
||||
|
||||
session.terminate();
|
||||
var ack = {};
|
||||
ack.source = 'terminate';
|
||||
$(document).trigger('ack.jingle', [session.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
$(document).trigger('ack.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
if (this.statsinterval !== null) {
|
||||
window.clearInterval(this.statsinterval);
|
||||
this.statsinterval = null;
|
||||
}
|
||||
};
|
|
@ -90,5 +90,5 @@ ColibriSession.prototype.sendAnswer = function (sdp, provisional) {
|
|||
};
|
||||
|
||||
ColibriSession.prototype.sendTerminate = function (reason, text) {
|
||||
console.log('ColibriSession.sendTerminate');
|
||||
this.colibri.sendTerminate(this, reason, text);
|
||||
};
|
||||
|
|
|
@ -112,17 +112,27 @@ Strophe.addConnectionPlugin('jingle', {
|
|||
$(document).trigger('callaccepted.jingle', [sess.sid]);
|
||||
break;
|
||||
case 'session-terminate':
|
||||
console.log('terminating...');
|
||||
// If this is not the focus sending the terminate, we have
|
||||
// nothing more to do here.
|
||||
if (Object.keys(this.sessions).length < 1
|
||||
|| !(this.sessions[Object.keys(this.sessions)[0]]
|
||||
instanceof JingleSession))
|
||||
{
|
||||
break;
|
||||
}
|
||||
console.log('terminating...', sess.sid);
|
||||
sess.terminate();
|
||||
this.terminate(sess.sid);
|
||||
if ($(iq).find('>jingle>reason').length) {
|
||||
$(document).trigger('callterminated.jingle', [
|
||||
sess.sid,
|
||||
sess.peerjid,
|
||||
$(iq).find('>jingle>reason>:first')[0].tagName,
|
||||
$(iq).find('>jingle>reason>text').text()
|
||||
]);
|
||||
} else {
|
||||
$(document).trigger('callterminated.jingle', [sess.sid]);
|
||||
$(document).trigger('callterminated.jingle',
|
||||
[sess.sid, sess.peerjid]);
|
||||
}
|
||||
break;
|
||||
case 'transport-info':
|
||||
|
@ -192,6 +202,7 @@ Strophe.addConnectionPlugin('jingle', {
|
|||
delete this.sessions[sid];
|
||||
}
|
||||
},
|
||||
// Used to terminate a session when an unavailable presence is received.
|
||||
terminateByJid: function (jid) {
|
||||
if (this.jid2session.hasOwnProperty(jid)) {
|
||||
var sess = this.jid2session[jid];
|
||||
|
@ -200,7 +211,22 @@ Strophe.addConnectionPlugin('jingle', {
|
|||
console.log('peer went away silently', jid);
|
||||
delete this.sessions[sess.sid];
|
||||
delete this.jid2session[jid];
|
||||
$(document).trigger('callterminated.jingle', [sess.sid, 'gone']);
|
||||
$(document).trigger('callterminated.jingle',
|
||||
[sess.sid, jid], 'gone');
|
||||
}
|
||||
}
|
||||
},
|
||||
terminateRemoteByJid: function (jid, reason) {
|
||||
if (this.jid2session.hasOwnProperty(jid)) {
|
||||
var sess = this.jid2session[jid];
|
||||
if (sess) {
|
||||
sess.sendTerminate(reason || (!sess.active()) ? 'kick' : null);
|
||||
sess.terminate();
|
||||
console.log('terminate peer with jid', sess.sid, jid);
|
||||
delete this.sessions[sess.sid];
|
||||
delete this.jid2session[jid];
|
||||
$(document).trigger('callterminated.jingle',
|
||||
[sess.sid, jid, 'kicked']);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Moderate connection plugin.
|
||||
*/
|
||||
Strophe.addConnectionPlugin('moderate', {
|
||||
connection: null,
|
||||
roomjid: null,
|
||||
myroomjid: null,
|
||||
members: {},
|
||||
list_members: [], // so we can elect a new focus
|
||||
presMap: {},
|
||||
preziMap: {},
|
||||
joined: false,
|
||||
isOwner: false,
|
||||
init: function (conn) {
|
||||
this.connection = conn;
|
||||
|
||||
this.connection.addHandler( this.onMute.bind(this),
|
||||
'http://jitsi.org/jitmeet/audio',
|
||||
'iq',
|
||||
'set',
|
||||
null,
|
||||
null);
|
||||
},
|
||||
setMute: function(jid, mute) {
|
||||
var iq = $iq({to: jid, type: 'set'})
|
||||
.c('mute', {xmlns: 'http://jitsi.org/jitmeet/audio'})
|
||||
.t(mute.toString())
|
||||
.up();
|
||||
|
||||
this.connection.sendIQ(
|
||||
iq,
|
||||
function (result) {
|
||||
console.log('set mute', result);
|
||||
},
|
||||
function (error) {
|
||||
console.log('set mute error', error);
|
||||
});
|
||||
},
|
||||
onMute: function(iq) {
|
||||
var mute = $(iq).find('mute');
|
||||
if (mute.length) {
|
||||
toggleAudio();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
eject: function(jid) {
|
||||
connection.jingle.terminateRemoteByJid(jid, 'kick');
|
||||
connection.emuc.kick(jid);
|
||||
}
|
||||
});
|
41
muc.js
41
muc.js
|
@ -36,6 +36,12 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
}
|
||||
this.sendPresence();
|
||||
},
|
||||
doLeave: function() {
|
||||
console.log("DO LEAVE", this.myroomjid);
|
||||
var pres = $pres({to: this.myroomjid, type: 'unavailable' });
|
||||
this.presMap.length = 0;
|
||||
this.connection.send(pres);
|
||||
},
|
||||
onPresence: function (pres) {
|
||||
var from = pres.getAttribute('from');
|
||||
var type = pres.getAttribute('type');
|
||||
|
@ -125,9 +131,22 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
},
|
||||
onPresenceUnavailable: function (pres) {
|
||||
var from = pres.getAttribute('from');
|
||||
delete this.members[from];
|
||||
this.list_members.splice(this.list_members.indexOf(from), 1);
|
||||
$(document).trigger('left.muc', [from]);
|
||||
// Status code 110 indicates that this notification is "self-presence".
|
||||
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]);
|
||||
}
|
||||
// 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.
|
||||
else if (this.list_members.length > 1) {
|
||||
for (var i = 0; i < this.list_members.length; i++) {
|
||||
var member = this.list_members[i];
|
||||
delete this.members[i];
|
||||
this.list_members.splice(i, 1);
|
||||
$(document).trigger('left.muc', member);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
onPresenceError: function (pres) {
|
||||
|
@ -188,6 +207,21 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
}
|
||||
);
|
||||
},
|
||||
kick: function (jid) {
|
||||
var kickIQ = $iq({to: this.roomjid, type: 'set'})
|
||||
.c('query', {xmlns: 'http://jabber.org/protocol/muc#admin'})
|
||||
.c('item', {nick: Strophe.getResourceFromJid(jid), role: 'none'})
|
||||
.c('reason').t('You have been kicked.').up().up().up();
|
||||
|
||||
this.connection.sendIQ(
|
||||
kickIQ,
|
||||
function (result) {
|
||||
console.log('Kick participant with jid: ' + jid, result);
|
||||
},
|
||||
function (error) {
|
||||
console.log('Kick participant error: ', error);
|
||||
});
|
||||
},
|
||||
sendPresence: function () {
|
||||
var pres = $pres({to: this.presMap['to'] });
|
||||
pres.c('x', {xmlns: this.presMap['xns']});
|
||||
|
@ -210,7 +244,6 @@ Strophe.addConnectionPlugin('emuc', {
|
|||
}
|
||||
|
||||
if (this.presMap['videons']) {
|
||||
console.log("SEND VIDEO MUTED", this.presMap['videomuted']);
|
||||
pres.c('videomuted', {xmlns: this.presMap['videons']})
|
||||
.t(this.presMap['videomuted']).up();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue