Commit 910e9bdd authored by JC Brand's avatar JC Brand

Refactoring in MUC

What started as an attempt to fix a bug in parseXUserElement, turned into
another large refactoring of MUC code, and it's not clear how to break this up
into multiple atomic commits. So I'm just pushing it all.

At least there are two new tests added to the suite.
parent 8bbd88ba
...@@ -135,7 +135,9 @@ require.config({ ...@@ -135,7 +135,9 @@ require.config({
"chatbox_minimize": "src/templates/chatbox_minimize", "chatbox_minimize": "src/templates/chatbox_minimize",
"chatroom": "src/templates/chatroom", "chatroom": "src/templates/chatroom",
"chatroom_bookmark_form": "src/templates/chatroom_bookmark_form", "chatroom_bookmark_form": "src/templates/chatroom_bookmark_form",
"chatroom_bookmark_toggle": "src/templates/chatroom_bookmark_toggle",
"chatroom_form": "src/templates/chatroom_form", "chatroom_form": "src/templates/chatroom_form",
"chatroom_head": "src/templates/chatroom_head",
"chatroom_nickname_form": "src/templates/chatroom_nickname_form", "chatroom_nickname_form": "src/templates/chatroom_nickname_form",
"chatroom_password_form": "src/templates/chatroom_password_form", "chatroom_password_form": "src/templates/chatroom_password_form",
"chatroom_sidebar": "src/templates/chatroom_sidebar", "chatroom_sidebar": "src/templates/chatroom_sidebar",
...@@ -147,6 +149,7 @@ require.config({ ...@@ -147,6 +149,7 @@ require.config({
"contacts_tab": "src/templates/contacts_tab", "contacts_tab": "src/templates/contacts_tab",
"controlbox": "src/templates/controlbox", "controlbox": "src/templates/controlbox",
"controlbox_toggle": "src/templates/controlbox_toggle", "controlbox_toggle": "src/templates/controlbox_toggle",
"dragresize": "src/templates/dragresize",
"field": "src/templates/field", "field": "src/templates/field",
"form_captcha": "src/templates/form_captcha", "form_captcha": "src/templates/form_captcha",
"form_checkbox": "src/templates/form_checkbox", "form_checkbox": "src/templates/form_checkbox",
......
...@@ -155,6 +155,36 @@ ...@@ -155,6 +155,36 @@
expect(view instanceof converse.ChatRoomView).toBe(true); expect(view instanceof converse.ChatRoomView).toBe(true);
})); }));
it("can be configured if you're its owner", mock.initConverse(function (converse) {
converse_api.rooms.open('room@conference.example.org', {'nick': 'some1'});
var view = converse.chatboxviews.get('room@conference.example.org');
spyOn(view, 'showConfigureButtonIfRoomOwner').andCallThrough();
/* <presence to="dummy@localhost/converse.js-29092160"
* from="room@conference.example.org/some1">
* <x xmlns="http://jabber.org/protocol/muc#user">
* <item affiliation="owner" jid="dummy@localhost/converse.js-29092160" role="moderator"/>
* <status code="110"/>
* </x>
* </presence></body>
*/
var presence = $pres({
to: 'dummy@localhost/converse.js-29092160',
from: 'room@conference.example.org/some1'
}).c('x', {xmlns: Strophe.NS.MUC_USER})
.c('item', {
'affiliation': 'owner',
'jid': 'dummy@localhost/converse.js-29092160',
'role': 'moderator'
}).up()
.c('status', {code: '110'});
converse.connection._dataRecv(test_utils.createRequest(presence));
expect(view.showConfigureButtonIfRoomOwner).toHaveBeenCalled();
expect(view.$('.configure-chatroom-button').is(':visible')).toBeTruthy();
expect(view.$('.toggle-chatbox-button').is(':visible')).toBeTruthy();
expect(view.$('.toggle-bookmark').is(':visible')).toBeTruthy();
}));
it("shows users currently present in the room", mock.initConverse(function (converse) { it("shows users currently present in the room", mock.initConverse(function (converse) {
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy');
var name; var name;
...@@ -575,6 +605,43 @@ ...@@ -575,6 +605,43 @@
expect($occupants.children().first(0).text()).toBe("newnick"); expect($occupants.children().first(0).text()).toBe("newnick");
})); }));
it("indicates when a room is no longer anonymous", mock.initConverse(function (converse) {
converse_api.rooms.open('room@conference.example.org', {
'nick': 'some1',
'roomconfig': {
'changesubject': false,
'membersonly': true,
'persistentroom': true,
'publicroom': true,
'roomdesc': 'Welcome to this room',
'whois': 'anyone'
}
});
/* <message xmlns="jabber:client"
* type="groupchat"
* to="dummy@localhost/converse.js-27854181"
* from="room@conference.example.org">
* <x xmlns="http://jabber.org/protocol/muc#user">
* <status code="104"/>
* <status code="172"/>
* </x>
* </message>
*/
var message = $msg({
type:'groupchat',
to: 'dummy@localhost/converse.js-27854181',
from: 'room@conference.example.org'
}).c('x', {xmlns: Strophe.NS.MUC_USER})
.c('status', {code: '104'}).up()
.c('status', {code: '172'});
converse.connection._dataRecv(test_utils.createRequest(message));
var view = converse.chatboxviews.get('room@conference.example.org');
var $chat_body = view.$('.chatroom-body');
expect($chat_body.html().trim().indexOf(
'<div class="chat-info">This room is now no longer anonymous</div>'
)).not.toBe(-1);
}));
it("informs users if they have been kicked out of the chat room", mock.initConverse(function (converse) { it("informs users if they have been kicked out of the chat room", mock.initConverse(function (converse) {
/* <presence /* <presence
* from='harfleur@chat.shakespeare.lit/pistol' * from='harfleur@chat.shakespeare.lit/pistol'
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
"converse-api", "converse-api",
"converse-muc", "converse-muc",
"tpl!chatroom_bookmark_form", "tpl!chatroom_bookmark_form",
"tpl!chatroom_bookmark_toggle",
"tpl!bookmark", "tpl!bookmark",
"tpl!bookmarks_list" "tpl!bookmarks_list"
], ],
...@@ -28,6 +29,7 @@ ...@@ -28,6 +29,7 @@
$, _, moment, strophe, utils, $, _, moment, strophe, utils,
converse, converse_api, muc, converse, converse_api, muc,
tpl_chatroom_bookmark_form, tpl_chatroom_bookmark_form,
tpl_chatroom_bookmark_toggle,
tpl_bookmark, tpl_bookmark,
tpl_bookmarks_list tpl_bookmarks_list
) { ) {
...@@ -40,6 +42,7 @@ ...@@ -40,6 +42,7 @@
// Add new HTML templates. // Add new HTML templates.
converse.templates.chatroom_bookmark_form = tpl_chatroom_bookmark_form; converse.templates.chatroom_bookmark_form = tpl_chatroom_bookmark_form;
converse.templates.chatroom_bookmark_toggle = tpl_chatroom_bookmark_toggle;
converse.templates.bookmark = tpl_bookmark; converse.templates.bookmark = tpl_bookmark;
converse.templates.bookmarks_list = tpl_bookmarks_list; converse.templates.bookmarks_list = tpl_bookmarks_list;
...@@ -69,16 +72,24 @@ ...@@ -69,16 +72,24 @@
this.setBookmarkState(); this.setBookmarkState();
}, },
render: function (options) { generateHeadingHTML: function () {
this.__super__.render.apply(this, arguments); var html = this.__super__.generateHeadingHTML.apply(this, arguments);
if (converse.allow_bookmarks) { if (converse.allow_bookmarks) {
var label_bookmark = _('Bookmark this room'); var div = document.createElement('div');
var button = '<a class="chatbox-btn toggle-bookmark icon-pushpin '+ div.innerHTML = html;
(this.model.get('bookmarked') ? 'button-on"' : '"') + var bookmark_button = converse.templates.chatroom_bookmark_toggle(
'title="'+label_bookmark+'"></a>'; _.extend(
this.$el.find('.chat-head-chatroom .icon-wrench').before(button); this.model.toJSON(),
{
info_toggle_bookmark: __('Bookmark this room'),
bookmarked: this.model.get('bookmarked')
}
));
var close_button = div.querySelector('.close-chatbox-button');
close_button.insertAdjacentHTML('afterend', bookmark_button);
return div.innerHTML;
} }
return this; return html;
}, },
checkForReservedNick: function () { checkForReservedNick: function () {
......
...@@ -10,14 +10,16 @@ ...@@ -10,14 +10,16 @@
define("converse-dragresize", [ define("converse-dragresize", [
"converse-core", "converse-core",
"converse-api", "converse-api",
"tpl!dragresize",
"converse-chatview", "converse-chatview",
"converse-muc", // XXX: would like to remove this "converse-muc", // XXX: would like to remove this
"converse-controlbox" "converse-controlbox"
], factory); ], factory);
}(this, function (converse, converse_api) { }(this, function (converse, converse_api, tpl_dragresize) {
"use strict"; "use strict";
var $ = converse_api.env.jQuery, var $ = converse_api.env.jQuery,
_ = converse_api.env._; _ = converse_api.env._;
converse.templates.dragresize = tpl_dragresize;
converse_api.plugins.add('converse-dragresize', { converse_api.plugins.add('converse-dragresize', {
...@@ -260,13 +262,23 @@ ...@@ -260,13 +262,23 @@
render: function () { render: function () {
var result = this.__super__.render.apply(this, arguments); var result = this.__super__.render.apply(this, arguments);
this.renderDragResizeHandles();
this.setWidth(); this.setWidth();
return result; return result;
},
renderDragResizeHandles: function () {
var flyout = this.el.querySelector('.box-flyout');
var div = document.createElement('div');
div.innerHTML = converse.templates.dragresize();
flyout.insertBefore(
div.firstChild,
flyout.firstChild
);
} }
} }
}, },
initialize: function () { initialize: function () {
/* The initialize function gets called as soon as the plugin is /* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery. * loaded by converse.js's plugin machinery.
......
...@@ -98,7 +98,6 @@ ...@@ -98,7 +98,6 @@
title: this.model.get('fullname'), title: this.model.get('fullname'),
unread_msgs: __('You have unread messages'), unread_msgs: __('You have unread messages'),
info_close: __('Close this box'), info_close: __('Close this box'),
info_minimize: __('Minimize this box'),
label_personal_message: '' label_personal_message: ''
} }
) )
......
...@@ -181,6 +181,18 @@ ...@@ -181,6 +181,18 @@
this.hide(); this.hide();
} }
return result; return result;
},
generateHeadingHTML: function () {
var html = this.__super__.generateHeadingHTML.apply(this, arguments);
var div = document.createElement('div');
div.innerHTML = html;
var el = converse.templates.chatbox_minimize(
{info_minimize: __('Minimize this chat box')}
);
var button = div.querySelector('.close-chatbox-button');
button.insertAdjacentHTML('afterend', el);
return div.innerHTML;
} }
}, },
...@@ -497,7 +509,7 @@ ...@@ -497,7 +509,7 @@
// Inserts a "minimize" button in the chatview's header // Inserts a "minimize" button in the chatview's header
var $el = view.$el.find('.toggle-chatbox-button'); var $el = view.$el.find('.toggle-chatbox-button');
var $new_el = converse.templates.chatbox_minimize( var $new_el = converse.templates.chatbox_minimize(
_.extend({info_minimize: __('Minimize this chat box')}) {info_minimize: __('Minimize this chat box')}
); );
if ($el.length) { if ($el.length) {
$el.replaceWith($new_el); $el.replaceWith($new_el);
...@@ -506,7 +518,6 @@ ...@@ -506,7 +518,6 @@
} }
}; };
converse.on('chatBoxOpened', renderMinimizeButton); converse.on('chatBoxOpened', renderMinimizeButton);
converse.on('chatRoomOpened', renderMinimizeButton);
converse.on('controlBoxOpened', function (evt, chatbox) { converse.on('controlBoxOpened', function (evt, chatbox) {
// Wrapped in anon method because at scan time, chatboxviews // Wrapped in anon method because at scan time, chatboxviews
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
"tpl!chatroom_password_form", "tpl!chatroom_password_form",
"tpl!chatroom_sidebar", "tpl!chatroom_sidebar",
"tpl!chatroom_toolbar", "tpl!chatroom_toolbar",
"tpl!chatroom_head",
"tpl!chatrooms_tab", "tpl!chatrooms_tab",
"tpl!info", "tpl!info",
"tpl!occupant", "tpl!occupant",
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
tpl_chatroom_password_form, tpl_chatroom_password_form,
tpl_chatroom_sidebar, tpl_chatroom_sidebar,
tpl_chatroom_toolbar, tpl_chatroom_toolbar,
tpl_chatroom_head,
tpl_chatrooms_tab, tpl_chatrooms_tab,
tpl_info, tpl_info,
tpl_occupant, tpl_occupant,
...@@ -53,6 +55,7 @@ ...@@ -53,6 +55,7 @@
converse.templates.chatroom_nickname_form = tpl_chatroom_nickname_form; converse.templates.chatroom_nickname_form = tpl_chatroom_nickname_form;
converse.templates.chatroom_password_form = tpl_chatroom_password_form; converse.templates.chatroom_password_form = tpl_chatroom_password_form;
converse.templates.chatroom_sidebar = tpl_chatroom_sidebar; converse.templates.chatroom_sidebar = tpl_chatroom_sidebar;
converse.templates.chatroom_head = tpl_chatroom_head;
converse.templates.chatrooms_tab = tpl_chatrooms_tab; converse.templates.chatrooms_tab = tpl_chatrooms_tab;
converse.templates.info = tpl_info; converse.templates.info = tpl_info;
converse.templates.occupant = tpl_occupant; converse.templates.occupant = tpl_occupant;
...@@ -109,7 +112,7 @@ ...@@ -109,7 +112,7 @@
104: __('Non-privacy-related room configuration has changed'), 104: __('Non-privacy-related room configuration has changed'),
170: __('Room logging is now enabled'), 170: __('Room logging is now enabled'),
171: __('Room logging is now disabled'), 171: __('Room logging is now disabled'),
172: __('This room is now non-anonymous'), 172: __('This room is now no longer anonymous'),
173: __('This room is now semi-anonymous'), 173: __('This room is now semi-anonymous'),
174: __('This room is now fully-anonymous'), 174: __('This room is now fully-anonymous'),
201: __('A new room has been created') 201: __('A new room has been created')
...@@ -293,6 +296,14 @@ ...@@ -293,6 +296,14 @@
}, },
}); });
converse.createChatRoom = function (settings) {
return converse.chatboxviews.showChat(
_.extend(settings, {
'type': 'chatroom',
'affiliation': undefined
})
);
};
converse.ChatRoomView = converse.ChatBoxView.extend({ converse.ChatRoomView = converse.ChatBoxView.extend({
/* Backbone View which renders a chat room, based upon the view /* Backbone View which renders a chat room, based upon the view
...@@ -320,6 +331,8 @@ ...@@ -320,6 +331,8 @@
this.model.on('show', this.show, this); this.model.on('show', this.show, this);
this.model.on('destroy', this.hide, this); this.model.on('destroy', this.hide, this);
this.model.on('change:chat_state', this.sendChatState, this); this.model.on('change:chat_state', this.sendChatState, this);
this.model.on('change:affiliation', this.renderHeading, this);
this.model.on('change:name', this.renderHeading, this);
this.occupantsview = new converse.ChatRoomOccupantsView({ this.occupantsview = new converse.ChatRoomOccupantsView({
model: new converse.ChatRoomOccupants({nick: this.model.get('nick')}) model: new converse.ChatRoomOccupants({nick: this.model.get('nick')})
...@@ -358,16 +371,25 @@ ...@@ -358,16 +371,25 @@
render: function () { render: function () {
this.$el.attr('id', this.model.get('box_id')) this.$el.attr('id', this.model.get('box_id'))
.html(converse.templates.chatroom( .html(converse.templates.chatroom());
_.extend(this.model.toJSON(), { this.renderHeading();
info_close: __('Close and leave this room'),
info_configure: __('Configure this room'),
})));
this.renderChatArea(); this.renderChatArea();
utils.refreshWebkit(); utils.refreshWebkit();
return this; return this;
}, },
generateHeadingHTML: function () {
return converse.templates.chatroom_head(
_.extend(this.model.toJSON(), {
info_close: __('Close and leave this room'),
info_configure: __('Configure this room'),
}));
},
renderHeading: function () {
this.el.querySelector('.chat-head-chatroom').innerHTML = this.generateHeadingHTML();
},
renderChatArea: function () { renderChatArea: function () {
if (!this.$('.chat-area').length) { if (!this.$('.chat-area').length) {
this.$('.chatroom-body').empty() this.$('.chatroom-body').empty()
...@@ -1044,13 +1066,25 @@ ...@@ -1044,13 +1066,25 @@
this.$('.chatroom-body').append($('<p>'+msg+'</p>')); this.$('.chatroom-body').append($('<p>'+msg+'</p>'));
}, },
getMessageFromStatus: function (stat, is_self, from_nick, item) { getMessageFromStatus: function (stat, stanza, is_self) {
var code = stat.getAttribute('code'); /* Parameters:
* (XMLElement) stat: A <status> element.
* (Boolean) is_self: Whether the element refers to the
* current user.
* (XMLElement) stanza: The original stanza received.
*/
var code = stat.getAttribute('code'),
from_nick;
if (is_self && code === "210") { if (is_self && code === "210") {
from_nick = Strophe.unescapeNode(Strophe.getResourceFromJid(stanza.getAttribute('from')));
return __(converse.muc.new_nickname_messages[code], from_nick); return __(converse.muc.new_nickname_messages[code], from_nick);
} else if (is_self && code === "303") { } else if (is_self && code === "303") {
return __(converse.muc.new_nickname_messages[code], item.getAttribute('nick')); return __(
converse.muc.new_nickname_messages[code],
stanza.querySelector('x item').getAttribute('nick')
);
} else if (!is_self && (code in converse.muc.action_info_messages)) { } else if (!is_self && (code in converse.muc.action_info_messages)) {
from_nick = Strophe.unescapeNode(Strophe.getResourceFromJid(stanza.getAttribute('from')));
return __(converse.muc.action_info_messages[code], from_nick); return __(converse.muc.action_info_messages[code], from_nick);
} else if (code in converse.muc.info_messages) { } else if (code in converse.muc.info_messages) {
return converse.muc.info_messages[code]; return converse.muc.info_messages[code];
...@@ -1063,37 +1097,42 @@ ...@@ -1063,37 +1097,42 @@
return; return;
}, },
parseXUserElement: function (x, is_self, from_nick) { showConfigureButtonIfRoomOwner: function (pres) {
/* Parse the passed-in <x xmlns='http://jabber.org/protocol/muc#user'> /* Show the configure button if the user is the room owner.
* element and construct a map containing relevant *
* information. * Parameters:
* (XMLElement) pres: A <presence> stanza.
*/ */
// By using querySelector, we assume here there is one // XXX: For some inexplicable reason, the following line of
// <item> per <x xmlns='http://jabber.org/protocol/muc#user'> // code works in tests, but not with live data, even though
// element. This appears to be a safe assumption, since // the passed in stanza looks exactly the same to me:
// each <x/> element pertains to a single user. // var item = pres.querySelector('x[xmlns="'+Strophe.NS.MUC_USER+'"] item');
var item = x.querySelector('item'); // If we want to eventually get rid of jQuery altogether,
// Show the configure button if user is the room owner. // then the Sizzle selector library might still be needed
// here.
var item = $(pres).find('x[xmlns="'+Strophe.NS.MUC_USER+'"] item').get(0);
if (_.isUndefined(item)) {
return;
}
var jid = item.getAttribute('jid'); var jid = item.getAttribute('jid');
var affiliation = item.getAttribute('affiliation'); var affiliation = item.getAttribute('affiliation');
if (Strophe.getBareJidFromJid(jid) === converse.bare_jid && affiliation === 'owner') { if (Strophe.getBareJidFromJid(jid) === converse.bare_jid && affiliation) {
this.$el.find('a.configure-chatroom-button').show(); this.model.save({'affiliation': affiliation});
} }
// Extract notification messages, reasons and },
// disconnection messages from the <x/> node.
parseXUserElement: function (x, stanza, is_self) {
/* Parse the passed-in <x xmlns='http://jabber.org/protocol/muc#user'>
* element and construct a map containing relevant
* information.
*/
// 1. Get notification messages based on the <status> elements.
var statuses = x.querySelectorAll('status'); var statuses = x.querySelectorAll('status');
var mapper = _.partial(this.getMessageFromStatus, _, is_self, from_nick, item); var mapper = _.partial(this.getMessageFromStatus, _, stanza, is_self);
var notification = { var notification = {
'messages': _.reject(_.map(statuses, mapper), _.isUndefined), 'messages': _.reject(_.map(statuses, mapper), _.isUndefined),
}; };
var reason = item.querySelector('reason'); // 2. Get disconnection messages based on the <status> elements
if (reason) {
notification.reason = reason ? reason.textContent : undefined;
}
var actor = item.querySelector('actor');
if (actor) {
notification.actor = actor ? actor.getAttribute('nick') : undefined;
}
var codes = _.map(statuses, function (stat) { return stat.getAttribute('code'); }); var codes = _.map(statuses, function (stat) { return stat.getAttribute('code'); });
var disconnection_codes = _.intersection(codes, _.keys(converse.muc.disconnect_messages)); var disconnection_codes = _.intersection(codes, _.keys(converse.muc.disconnect_messages));
var disconnected = is_self && disconnection_codes.length > 0; var disconnected = is_self && disconnection_codes.length > 0;
...@@ -1101,6 +1140,22 @@ ...@@ -1101,6 +1140,22 @@
notification.disconnected = true; notification.disconnected = true;
notification.disconnection_message = converse.muc.disconnect_messages[disconnection_codes[0]]; notification.disconnection_message = converse.muc.disconnect_messages[disconnection_codes[0]];
} }
// 3. Find the reason and actor from the <item> element
var item = x.querySelector('item');
// By using querySelector above, we assume here there is
// one <item> per <x xmlns='http://jabber.org/protocol/muc#user'>
// element. This appears to be a safe assumption, since
// each <x/> element pertains to a single user.
if (!_.isNull(item)) {
var reason = item.querySelector('reason');
if (reason) {
notification.reason = reason ? reason.textContent : undefined;
}
var actor = item.querySelector('actor');
if (actor) {
notification.actor = actor ? actor.getAttribute('nick') : undefined;
}
}
return notification; return notification;
}, },
...@@ -1132,22 +1187,18 @@ ...@@ -1132,22 +1187,18 @@
} }
}, },
showStatusMessages: function (presence, is_self) { showStatusMessages: function (stanza, is_self) {
/* Check for status codes and communicate their purpose to the user. /* Check for status codes and communicate their purpose to the user.
* Allows user to configure chat room if they are the owner. * Allows user to configure chat room if they are the owner.
* See: http://xmpp.org/registrar/mucstatus.html * See: http://xmpp.org/registrar/mucstatus.html
*/ */
var from_nick = Strophe.unescapeNode(Strophe.getResourceFromJid(presence.getAttribute('from'))); var elements = stanza.querySelectorAll('x[xmlns="'+Strophe.NS.MUC_USER+'"]');
// XXX: Unfortunately presence.querySelectorAll('x[xmlns="'+Strophe.NS.MUC_USER+'"]') returns []
var elements = _.filter(presence.querySelectorAll('x'), function (x) {
return x.getAttribute('xmlns') === Strophe.NS.MUC_USER;
});
var notifications = _.map( var notifications = _.map(
elements, elements,
_.partial(this.parseXUserElement.bind(this), _, is_self, from_nick) _.partial(this.parseXUserElement.bind(this), _, stanza, is_self)
); );
_.each(notifications, this.displayNotificationsforUser.bind(this)); _.each(notifications, this.displayNotificationsforUser.bind(this));
return presence; return stanza;
}, },
showErrorMessage: function (presence) { showErrorMessage: function (presence) {
...@@ -1221,6 +1272,7 @@ ...@@ -1221,6 +1272,7 @@
this.configureChatRoom(); this.configureChatRoom();
} else { } else {
this.hideSpinner().showStatusMessages(pres, is_self); this.hideSpinner().showStatusMessages(pres, is_self);
this.showConfigureButtonIfRoomOwner(pres);
} }
} }
} }
...@@ -1702,7 +1754,7 @@ ...@@ -1702,7 +1754,7 @@
return; return;
} }
} }
converse.chatboxviews.showChat({ converse.createChatRoom({
'id': jid, 'id': jid,
'jid': jid, 'jid': jid,
'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)), 'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
...@@ -1750,7 +1802,7 @@ ...@@ -1750,7 +1802,7 @@
} }
} }
if (result === true) { if (result === true) {
var chatroom = converse.chatboxviews.showChat({ var chatroom = converse.createChatRoom({
'id': room_jid, 'id': room_jid,
'jid': room_jid, 'jid': room_jid,
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(room_jid)), 'name': Strophe.unescapeNode(Strophe.getNodeFromJid(room_jid)),
...@@ -1837,16 +1889,15 @@ ...@@ -1837,16 +1889,15 @@
if (_.isUndefined(attrs.maximize)) { if (_.isUndefined(attrs.maximize)) {
attrs.maximize = false; attrs.maximize = false;
} }
var fetcher = converse.chatboxviews.showChat.bind(converse.chatboxviews);
if (!attrs.nick && converse.muc_nickname_from_jid) { if (!attrs.nick && converse.muc_nickname_from_jid) {
attrs.nick = Strophe.getNodeFromJid(converse.bare_jid); attrs.nick = Strophe.getNodeFromJid(converse.bare_jid);
} }
if (typeof jids === "undefined") { if (typeof jids === "undefined") {
throw new TypeError('rooms.open: You need to provide at least one JID'); throw new TypeError('rooms.open: You need to provide at least one JID');
} else if (typeof jids === "string") { } else if (typeof jids === "string") {
return _transform(jids, attrs, fetcher); return _transform(jids, attrs, converse.createChatRoom);
} }
return _.map(jids, _.partial(_transform, _, attrs, fetcher)); return _.map(jids, _.partial(_transform, _, attrs, converse.createChatRoom));
}, },
'get': function (jids, attrs, create) { 'get': function (jids, attrs, create) {
if (typeof attrs === "string") { if (typeof attrs === "string") {
......
<div class="flyout box-flyout"> <div class="flyout box-flyout">
<div class="dragresize dragresize-top"></div> <div class="chat-head chat-head-chatroom"></div>
<div class="dragresize dragresize-topleft"></div>
<div class="dragresize dragresize-left"></div>
<div class="chat-head chat-head-chatroom">
<a class="chatbox-btn close-chatbox-button icon-close" title="{{info_close}}"></a>
<a class="chatbox-btn configure-chatroom-button icon-wrench" title="{{info_configure}} "style="display:none"></a>
<div class="chat-title">
{{ _.escape(name) }}
<p class="chatroom-topic"><p/>
</div>
</div>
<div class="chat-body chatroom-body"><span class="spinner centered"/></div> <div class="chat-body chatroom-body"><span class="spinner centered"/></div>
</div> </div>
<a class="chatbox-btn toggle-bookmark icon-pushpin
{[ if (bookmarked) {]}
button-on
{[ } ]}" title="{{info_toggle_bookmark}}"></a>
<div class="dragresize dragresize-top"></div>
<div class="dragresize dragresize-topleft"></div>
<div class="dragresize dragresize-left"></div>
<a class="chatbox-btn close-chatbox-button icon-close" title="{{info_close}}"></a>
{[ if (affiliation == 'owner') { ]}
<a class="chatbox-btn configure-chatroom-button icon-wrench" title="{{info_configure}} "></a>
{[ } ]}
<div class="chat-title">
{{ _.escape(name) }}
<p class="chatroom-topic"><p/>
</div>
<div class="dragresize dragresize-top"></div>
<div class="dragresize dragresize-topleft"></div>
<div class="dragresize dragresize-left"></div>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment