Fixes #1094
- Show users who are registered on the different members lists - Show badges indicating user's roles and affiliations
This commit is contained in:
parent
28ec15094e
commit
859bc0616e
@ -8309,9 +8309,8 @@ body.reset {
|
|||||||
display: block;
|
display: block;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0.2em 0.5em 0.2em 0;
|
padding: 0.25em 0.25em 0.25em 0;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis; }
|
||||||
white-space: nowrap; }
|
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li .fa,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li .fa,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li .fa {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li .fa {
|
||||||
margin-right: 0.5em; }
|
margin-right: 0.5em; }
|
||||||
@ -8321,10 +8320,16 @@ body.reset {
|
|||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant {
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters,
|
||||||
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters {
|
||||||
|
flex-wrap: nowrap; }
|
||||||
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge,
|
||||||
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge {
|
||||||
|
margin-top: 0.125rem; }
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 0.5em;
|
margin: 0.5em 0.5em 0.5em 0;
|
||||||
width: 0.5em;
|
width: 0.5em;
|
||||||
height: 0.5em; }
|
height: 0.5em; }
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online, #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online, #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,
|
||||||
@ -8340,12 +8345,9 @@ body.reset {
|
|||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa {
|
||||||
background-color: orange; }
|
background-color: orange; }
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.moderator,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.moderator {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline {
|
||||||
color: #D24E2B; }
|
background-color: darkgrey; }
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.visitor,
|
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.visitor {
|
|
||||||
color: #A8ABA1; }
|
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container {
|
#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -8449,9 +8449,8 @@ body {
|
|||||||
display: block;
|
display: block;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0.2em 0.5em 0.2em 0;
|
padding: 0.25em 0.25em 0.25em 0;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis; }
|
||||||
white-space: nowrap; }
|
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li .fa,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li .fa,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li .fa {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li .fa {
|
||||||
margin-right: 0.5em; }
|
margin-right: 0.5em; }
|
||||||
@ -8461,10 +8460,16 @@ body {
|
|||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant {
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters,
|
||||||
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters {
|
||||||
|
flex-wrap: nowrap; }
|
||||||
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge,
|
||||||
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge {
|
||||||
|
margin-top: 0.125rem; }
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 0.5em;
|
margin: 0.5em 0.5em 0.5em 0;
|
||||||
width: 0.5em;
|
width: 0.5em;
|
||||||
height: 0.5em; }
|
height: 0.5em; }
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online, #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online, #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,
|
||||||
@ -8480,12 +8485,9 @@ body {
|
|||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa {
|
||||||
background-color: orange; }
|
background-color: orange; }
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.moderator,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.moderator {
|
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline {
|
||||||
color: #D24E2B; }
|
background-color: darkgrey; }
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.visitor,
|
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.visitor {
|
|
||||||
color: #A8ABA1; }
|
|
||||||
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container,
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container,
|
||||||
#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container {
|
#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -233,15 +233,21 @@
|
|||||||
|
|
||||||
<ul class="occupant-list">
|
<ul class="occupant-list">
|
||||||
<li class="moderator occupant" title="Click to mention leia in your message.">
|
<li class="moderator occupant" title="Click to mention leia in your message.">
|
||||||
<div class="occupant-status occupant-online circle" title="Online"></div>Juliet Capulet</li>
|
<div class="occupant-status occupant-online circle" title="Online"></div>Juliet Capulet
|
||||||
|
<span class="badge badge-info">Owner</span>
|
||||||
|
</li>
|
||||||
<li class="moderator occupant" title="Click to mention leia in your message.">
|
<li class="moderator occupant" title="Click to mention leia in your message.">
|
||||||
<div class="occupant-status occupant-online circle" title="Online"></div>Romeo Montague</li>
|
<div class="occupant-status occupant-online circle" title="Online"></div>Romeo Montague
|
||||||
<li class="participant occupant" title="Click to mention leia in your message.">
|
<span class="badge badge-info">Moderator</span>
|
||||||
<div class="occupant-status occupant-online circle" title="Online"></div>Mercutio</li>
|
</li>
|
||||||
<li class="participant occupant" title="Click to mention leia in your message.">
|
<li class="participant occupant" title="Click to mention leia in your message.">
|
||||||
<div class="occupant-status occupant-away circle" title="Away"></div>Lady Montague</li>
|
<div class="occupant-status occupant-away circle" title="Away"></div>Lady Montague</li>
|
||||||
<li class="participant occupant" title="Click to mention leia in your message.">
|
<li class="participant occupant" title="Click to mention leia in your message.">
|
||||||
<div class="occupant-status occupant-online circle" title="Online"></div>Lord Montague</li>
|
<div class="occupant-status occupant-online circle" title="Online"></div>Mercutio
|
||||||
|
<span class="badge badge-secondary">Visitor</span>
|
||||||
|
</li>
|
||||||
|
<li class="participant occupant" title="Click to mention leia in your message.">
|
||||||
|
<div class="occupant-status occupant-offline circle" title="Offline"></div>Lord Montague</li>
|
||||||
<li class="participant occupant" title="Click to mention leia in your message.">
|
<li class="participant occupant" title="Click to mention leia in your message.">
|
||||||
<div class="occupant-status occupant-online circle" title="Online"></div>Friar Laurence</li>
|
<div class="occupant-status occupant-online circle" title="Online"></div>Friar Laurence</li>
|
||||||
<li class="participant occupant" title="Click to mention leia in your message.">
|
<li class="participant occupant" title="Click to mention leia in your message.">
|
||||||
|
@ -172,9 +172,8 @@
|
|||||||
display: block;
|
display: block;
|
||||||
font-size: $font-size-small;
|
font-size: $font-size-small;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0.2em 0.5em 0.2em 0;
|
padding: 0.25em 0.25em 0.25em 0;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
|
||||||
.fa {
|
.fa {
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
}
|
}
|
||||||
@ -183,11 +182,21 @@
|
|||||||
}
|
}
|
||||||
&.occupant {
|
&.occupant {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
div.row.no-gutters {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
margin-top: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
.occupant-status {
|
.occupant-status {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 0.5em;
|
margin: 0.5em 0.5em 0.5em 0;
|
||||||
width: 0.5em;
|
width: 0.5em;
|
||||||
height: 0.5em;
|
height: 0.5em;
|
||||||
|
|
||||||
&.occupant-online,
|
&.occupant-online,
|
||||||
&.occupant-chat {
|
&.occupant-chat {
|
||||||
background-color: #1A9707;
|
background-color: #1A9707;
|
||||||
@ -201,14 +210,11 @@
|
|||||||
&.occupant-xa {
|
&.occupant-xa {
|
||||||
background-color: orange;
|
background-color: orange;
|
||||||
}
|
}
|
||||||
|
&.occupant-offline {
|
||||||
|
background-color: darkgrey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.moderator {
|
|
||||||
color: $moderator-color;
|
|
||||||
}
|
|
||||||
&.visitor {
|
|
||||||
color: $visitor-color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1142,8 +1142,7 @@
|
|||||||
expect(occupants.querySelectorAll('li').length).toBe(2+i);
|
expect(occupants.querySelectorAll('li').length).toBe(2+i);
|
||||||
model = view.occupantsview.model.where({'nick': name})[0];
|
model = view.occupantsview.model.where({'nick': name})[0];
|
||||||
var index = view.occupantsview.model.indexOf(model);
|
var index = view.occupantsview.model.indexOf(model);
|
||||||
expect(occupants.querySelectorAll('li')[index].textContent).toBe(mock.chatroom_names[i]);
|
expect(occupants.querySelectorAll('li .occupant-nick')[index].textContent.trim()).toBe(mock.chatroom_names[i]);
|
||||||
expect($(occupants.querySelectorAll('li')[index]).hasClass('moderator')).toBe(role === "moderator");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test users leaving the room
|
// Test users leaving the room
|
||||||
@ -1166,7 +1165,7 @@
|
|||||||
expect(occupants.querySelectorAll('li').length).toBe(i+1);
|
expect(occupants.querySelectorAll('li').length).toBe(i+1);
|
||||||
}
|
}
|
||||||
done();
|
done();
|
||||||
});
|
}).catch(_.partial(console.error, _));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("escapes occupant nicknames when rendering them, to avoid JS-injection attacks",
|
it("escapes occupant nicknames when rendering them, to avoid JS-injection attacks",
|
||||||
@ -1193,9 +1192,9 @@
|
|||||||
|
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
var view = _converse.chatboxviews.get('lounge@localhost');
|
var view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
var occupants = view.el.querySelector('.occupant-list').querySelectorAll('li');
|
var occupants = view.el.querySelector('.occupant-list').querySelectorAll('li .occupant-nick');
|
||||||
expect(occupants.length).toBe(2);
|
expect(occupants.length).toBe(2);
|
||||||
expect($(occupants).first().text()).toBe("<img src="x" onerror="alert(123)"/>");
|
expect($(occupants).first().text().trim()).toBe("<img src="x" onerror="alert(123)"/>");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
@ -1208,6 +1207,13 @@
|
|||||||
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
|
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
|
||||||
var view = _converse.chatboxviews.get('lounge@localhost');
|
var view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
|
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
|
||||||
|
var occupants = view.el.querySelector('.occupant-list').querySelectorAll('li');
|
||||||
|
expect(occupants.length).toBe(1);
|
||||||
|
expect($(occupants).first().find('.occupant-nick').text().trim()).toBe("dummy");
|
||||||
|
expect($(occupants).first().find('.badge').length).toBe(1);
|
||||||
|
expect($(occupants).first().find('.badge').first().text()).toBe('Member');
|
||||||
|
|
||||||
var presence = $pres({
|
var presence = $pres({
|
||||||
to:'dummy@localhost/pda',
|
to:'dummy@localhost/pda',
|
||||||
from:'lounge@localhost/moderatorman'
|
from:'lounge@localhost/moderatorman'
|
||||||
@ -1220,11 +1226,14 @@
|
|||||||
.c('status').attrs({code:'110'}).nodeTree;
|
.c('status').attrs({code:'110'}).nodeTree;
|
||||||
|
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
var occupants = view.el.querySelector('.occupant-list').querySelectorAll('li');
|
occupants = view.el.querySelector('.occupant-list').querySelectorAll('li');
|
||||||
expect(occupants.length).toBe(2);
|
expect(occupants.length).toBe(2);
|
||||||
expect($(occupants).first().text()).toBe("moderatorman");
|
expect($(occupants).first().find('.occupant-nick').text().trim()).toBe("moderatorman");
|
||||||
expect($(occupants).last().text()).toBe("dummy");
|
expect($(occupants).last().find('.occupant-nick').text().trim()).toBe("dummy");
|
||||||
expect($(occupants).first().attr('class').indexOf('moderator')).not.toBe(-1);
|
expect($(occupants).first().find('.badge').length).toBe(2);
|
||||||
|
expect($(occupants).first().find('.badge').first().text()).toBe('Admin');
|
||||||
|
expect($(occupants).first().find('.badge').last().text()).toBe('Moderator');
|
||||||
|
|
||||||
expect($(occupants).first().attr('title')).toBe(
|
expect($(occupants).first().attr('title')).toBe(
|
||||||
contact_jid + ' This user is a moderator. Click to mention moderatorman in your message.'
|
contact_jid + ' This user is a moderator. Click to mention moderatorman in your message.'
|
||||||
);
|
);
|
||||||
@ -1242,13 +1251,14 @@
|
|||||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
|
|
||||||
occupants = view.el.querySelector('.occupant-list').querySelectorAll('li');
|
occupants = view.el.querySelector('.occupant-list').querySelectorAll('li');
|
||||||
expect($(occupants).last().text()).toBe("visitorwoman");
|
expect($(occupants).last().find('.occupant-nick').text().trim()).toBe("visitorwoman");
|
||||||
expect($(occupants).last().attr('class').indexOf('visitor')).not.toBe(-1);
|
expect($(occupants).last().find('.badge').length).toBe(1);
|
||||||
|
expect($(occupants).last().find('.badge').last().text()).toBe('Visitor');
|
||||||
expect($(occupants).last().attr('title')).toBe(
|
expect($(occupants).last().attr('title')).toBe(
|
||||||
contact_jid + ' This user can NOT send messages in this room. Click to mention visitorwoman in your message.'
|
contact_jid + ' This user can NOT send messages in this room. Click to mention visitorwoman in your message.'
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
}).catch(_.partial(console.error, _));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("will use the user's reserved nickname, if it exists",
|
it("will use the user's reserved nickname, if it exists",
|
||||||
@ -1656,7 +1666,7 @@
|
|||||||
|
|
||||||
var $occupants = $(view.el.querySelector('.occupant-list'));
|
var $occupants = $(view.el.querySelector('.occupant-list'));
|
||||||
expect($occupants.children().length).toBe(1);
|
expect($occupants.children().length).toBe(1);
|
||||||
expect($occupants.children().first(0).text()).toBe("oldnick");
|
expect($occupants.children().first(0).find('.occupant-nick').text().trim()).toBe("oldnick");
|
||||||
|
|
||||||
expect($chat_content.find('div.chat-info').length).toBe(1);
|
expect($chat_content.find('div.chat-info').length).toBe(1);
|
||||||
expect($chat_content.find('div.chat-info:first').html()).toBe("oldnick has entered the room");
|
expect($chat_content.find('div.chat-info:first').html()).toBe("oldnick has entered the room");
|
||||||
|
@ -537,8 +537,7 @@
|
|||||||
// collection anymore).
|
// collection anymore).
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.join();
|
this.populateAndJoin();
|
||||||
this.fetchMessages();
|
|
||||||
_converse.emit('chatRoomOpened', this);
|
_converse.emit('chatRoomOpened', this);
|
||||||
}
|
}
|
||||||
this.model.getRoomFeatures().then(handler, handler);
|
this.model.getRoomFeatures().then(handler, handler);
|
||||||
@ -919,6 +918,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
populateAndJoin () {
|
||||||
|
this.model.occupants.fetchMembers();
|
||||||
|
this.join();
|
||||||
|
this.fetchMessages();
|
||||||
|
},
|
||||||
|
|
||||||
join (nick, password) {
|
join (nick, password) {
|
||||||
/* Join the chat room.
|
/* Join the chat room.
|
||||||
*
|
*
|
||||||
@ -1536,7 +1541,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
toHTML () {
|
toHTML () {
|
||||||
const show = this.model.get('show') || 'online';
|
const show = this.model.get('show');
|
||||||
return tpl_occupant(
|
return tpl_occupant(
|
||||||
_.extend(
|
_.extend(
|
||||||
{ 'jid': '',
|
{ 'jid': '',
|
||||||
@ -1544,8 +1549,13 @@
|
|||||||
'hint_show': _converse.PRETTY_CHAT_STATUS[show],
|
'hint_show': _converse.PRETTY_CHAT_STATUS[show],
|
||||||
'hint_occupant': __('Click to mention %1$s in your message.', this.model.get('nick')),
|
'hint_occupant': __('Click to mention %1$s in your message.', this.model.get('nick')),
|
||||||
'desc_moderator': __('This user is a moderator.'),
|
'desc_moderator': __('This user is a moderator.'),
|
||||||
'desc_occupant': __('This user can send messages in this room.'),
|
'desc_participant': __('This user can send messages in this room.'),
|
||||||
'desc_visitor': __('This user can NOT send messages in this room.')
|
'desc_visitor': __('This user can NOT send messages in this room.'),
|
||||||
|
'label_moderator': __('Moderator'),
|
||||||
|
'label_visitor': __('Visitor'),
|
||||||
|
'label_owner': __('Owner'),
|
||||||
|
'label_member': __('Member'),
|
||||||
|
'label_admin': __('Admin')
|
||||||
}, this.model.toJSON())
|
}, this.model.toJSON())
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -1824,8 +1834,7 @@
|
|||||||
if (view.model.get('type') === converse.CHATROOMS_TYPE) {
|
if (view.model.get('type') === converse.CHATROOMS_TYPE) {
|
||||||
view.model.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
|
view.model.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
|
||||||
view.model.registerHandlers();
|
view.model.registerHandlers();
|
||||||
view.join();
|
view.populateAndJoin();
|
||||||
view.fetchMessages();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
'moderator': 1,
|
'moderator': 1,
|
||||||
'participant': 2,
|
'participant': 2,
|
||||||
'visitor': 3,
|
'visitor': 3,
|
||||||
'none': 4,
|
'none': 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { Strophe, Backbone, Promise, $iq, $build, $msg, $pres, b64_sha1, sizzle, _, moment } = converse.env;
|
const { Strophe, Backbone, Promise, $iq, $build, $msg, $pres, b64_sha1, sizzle, _, moment } = converse.env;
|
||||||
@ -187,6 +187,8 @@
|
|||||||
this.occupants.browserStorage = new Backbone.BrowserStorage.session(
|
this.occupants.browserStorage = new Backbone.BrowserStorage.session(
|
||||||
b64_sha1(`converse.occupants-${_converse.bare_jid}${this.get('jid')}`)
|
b64_sha1(`converse.occupants-${_converse.bare_jid}${this.get('jid')}`)
|
||||||
);
|
);
|
||||||
|
this.occupants.chatroom = this;
|
||||||
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
this.on('change:chat_state', this.sendChatState, this);
|
this.on('change:chat_state', this.sendChatState, this);
|
||||||
},
|
},
|
||||||
@ -726,22 +728,6 @@
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
findOccupant (data) {
|
|
||||||
/* Try to find an existing occupant based on the passed in
|
|
||||||
* data object.
|
|
||||||
*
|
|
||||||
* If we have a JID, we use that as lookup variable,
|
|
||||||
* otherwise we use the nick. We don't always have both,
|
|
||||||
* but should have at least one or the other.
|
|
||||||
*/
|
|
||||||
const jid = Strophe.getBareJidFromJid(data.jid);
|
|
||||||
if (jid !== null) {
|
|
||||||
return this.occupants.where({'jid': jid}).pop();
|
|
||||||
} else {
|
|
||||||
return this.occupants.where({'nick': data.nick}).pop();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
updateOccupantsOnPresence (pres) {
|
updateOccupantsOnPresence (pres) {
|
||||||
/* Given a presence stanza, update the occupant model
|
/* Given a presence stanza, update the occupant model
|
||||||
* based on its contents.
|
* based on its contents.
|
||||||
@ -753,7 +739,7 @@
|
|||||||
if (data.type === 'error') {
|
if (data.type === 'error') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const occupant = this.findOccupant(data);
|
const occupant = this.occupants.findOccupant(data);
|
||||||
if (data.type === 'unavailable') {
|
if (data.type === 'unavailable') {
|
||||||
if (occupant) {
|
if (occupant) {
|
||||||
// Even before destroying, we set the new data, so
|
// Even before destroying, we set the new data, so
|
||||||
@ -788,7 +774,8 @@
|
|||||||
'from': from,
|
'from': from,
|
||||||
'nick': Strophe.getResourceFromJid(from),
|
'nick': Strophe.getResourceFromJid(from),
|
||||||
'type': pres.getAttribute("type"),
|
'type': pres.getAttribute("type"),
|
||||||
'states': []
|
'states': [],
|
||||||
|
'show': 'online'
|
||||||
};
|
};
|
||||||
_.each(pres.childNodes, function (child) {
|
_.each(pres.childNodes, function (child) {
|
||||||
switch (child.nodeName) {
|
switch (child.nodeName) {
|
||||||
@ -987,6 +974,11 @@
|
|||||||
|
|
||||||
|
|
||||||
_converse.ChatRoomOccupant = Backbone.Model.extend({
|
_converse.ChatRoomOccupant = Backbone.Model.extend({
|
||||||
|
|
||||||
|
defaults: {
|
||||||
|
'show': 'offline'
|
||||||
|
},
|
||||||
|
|
||||||
initialize (attributes) {
|
initialize (attributes) {
|
||||||
this.set(_.extend({
|
this.set(_.extend({
|
||||||
'id': _converse.connection.getUniqueId(),
|
'id': _converse.connection.getUniqueId(),
|
||||||
@ -1014,13 +1006,48 @@
|
|||||||
const role1 = occupant1.get('role') || 'none';
|
const role1 = occupant1.get('role') || 'none';
|
||||||
const role2 = occupant2.get('role') || 'none';
|
const role2 = occupant2.get('role') || 'none';
|
||||||
if (MUC_ROLE_WEIGHTS[role1] === MUC_ROLE_WEIGHTS[role2]) {
|
if (MUC_ROLE_WEIGHTS[role1] === MUC_ROLE_WEIGHTS[role2]) {
|
||||||
const nick1 = occupant1.get('nick').toLowerCase();
|
try {
|
||||||
const nick2 = occupant2.get('nick').toLowerCase();
|
const nick1 = occupant1.get('nick').toLowerCase();
|
||||||
return nick1 < nick2 ? -1 : (nick1 > nick2? 1 : 0);
|
const nick2 = occupant2.get('nick').toLowerCase();
|
||||||
|
return nick1 < nick2 ? -1 : (nick1 > nick2? 1 : 0);
|
||||||
|
} catch (e) {
|
||||||
|
debugger;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return MUC_ROLE_WEIGHTS[role1] < MUC_ROLE_WEIGHTS[role2] ? -1 : 1;
|
return MUC_ROLE_WEIGHTS[role1] < MUC_ROLE_WEIGHTS[role2] ? -1 : 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
fetchMembers () {
|
||||||
|
this.chatroom.getJidsWithAffiliations(['member', 'owner', 'admin'])
|
||||||
|
.then((jids) => {
|
||||||
|
_.each(jids, (attrs) => {
|
||||||
|
const occupant = this.findOccupant({'jid': attrs.jid});
|
||||||
|
if (occupant) {
|
||||||
|
occupant.save(attrs);
|
||||||
|
} else {
|
||||||
|
this.create(attrs);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR));
|
||||||
|
},
|
||||||
|
|
||||||
|
findOccupant (data) {
|
||||||
|
/* Try to find an existing occupant based on the passed in
|
||||||
|
* data object.
|
||||||
|
*
|
||||||
|
* If we have a JID, we use that as lookup variable,
|
||||||
|
* otherwise we use the nick. We don't always have both,
|
||||||
|
* but should have at least one or the other.
|
||||||
|
*/
|
||||||
|
const jid = Strophe.getBareJidFromJid(data.jid);
|
||||||
|
if (jid !== null) {
|
||||||
|
return this.where({'jid': jid}).pop();
|
||||||
|
} else {
|
||||||
|
return this.where({'nick': data.nick}).pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,40 @@
|
|||||||
<li class="{{{ o.role }}} occupant" id="{{{ o.id }}}"
|
<li class="occupant" id="{{{ o.id }}}"
|
||||||
{[ if (o.role === "moderator") { ]}
|
{[ if (o.role === "moderator") { ]}
|
||||||
title="{{{ o.jid }}} {{{ o.desc_moderator }}} {{{ o.hint_occupant }}}"
|
title="{{{ o.jid }}} {{{ o.desc_moderator }}} {{{ o.hint_occupant }}}"
|
||||||
{[ } ]}
|
{[ } ]}
|
||||||
{[ if (o.role === "occupant") { ]}
|
{[ if (o.role === "participant") { ]}
|
||||||
title="{{{ o.jid }}} {{{ o.desc_occupant }}} {{{ o.hint_occupant }}}"
|
title="{{{ o.jid }}} {{{ o.desc_participant }}} {{{ o.hint_occupant }}}"
|
||||||
{[ } ]}
|
{[ } ]}
|
||||||
{[ if (o.role === "visitor") { ]}
|
{[ if (o.role === "visitor") { ]}
|
||||||
title="{{{ o.jid }}} {{{ o.desc_visitor }}} {{{ o.hint_occupant }}}"
|
title="{{{ o.jid }}} {{{ o.desc_visitor }}} {{{ o.hint_occupant }}}"
|
||||||
{[ } ]}
|
{[ } ]}
|
||||||
{[ if (!_.includes(["visitor", "occupant", "moderator"], o.role)) { ]}
|
{[ if (!_.includes(["visitor", "participant", "moderator"], o.role)) { ]}
|
||||||
title="{{{ o.jid }}} {{{ o.hint_occupant }}}"
|
title="{{{ o.jid }}} {{{ o.hint_occupant }}}"
|
||||||
{[ } ]}><div class="occupant-status occupant-{{{o.show}}} circle" title="{{{o.hint_show}}}"></div>{{{o.nick}}}</li>
|
{[ } ]}>
|
||||||
|
<div class="row no-gutters">
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="occupant-status occupant-{{{o.show}}} circle" title="{{{o.hint_show}}}"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="occupant-nick">
|
||||||
|
{{{o.nick || o.jid}}}
|
||||||
|
</span>
|
||||||
|
{[ if (o.affiliation === "owner") { ]}
|
||||||
|
<span class="badge badge-danger">{{{o.label_owner}}}</span>
|
||||||
|
{[ } ]}
|
||||||
|
{[ if (o.affiliation === "admin") { ]}
|
||||||
|
<span class="badge badge-info">{{{o.label_admin}}}</span>
|
||||||
|
{[ } ]}
|
||||||
|
{[ if (o.affiliation === "member") { ]}
|
||||||
|
<span class="badge badge-info">{{{o.label_member}}}</span>
|
||||||
|
{[ } ]}
|
||||||
|
|
||||||
|
{[ if (o.role === "moderator") { ]}
|
||||||
|
<span class="badge badge-info">{{{o.label_moderator}}}</span>
|
||||||
|
{[ } ]}
|
||||||
|
{[ if (o.role === "visitor") { ]}
|
||||||
|
<span class="badge badge-secondary">{{{o.label_visitor}}}</span>
|
||||||
|
{[ } ]}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
@ -72,15 +72,32 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
u.parseMemberListIQ = function parseMemberListIQ (iq) {
|
u.parseMemberListIQ = function parseMemberListIQ (iq) {
|
||||||
/* Given an IQ stanza with a member list, create an array of member
|
/* Given an IQ stanza with a member list, create an array of member objects.
|
||||||
* objects.
|
*/
|
||||||
*/
|
|
||||||
return _.map(
|
return _.map(
|
||||||
sizzle(`query[xmlns="${Strophe.NS.MUC_ADMIN}"] item`, iq),
|
sizzle(`query[xmlns="${Strophe.NS.MUC_ADMIN}"] item`, iq),
|
||||||
(item) => ({
|
(item) => {
|
||||||
'jid': item.getAttribute('jid'),
|
const data = {
|
||||||
'affiliation': item.getAttribute('affiliation'),
|
'affiliation': item.getAttribute('affiliation'),
|
||||||
})
|
}
|
||||||
|
const jid = item.getAttribute('jid');
|
||||||
|
if (u.isValidJID(jid)) {
|
||||||
|
data['jid'] = jid;
|
||||||
|
} else {
|
||||||
|
// XXX: Prosody sends nick for the jid attribute value
|
||||||
|
// Perhaps for anonymous room?
|
||||||
|
data['nick'] = jid;
|
||||||
|
}
|
||||||
|
const nick = item.getAttribute('nick');
|
||||||
|
if (nick) {
|
||||||
|
data['nick'] = nick;
|
||||||
|
}
|
||||||
|
const role = item.getAttribute('role');
|
||||||
|
if (role) {
|
||||||
|
data['role'] = nick;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user