Add a modal to list rooms
This commit is contained in:
parent
e143c88475
commit
4e508cfe88
@ -4993,8 +4993,7 @@ body.reset {
|
|||||||
#conversejs .centered {
|
#conversejs .centered {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0;
|
margin: 0; }
|
||||||
padding: 10% 0; }
|
|
||||||
#conversejs .hor_centered {
|
#conversejs .hor_centered {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: block;
|
display: block;
|
||||||
@ -5653,6 +5652,22 @@ body.reset {
|
|||||||
color: #A8ABA1; }
|
color: #A8ABA1; }
|
||||||
#conversejs .set-xmpp-status .fa-times-circle, #conversejs .xmpp-status .fa-times-circle, #conversejs .roster-contacts .fa-times-circle {
|
#conversejs .set-xmpp-status .fa-times-circle, #conversejs .xmpp-status .fa-times-circle, #conversejs .roster-contacts .fa-times-circle {
|
||||||
color: #A8ABA1; }
|
color: #A8ABA1; }
|
||||||
|
#conversejs .room-info {
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal; }
|
||||||
|
#conversejs .room-info li.room-info {
|
||||||
|
display: block;
|
||||||
|
margin-left: 5px; }
|
||||||
|
#conversejs .room-info p.room-info {
|
||||||
|
line-height: 16px;
|
||||||
|
margin: 0;
|
||||||
|
display: block;
|
||||||
|
white-space: normal; }
|
||||||
|
#conversejs div.room-info {
|
||||||
|
padding: 0.3em 0;
|
||||||
|
clear: left;
|
||||||
|
width: 100%; }
|
||||||
#conversejs #converse-modals .set-xmpp-status {
|
#conversejs #converse-modals .set-xmpp-status {
|
||||||
margin: 1em; }
|
margin: 1em; }
|
||||||
#conversejs #converse-modals .set-xmpp-status .custom-control-label {
|
#conversejs #converse-modals .set-xmpp-status .custom-control-label {
|
||||||
@ -5795,22 +5810,6 @@ body.reset {
|
|||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list {
|
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list {
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
text-align: left; }
|
text-align: left; }
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .room-info {
|
|
||||||
font-size: 12px;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal; }
|
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .room-info li.room-info {
|
|
||||||
display: block;
|
|
||||||
margin-left: 5px; }
|
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .room-info p.room-info {
|
|
||||||
line-height: 16px;
|
|
||||||
margin: 0;
|
|
||||||
display: block;
|
|
||||||
white-space: normal; }
|
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list div.room-info {
|
|
||||||
padding: 0.3em 0;
|
|
||||||
clear: left;
|
|
||||||
width: 100%; }
|
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .available-chatroom,
|
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .available-chatroom,
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .open-chatroom {
|
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .open-chatroom {
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -4993,8 +4993,7 @@ body.reset {
|
|||||||
#conversejs .centered {
|
#conversejs .centered {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0;
|
margin: 0; }
|
||||||
padding: 10% 0; }
|
|
||||||
#conversejs .hor_centered {
|
#conversejs .hor_centered {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: block;
|
display: block;
|
||||||
@ -5725,6 +5724,22 @@ body {
|
|||||||
color: #A8ABA1; }
|
color: #A8ABA1; }
|
||||||
#conversejs .set-xmpp-status .fa-times-circle, #conversejs .xmpp-status .fa-times-circle, #conversejs .roster-contacts .fa-times-circle {
|
#conversejs .set-xmpp-status .fa-times-circle, #conversejs .xmpp-status .fa-times-circle, #conversejs .roster-contacts .fa-times-circle {
|
||||||
color: #A8ABA1; }
|
color: #A8ABA1; }
|
||||||
|
#conversejs .room-info {
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal; }
|
||||||
|
#conversejs .room-info li.room-info {
|
||||||
|
display: block;
|
||||||
|
margin-left: 5px; }
|
||||||
|
#conversejs .room-info p.room-info {
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 0;
|
||||||
|
display: block;
|
||||||
|
white-space: normal; }
|
||||||
|
#conversejs div.room-info {
|
||||||
|
padding: 0.3em 0;
|
||||||
|
clear: left;
|
||||||
|
width: 100%; }
|
||||||
#conversejs #converse-modals .set-xmpp-status {
|
#conversejs #converse-modals .set-xmpp-status {
|
||||||
margin: 1em; }
|
margin: 1em; }
|
||||||
#conversejs #converse-modals .set-xmpp-status .custom-control-label {
|
#conversejs #converse-modals .set-xmpp-status .custom-control-label {
|
||||||
@ -5867,22 +5882,6 @@ body {
|
|||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list {
|
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list {
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
text-align: left; }
|
text-align: left; }
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .room-info {
|
|
||||||
font-size: 14px;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal; }
|
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .room-info li.room-info {
|
|
||||||
display: block;
|
|
||||||
margin-left: 5px; }
|
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .room-info p.room-info {
|
|
||||||
line-height: 22px;
|
|
||||||
margin: 0;
|
|
||||||
display: block;
|
|
||||||
white-space: normal; }
|
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list div.room-info {
|
|
||||||
padding: 0.3em 0;
|
|
||||||
clear: left;
|
|
||||||
width: 100%; }
|
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .available-chatroom,
|
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .available-chatroom,
|
||||||
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .open-chatroom {
|
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-list .open-chatroom {
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -18,6 +18,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.room-info {
|
||||||
|
font-size: $font-size-small;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
li.room-info {
|
||||||
|
display: block;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
p.room-info {
|
||||||
|
line-height: $line-height;
|
||||||
|
margin: 0;
|
||||||
|
display: block;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div.room-info {
|
||||||
|
padding: 0.3em 0;
|
||||||
|
clear: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
#converse-modals {
|
#converse-modals {
|
||||||
.set-xmpp-status {
|
.set-xmpp-status {
|
||||||
@ -225,26 +246,6 @@
|
|||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
.room-info {
|
|
||||||
font-size: $font-size-small;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
li.room-info {
|
|
||||||
display: block;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
p.room-info {
|
|
||||||
line-height: $line-height;
|
|
||||||
margin: 0;
|
|
||||||
display: block;
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
div.room-info {
|
|
||||||
padding: 0.3em 0;
|
|
||||||
clear: left;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.available-chatroom,
|
.available-chatroom,
|
||||||
.open-chatroom {
|
.open-chatroom {
|
||||||
|
@ -303,7 +303,6 @@ body.reset {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 10% 0;
|
|
||||||
}
|
}
|
||||||
.hor_centered {
|
.hor_centered {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"tpl!chatroom_sidebar",
|
"tpl!chatroom_sidebar",
|
||||||
"tpl!chatroom_toolbar",
|
"tpl!chatroom_toolbar",
|
||||||
"tpl!info",
|
"tpl!info",
|
||||||
|
"tpl!list_chatrooms_modal",
|
||||||
"tpl!occupant",
|
"tpl!occupant",
|
||||||
"tpl!room_description",
|
"tpl!room_description",
|
||||||
"tpl!room_item",
|
"tpl!room_item",
|
||||||
@ -50,6 +51,7 @@
|
|||||||
tpl_chatroom_sidebar,
|
tpl_chatroom_sidebar,
|
||||||
tpl_chatroom_toolbar,
|
tpl_chatroom_toolbar,
|
||||||
tpl_info,
|
tpl_info,
|
||||||
|
tpl_list_chatrooms_modal,
|
||||||
tpl_occupant,
|
tpl_occupant,
|
||||||
tpl_room_description,
|
tpl_room_description,
|
||||||
tpl_room_item,
|
tpl_room_item,
|
||||||
@ -78,7 +80,6 @@
|
|||||||
'unmoderated': 'moderated'
|
'unmoderated': 'moderated'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
converse.plugins.add('converse-muc-views', {
|
converse.plugins.add('converse-muc-views', {
|
||||||
/* Dependencies are other plugins which might be
|
/* Dependencies are other plugins which might be
|
||||||
* overridden or relied upon, and therefore need to be loaded before
|
* overridden or relied upon, and therefore need to be loaded before
|
||||||
@ -150,6 +151,212 @@
|
|||||||
_converse.api.promises.add(['roomsPanelRendered']);
|
_converse.api.promises.add(['roomsPanelRendered']);
|
||||||
|
|
||||||
|
|
||||||
|
function insertRoomInfo (el, stanza) {
|
||||||
|
/* Insert room info (based on returned #disco IQ stanza)
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (HTMLElement) el: The HTML DOM element that should
|
||||||
|
* contain the info.
|
||||||
|
* (XMLElement) stanza: The IQ stanza containing the room
|
||||||
|
* info.
|
||||||
|
*/
|
||||||
|
// All MUC features found here: http://xmpp.org/registrar/disco-features.html
|
||||||
|
el.querySelector('span.spinner').remove();
|
||||||
|
el.querySelector('a.room-info').classList.add('selected');
|
||||||
|
el.insertAdjacentHTML(
|
||||||
|
'beforeEnd',
|
||||||
|
tpl_room_description({
|
||||||
|
'jid': stanza.getAttribute('from'),
|
||||||
|
'desc': _.get(_.head(sizzle('field[var="muc#roominfo_description"] value', stanza)), 'textContent'),
|
||||||
|
'occ': _.get(_.head(sizzle('field[var="muc#roominfo_occupants"] value', stanza)), 'textContent'),
|
||||||
|
'hidden': sizzle('feature[var="muc_hidden"]', stanza).length,
|
||||||
|
'membersonly': sizzle('feature[var="muc_membersonly"]', stanza).length,
|
||||||
|
'moderated': sizzle('feature[var="muc_moderated"]', stanza).length,
|
||||||
|
'nonanonymous': sizzle('feature[var="muc_nonanonymous"]', stanza).length,
|
||||||
|
'open': sizzle('feature[var="muc_open"]', stanza).length,
|
||||||
|
'passwordprotected': sizzle('feature[var="muc_passwordprotected"]', stanza).length,
|
||||||
|
'persistent': sizzle('feature[var="muc_persistent"]', stanza).length,
|
||||||
|
'publicroom': sizzle('feature[var="muc_publicroom"]', stanza).length,
|
||||||
|
'semianonymous': sizzle('feature[var="muc_semianonymous"]', stanza).length,
|
||||||
|
'temporary': sizzle('feature[var="muc_temporary"]', stanza).length,
|
||||||
|
'unmoderated': sizzle('feature[var="muc_unmoderated"]', stanza).length,
|
||||||
|
'label_desc': __('Description:'),
|
||||||
|
'label_jid': __('Room Address (JID):'),
|
||||||
|
'label_occ': __('Occupants:'),
|
||||||
|
'label_features': __('Features:'),
|
||||||
|
'label_requires_auth': __('Requires authentication'),
|
||||||
|
'label_hidden': __('Hidden'),
|
||||||
|
'label_requires_invite': __('Requires an invitation'),
|
||||||
|
'label_moderated': __('Moderated'),
|
||||||
|
'label_non_anon': __('Non-anonymous'),
|
||||||
|
'label_open_room': __('Open room'),
|
||||||
|
'label_permanent_room': __('Permanent room'),
|
||||||
|
'label_public': __('Public'),
|
||||||
|
'label_semi_anon': __('Semi-anonymous'),
|
||||||
|
'label_temp_room': __('Temporary room'),
|
||||||
|
'label_unmoderated': __('Unmoderated')
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleRoomInfo (ev) {
|
||||||
|
/* Show/hide extra information about a room in a listing. */
|
||||||
|
const parent_el = u.ancestor(ev.target, '.room-item'),
|
||||||
|
div_el = parent_el.querySelector('div.room-info');
|
||||||
|
if (div_el) {
|
||||||
|
u.slideIn(div_el).then(u.removeElement)
|
||||||
|
parent_el.querySelector('a.room-info').classList.remove('selected');
|
||||||
|
} else {
|
||||||
|
parent_el.insertAdjacentHTML('beforeend', tpl_spinner());
|
||||||
|
_converse.connection.disco.info(
|
||||||
|
ev.target.getAttribute('data-room-jid'),
|
||||||
|
null,
|
||||||
|
_.partial(insertRoomInfo, parent_el)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_converse.ListChatRoomsModal = Backbone.VDOMView.extend({
|
||||||
|
events: {
|
||||||
|
'submit form': 'showRooms',
|
||||||
|
'click a.room-info': 'toggleRoomInfo',
|
||||||
|
'change input[name=nick]': 'setNick',
|
||||||
|
'change input[name=server]': 'setDomain',
|
||||||
|
'click .open-room': 'openRoom'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize () {
|
||||||
|
this.render().insertIntoDOM();
|
||||||
|
this.modal = new bootstrap.Modal(this.el, {
|
||||||
|
backdrop: 'static',
|
||||||
|
keyboard: true
|
||||||
|
});
|
||||||
|
this.model.on('change:muc_domain', this.onDomainChange, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
toHTML () {
|
||||||
|
return tpl_list_chatrooms_modal(_.extend(this.model.toJSON(), {
|
||||||
|
'heading_list_chatrooms': __('Query for Chatrooms'),
|
||||||
|
'label_server_address': __('Server address'),
|
||||||
|
'label_query': __('Show rooms'),
|
||||||
|
'server_placeholder': __('conference.example.org')
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
insertIntoDOM () {
|
||||||
|
const container_el = _converse.chatboxviews.el.querySelector('#converse-modals');
|
||||||
|
container_el.insertAdjacentElement('beforeEnd', this.el);
|
||||||
|
},
|
||||||
|
|
||||||
|
show () {
|
||||||
|
this.render();
|
||||||
|
this.modal.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
openRoom (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
const jid = ev.target.getAttribute('data-room-jid');
|
||||||
|
this.modal.hide();
|
||||||
|
_converse.api.rooms.open(jid);
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleRoomInfo (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
toggleRoomInfo(ev);
|
||||||
|
},
|
||||||
|
|
||||||
|
onDomainChange (model) {
|
||||||
|
if (_converse.auto_list_rooms) {
|
||||||
|
this.updateRoomsList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
roomStanzaItemToHTMLElement (room) {
|
||||||
|
const name = Strophe.unescapeNode(
|
||||||
|
room.getAttribute('name') ||
|
||||||
|
room.getAttribute('jid')
|
||||||
|
);
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.innerHTML = tpl_room_item({
|
||||||
|
'name': name,
|
||||||
|
'jid': room.getAttribute('jid'),
|
||||||
|
'open_title': __('Click to open this room'),
|
||||||
|
'info_title': __('Show more information on this room')
|
||||||
|
});
|
||||||
|
return div.firstChild;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeSpinner () {
|
||||||
|
_.each(this.el.querySelectorAll('span.spinner'),
|
||||||
|
(el) => el.parentNode.removeChild(el)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
informNoRoomsFound () {
|
||||||
|
const chatrooms_el = this.el.querySelector('.available-chatrooms');
|
||||||
|
chatrooms_el.innerHTML = tpl_rooms_results({
|
||||||
|
'feedback_text': __('No rooms found')
|
||||||
|
});
|
||||||
|
const input_el = this.el.querySelector('input#show-rooms');
|
||||||
|
input_el.classList.remove('hidden')
|
||||||
|
this.removeSpinner();
|
||||||
|
},
|
||||||
|
|
||||||
|
onRoomsFound (iq) {
|
||||||
|
/* Handle the IQ stanza returned from the server, containing
|
||||||
|
* all its public rooms.
|
||||||
|
*/
|
||||||
|
const available_chatrooms = this.el.querySelector('.available-chatrooms');
|
||||||
|
this.rooms = iq.querySelectorAll('query item');
|
||||||
|
if (this.rooms.length) {
|
||||||
|
// For translators: %1$s is a variable and will be
|
||||||
|
// replaced with the XMPP server name
|
||||||
|
available_chatrooms.innerHTML = tpl_rooms_results({
|
||||||
|
'feedback_text': __('Rooms found')
|
||||||
|
});
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
const children = _.reject(_.map(this.rooms, this.roomStanzaItemToHTMLElement), _.isNil)
|
||||||
|
_.each(children, (child) => fragment.appendChild(child));
|
||||||
|
available_chatrooms.appendChild(fragment);
|
||||||
|
this.removeSpinner();
|
||||||
|
} else {
|
||||||
|
this.informNoRoomsFound();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateRoomsList () {
|
||||||
|
/* Send an IQ stanza to the server asking for all rooms
|
||||||
|
*/
|
||||||
|
_converse.connection.sendIQ(
|
||||||
|
$iq({
|
||||||
|
to: this.model.get('muc_domain'),
|
||||||
|
from: _converse.connection.jid,
|
||||||
|
type: "get"
|
||||||
|
}).c("query", {xmlns: Strophe.NS.DISCO_ITEMS}),
|
||||||
|
this.onRoomsFound.bind(this),
|
||||||
|
this.informNoRoomsFound.bind(this),
|
||||||
|
5000
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
showRooms (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
const data = new FormData(ev.target);
|
||||||
|
this.model.save('muc_domain', data.get('server'));
|
||||||
|
this.updateRoomsList();
|
||||||
|
},
|
||||||
|
|
||||||
|
setDomain (ev) {
|
||||||
|
this.model.save({muc_domain: ev.target.value});
|
||||||
|
},
|
||||||
|
|
||||||
|
setNick (ev) {
|
||||||
|
this.model.save({nick: ev.target.value});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
_converse.AddChatRoomModal = Backbone.VDOMView.extend({
|
_converse.AddChatRoomModal = Backbone.VDOMView.extend({
|
||||||
events: {
|
events: {
|
||||||
'submit form.add-chatroom': 'openChatRoom'
|
'submit form.add-chatroom': 'openChatRoom'
|
||||||
@ -161,14 +368,15 @@
|
|||||||
backdrop: 'static',
|
backdrop: 'static',
|
||||||
keyboard: true
|
keyboard: true
|
||||||
});
|
});
|
||||||
this.model.on('change:muc_domain', this.render, this);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
toHTML () {
|
toHTML () {
|
||||||
return tpl_add_chatroom_modal(_.extend(this.model.toJSON(), {
|
return tpl_add_chatroom_modal(_.extend(this.model.toJSON(), {
|
||||||
'heading_new_chatroom': __('Enter a new Chatroom'),
|
'heading_new_chatroom': __('Enter a new Chatroom'),
|
||||||
'label_room_address': __('Room address'),
|
'label_room_address': __('Room address'),
|
||||||
'label_nickname': __('Optional nickname')
|
'label_nickname': __('Optional nickname'),
|
||||||
|
'chatroom_placeholder': __('name@conference.example.org'),
|
||||||
|
'label_join': __('Join'),
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2002,207 +2210,37 @@
|
|||||||
id: 'chatrooms',
|
id: 'chatrooms',
|
||||||
events: {
|
events: {
|
||||||
'click a.chatbox-btn.fa-users': 'showAddRoomModal',
|
'click a.chatbox-btn.fa-users': 'showAddRoomModal',
|
||||||
'change input[name=nick]': 'setNick',
|
'click a.chatbox-btn.fa-list-ul': 'showListRoomsModal',
|
||||||
'change input[name=server]': 'setDomain',
|
'click a.room-info': 'toggleRoomInfo'
|
||||||
'click a.room-info': 'toggleRoomInfo',
|
|
||||||
'click input#show-rooms': 'showRooms',
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize (cfg) {
|
initialize (cfg) {
|
||||||
this.add_room_modal = new _converse.AddChatRoomModal({'model': this.model});
|
this.add_room_modal = new _converse.AddChatRoomModal({'model': this.model});
|
||||||
this.model.on('change:muc_domain', this.onDomainChange, this);
|
this.list_rooms_modal = new _converse.ListChatRoomsModal({'model': this.model});
|
||||||
this.model.on('change:nick', this.onNickChange, this);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
this.el.innerHTML = tpl_room_panel({
|
this.el.innerHTML = tpl_room_panel({
|
||||||
'heading_chatrooms': __('Chatrooms'),
|
'heading_chatrooms': __('Chatrooms'),
|
||||||
'title_new_room': __('Click to add a new room')
|
'title_new_room': __('Add a new room'),
|
||||||
|
'title_list_rooms': __('Query for rooms')
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toggleRoomInfo (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
toggleRoomInfo(ev);
|
||||||
|
},
|
||||||
|
|
||||||
showAddRoomModal (ev) {
|
showAddRoomModal (ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
this.add_room_modal.show();
|
this.add_room_modal.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showListRoomsModal(ev) {
|
||||||
onDomainChange (model) {
|
ev.preventDefault();
|
||||||
if (_converse.auto_list_rooms) {
|
this.list_rooms_modal.show();
|
||||||
this.updateRoomsList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onNickChange (model) {
|
|
||||||
const nick = this.el.querySelector('input.new-chatroom-nick');
|
|
||||||
if (!_.isNull(nick)) {
|
|
||||||
nick.value = model.get('nick');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
removeSpinner () {
|
|
||||||
_.each(this.el.querySelectorAll('span.spinner'),
|
|
||||||
(el) => el.parentNode.removeChild(el)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
informNoRoomsFound () {
|
|
||||||
const chatrooms_el = this.el.querySelector('#available-chatrooms');
|
|
||||||
chatrooms_el.innerHTML = tpl_rooms_results({
|
|
||||||
'feedback_text': __('No rooms found')
|
|
||||||
});
|
|
||||||
const input_el = this.el.querySelector('input#show-rooms');
|
|
||||||
input_el.classList.remove('hidden')
|
|
||||||
this.removeSpinner();
|
|
||||||
},
|
|
||||||
|
|
||||||
roomStanzaItemToHTMLElement (room) {
|
|
||||||
const name = Strophe.unescapeNode(
|
|
||||||
room.getAttribute('name') ||
|
|
||||||
room.getAttribute('jid')
|
|
||||||
);
|
|
||||||
const div = document.createElement('div');
|
|
||||||
div.innerHTML = tpl_room_item({
|
|
||||||
'name': name,
|
|
||||||
'jid': room.getAttribute('jid'),
|
|
||||||
'open_title': __('Click to open this room'),
|
|
||||||
'info_title': __('Show more information on this room')
|
|
||||||
});
|
|
||||||
return div.firstChild;
|
|
||||||
},
|
|
||||||
|
|
||||||
onRoomsFound (iq) {
|
|
||||||
/* Handle the IQ stanza returned from the server, containing
|
|
||||||
* all its public rooms.
|
|
||||||
*/
|
|
||||||
const available_chatrooms = this.el.querySelector('#available-chatrooms');
|
|
||||||
this.rooms = iq.querySelectorAll('query item');
|
|
||||||
if (this.rooms.length) {
|
|
||||||
// For translators: %1$s is a variable and will be
|
|
||||||
// replaced with the XMPP server name
|
|
||||||
available_chatrooms.innerHTML = tpl_rooms_results({
|
|
||||||
'feedback_text': __('Rooms found')
|
|
||||||
});
|
|
||||||
const fragment = document.createDocumentFragment();
|
|
||||||
const children = _.reject(_.map(this.rooms, this.roomStanzaItemToHTMLElement), _.isNil)
|
|
||||||
_.each(children, (child) => fragment.appendChild(child));
|
|
||||||
available_chatrooms.appendChild(fragment);
|
|
||||||
const input_el = this.el.querySelector('input#show-rooms');
|
|
||||||
input_el.classList.remove('hidden')
|
|
||||||
this.removeSpinner();
|
|
||||||
} else {
|
|
||||||
this.informNoRoomsFound();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
updateRoomsList () {
|
|
||||||
/* Send an IQ stanza to the server asking for all rooms
|
|
||||||
*/
|
|
||||||
_converse.connection.sendIQ(
|
|
||||||
$iq({
|
|
||||||
to: this.model.get('muc_domain'),
|
|
||||||
from: _converse.connection.jid,
|
|
||||||
type: "get"
|
|
||||||
}).c("query", {xmlns: Strophe.NS.DISCO_ITEMS}),
|
|
||||||
this.onRoomsFound.bind(this),
|
|
||||||
this.informNoRoomsFound.bind(this),
|
|
||||||
5000
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
showRooms () {
|
|
||||||
const chatrooms_el = this.el.querySelector('#available-chatrooms');
|
|
||||||
const server_el = this.el.querySelector('input.new-chatroom-server');
|
|
||||||
const server = server_el.value;
|
|
||||||
if (!server) {
|
|
||||||
server_el.classList.add('error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.el.querySelector('input.new-chatroom-name').classList.remove('error');
|
|
||||||
server_el.classList.remove('error');
|
|
||||||
chatrooms_el.innerHTML = '';
|
|
||||||
|
|
||||||
const input_el = this.el.querySelector('input#show-rooms');
|
|
||||||
input_el.classList.add('hidden')
|
|
||||||
input_el.insertAdjacentHTML('afterend', tpl_spinner());
|
|
||||||
|
|
||||||
this.model.save({muc_domain: server});
|
|
||||||
this.updateRoomsList();
|
|
||||||
},
|
|
||||||
|
|
||||||
insertRoomInfo (el, stanza) {
|
|
||||||
/* Insert room info (based on returned #disco IQ stanza)
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* (HTMLElement) el: The HTML DOM element that should
|
|
||||||
* contain the info.
|
|
||||||
* (XMLElement) stanza: The IQ stanza containing the room
|
|
||||||
* info.
|
|
||||||
*/
|
|
||||||
// All MUC features found here: http://xmpp.org/registrar/disco-features.html
|
|
||||||
el.querySelector('span.spinner').remove();
|
|
||||||
el.querySelector('a.room-info').classList.add('selected');
|
|
||||||
el.insertAdjacentHTML(
|
|
||||||
'beforeEnd',
|
|
||||||
tpl_room_description({
|
|
||||||
'jid': stanza.getAttribute('from'),
|
|
||||||
'desc': _.get(_.head(sizzle('field[var="muc#roominfo_description"] value', stanza)), 'textContent'),
|
|
||||||
'occ': _.get(_.head(sizzle('field[var="muc#roominfo_occupants"] value', stanza)), 'textContent'),
|
|
||||||
'hidden': sizzle('feature[var="muc_hidden"]', stanza).length,
|
|
||||||
'membersonly': sizzle('feature[var="muc_membersonly"]', stanza).length,
|
|
||||||
'moderated': sizzle('feature[var="muc_moderated"]', stanza).length,
|
|
||||||
'nonanonymous': sizzle('feature[var="muc_nonanonymous"]', stanza).length,
|
|
||||||
'open': sizzle('feature[var="muc_open"]', stanza).length,
|
|
||||||
'passwordprotected': sizzle('feature[var="muc_passwordprotected"]', stanza).length,
|
|
||||||
'persistent': sizzle('feature[var="muc_persistent"]', stanza).length,
|
|
||||||
'publicroom': sizzle('feature[var="muc_publicroom"]', stanza).length,
|
|
||||||
'semianonymous': sizzle('feature[var="muc_semianonymous"]', stanza).length,
|
|
||||||
'temporary': sizzle('feature[var="muc_temporary"]', stanza).length,
|
|
||||||
'unmoderated': sizzle('feature[var="muc_unmoderated"]', stanza).length,
|
|
||||||
'label_desc': __('Description:'),
|
|
||||||
'label_jid': __('Room Address (JID):'),
|
|
||||||
'label_occ': __('Occupants:'),
|
|
||||||
'label_features': __('Features:'),
|
|
||||||
'label_requires_auth': __('Requires authentication'),
|
|
||||||
'label_hidden': __('Hidden'),
|
|
||||||
'label_requires_invite': __('Requires an invitation'),
|
|
||||||
'label_moderated': __('Moderated'),
|
|
||||||
'label_non_anon': __('Non-anonymous'),
|
|
||||||
'label_open_room': __('Open room'),
|
|
||||||
'label_permanent_room': __('Permanent room'),
|
|
||||||
'label_public': __('Public'),
|
|
||||||
'label_semi_anon': __('Semi-anonymous'),
|
|
||||||
'label_temp_room': __('Temporary room'),
|
|
||||||
'label_unmoderated': __('Unmoderated')
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleRoomInfo (ev) {
|
|
||||||
/* Show/hide extra information about a room in the listing.
|
|
||||||
*/
|
|
||||||
const parent_el = u.ancestor(ev.target, '.room-item'),
|
|
||||||
div_el = parent_el.querySelector('div.room-info');
|
|
||||||
if (div_el) {
|
|
||||||
u.slideIn(div_el).then(u.removeElement)
|
|
||||||
parent_el.querySelector('a.room-info').classList.remove('selected');
|
|
||||||
} else {
|
|
||||||
parent_el.insertAdjacentHTML('beforeend', tpl_spinner());
|
|
||||||
_converse.connection.disco.info(
|
|
||||||
ev.target.getAttribute('data-room-jid'),
|
|
||||||
null,
|
|
||||||
_.partial(this.insertRoomInfo, parent_el)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setDomain (ev) {
|
|
||||||
this.model.save({muc_domain: ev.target.value});
|
|
||||||
},
|
|
||||||
|
|
||||||
setNick (ev) {
|
|
||||||
this.model.save({nick: ev.target.value});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11,14 +11,14 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form class="converse-form add-chatroom">
|
<form class="converse-form add-chatroom">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="chatroom">{{{o.label_room_address}}}:</label>
|
<label for="server">{{{o.label_room_address}}}:</label>
|
||||||
<input type="text" required="required" name="chatroom" class="form-control" placeholder="name@conference.example.org">
|
<input type="text" value="{{{o.muc_domain}}}" required="required" name="chatroom" class="form-control" placeholder="{{{o.chatroom_placeholder}}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="chatroom">{{{o.label_nickname}}}:</label>
|
<label for="chatroom">{{{o.label_nickname}}}:</label>
|
||||||
<input type="text" name="nickname" class="form-control">
|
<input type="text" name="nickname" value="{{{o.nick}}}" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<input type="submit" class="btn btn-primary" name="join" value="Join">
|
<input type="submit" class="btn btn-primary" name="join" value="{{{o.label_join}}}">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
23
src/templates/list_chatrooms_modal.html
Normal file
23
src/templates/list_chatrooms_modal.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<div class="modal fade" id="list-chatrooms-modal" tabindex="-1" role="dialog" aria-labelledby="chatroomsModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"
|
||||||
|
id="chatroomsModalLabel">{{{o.heading_list_chatrooms}}}</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form class="converse-form add-chatroom">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="chatroom">{{{o.label_server_address}}}:</label>
|
||||||
|
<input type="text" value="{{{o.muc_domain}}}" required="required" name="server" class="form-control" placeholder="{{{o.server_placeholder}}}">
|
||||||
|
</div>
|
||||||
|
<input type="submit" class="btn btn-primary" name="join" value="{{{o.label_query}}}">
|
||||||
|
</form>
|
||||||
|
<ul class="available-chatrooms list-group"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,6 +1,6 @@
|
|||||||
<div class="room-item">
|
<li class="room-item list-group-item">
|
||||||
<div class="available-chatroom d-flex flex-row">
|
<div class="available-chatroom d-flex flex-row">
|
||||||
<a class="open-room available-room"
|
<a class="open-room available-room w-100"
|
||||||
data-room-jid="{{{o.jid}}}"
|
data-room-jid="{{{o.jid}}}"
|
||||||
title="{{{o.open_title}}}"
|
title="{{{o.open_title}}}"
|
||||||
href="#">{{{o.name}}}</a>
|
href="#">{{{o.name}}}</a>
|
||||||
@ -8,4 +8,4 @@
|
|||||||
data-room-jid="{{{o.jid}}}"
|
data-room-jid="{{{o.jid}}}"
|
||||||
title="{{{o.info_title}}}" href="#"> </a>
|
title="{{{o.info_title}}}" href="#"> </a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<!-- <div id="chatrooms"> -->
|
<!-- <div id="chatrooms"> -->
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<span class="w-100">{{{o.heading_chatrooms}}}</span>
|
<span class="w-100">{{{o.heading_chatrooms}}}</span>
|
||||||
|
<a class="chatbox-btn fa fa-list-ul" title="{{{o.title_list_rooms}}}" data-toggle="modal" data-target="#list-chatrooms-modal"></a>
|
||||||
<a class="chatbox-btn fa fa-users" title="{{{o.title_new_room}}}" data-toggle="modal" data-target="#chatroomsModal"></a>
|
<a class="chatbox-btn fa fa-users" title="{{{o.title_new_room}}}" data-toggle="modal" data-target="#chatroomsModal"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-container open-rooms-list rooms-list-container"></div>
|
<div class="list-container open-rooms-list rooms-list-container"></div>
|
||||||
|
@ -1 +1 @@
|
|||||||
<dt class="centered">{{{ o.feedback_text }}}</dt>
|
<li class="list-group-item active">{{{ o.feedback_text }}}:</dt>
|
||||||
|
Loading…
Reference in New Issue
Block a user