Tricky refactoring.

Removed `_converse.chatboxviews.showChat` and trying to simplify how
chats are created and when they're shown.

Prompted by the work to split the MUC views into a separate plugin
This commit is contained in:
JC Brand 2018-02-21 22:40:51 +01:00
parent d1d43edf52
commit 47aad31899
12 changed files with 165 additions and 2644 deletions

View File

@ -135,6 +135,8 @@ require.config({
// define module dependencies for modules not using define
shim: {
'backbone.overview': { deps: ['backbone.nativeview'] },
'backbone.orderedlistview': { deps: ['backbone.nativeview'] },
'awesomplete': { exports: 'Awesomplete'},
'emojione': { exports: 'emojione'},
'xss': {

View File

@ -269,7 +269,7 @@
openBookmarkedRoom (bookmark) {
if (bookmark.get('autojoin')) {
_converse.api.rooms.open(bookmark.get('jid'), bookmark.get('nick'));
_converse.api.rooms.create(bookmark.get('jid'), bookmark.get('nick'));
}
return bookmark;
},

View File

@ -95,11 +95,13 @@
_converse.ChatBox = Backbone.Model.extend({
defaults: {
'type': 'chatbox',
'show_avatar': true,
'bookmarked': false,
'chat_state': undefined,
'image': _converse.DEFAULT_IMAGE,
'image_type': _converse.DEFAULT_IMAGE_TYPE,
'num_unread': 0,
'show_avatar': true,
'type': 'chatbox',
'url': ''
},
@ -244,11 +246,7 @@
},
onChatBoxesFetched (collection) {
/* Show chat boxes upon receiving them from sessionStorage
*
* This method gets overridden entirely in src/converse-controlbox.js
* if the controlbox plugin is active.
*/
/* Show chat boxes upon receiving them from sessionStorage */
collection.each((chatbox) => {
if (this.chatBoxMayBeShown(chatbox)) {
chatbox.trigger('show');
@ -344,8 +342,8 @@
resource = from_resource;
}
// Get chat box, but only create a new one when the message has a body.
const chatbox = this.getChatBox(contact_jid, !_.isNull(message.querySelector('body'))),
msgid = message.getAttribute('id');
const chatbox = this.getChatBox(contact_jid, {}, !_.isNull(message.querySelector('body'))),
msgid = message.getAttribute('id');
if (chatbox) {
const messages = msgid && chatbox.messages.findWhere({msgid}) || [];
@ -360,54 +358,30 @@
return true;
},
createChatBox (jid, attrs) {
/* Creates a chat box
*
* Parameters:
* (String) jid - The JID of the user for whom a chat box
* gets created.
* (Object) attrs - Optional chat box atributes.
*/
const bare_jid = Strophe.getBareJidFromJid(jid),
roster_item = _converse.roster.get(bare_jid);
let roster_info = {};
if (! _.isUndefined(roster_item)) {
roster_info = {
'fullname': _.isEmpty(roster_item.get('fullname'))? jid: roster_item.get('fullname'),
'image_type': roster_item.get('image_type'),
'image': roster_item.get('image'),
'url': roster_item.get('url'),
};
} else if (!_converse.allow_non_roster_messaging) {
_converse.log(`Could not get roster item for JID ${bare_jid}`+
' and allow_non_roster_messaging is set to false',
Strophe.LogLevel.ERROR);
return;
}
return this.create(_.assignIn({
'id': bare_jid,
'jid': bare_jid,
'fullname': jid,
'image_type': _converse.DEFAULT_IMAGE_TYPE,
'image': _converse.DEFAULT_IMAGE,
'url': '',
}, roster_info, attrs || {}));
},
getChatBox (jid, create, attrs) {
getChatBox (jid, attrs={}, create) {
/* Returns a chat box or optionally return a newly
* created one if one doesn't exist.
*
* Parameters:
* (String) jid - The JID of the user whose chat box we want
* (Boolean) create - Should a new chat box be created if none exists?
* (Object) attrs - Optional chat box atributes.
*/
* created one if one doesn't exist.
*
* Parameters:
* (String) jid - The JID of the user whose chat box we want
* (Boolean) create - Should a new chat box be created if none exists?
* (Object) attrs - Optional chat box atributes.
*/
if (_.isObject(jid)) {
create = attrs;
attrs = jid;
jid = attrs.jid;
} else {
attrs.jid = jid;
}
jid = jid.toLowerCase();
let chatbox = this.get(Strophe.getBareJidFromJid(jid));
if (!chatbox && create) {
chatbox = this.createChatBox(jid, attrs);
chatbox = this.create(attrs, {
'error' (model, response) {
_converse.log(response.responseText);
}
});
}
return chatbox;
}
@ -449,7 +423,12 @@
},
render () {
this.el.innerHTML = tpl_chatboxes();
try {
this.el.innerHTML = tpl_chatboxes();
} catch (e) {
this._ensureElement();
this.el.innerHTML = tpl_chatboxes();
}
this.row_el = this.el.querySelector('.row');
},
@ -481,29 +460,6 @@
chatBoxMayBeShown (chatbox) {
return this.model.chatBoxMayBeShown(chatbox);
},
getChatBox (attrs, create) {
let chatbox = this.model.get(attrs.jid);
if (!chatbox && create) {
chatbox = this.model.create(attrs, {
'error' (model, response) {
_converse.log(response.responseText);
}
});
}
return chatbox;
},
showChat (attrs) {
/* Find the chat box and show it (if it may be shown).
* If it doesn't exist, create it.
*/
const chatbox = this.getChatBox(attrs, true);
if (this.chatBoxMayBeShown(chatbox)) {
chatbox.trigger('show', true);
}
return chatbox;
}
});
@ -575,6 +531,7 @@
}
}
});
/************************ END API ************************/
}
});
return converse;

View File

@ -737,10 +737,6 @@
return message;
},
shouldShowOnTextMessage () {
return !u.isVisible(this.el);
},
handleTextMessage (message) {
this.showMessage(_.clone(message.attributes));
if (u.isNewMessage(message)) {
@ -754,11 +750,7 @@
this.showNewMessagesIndicator();
}
}
if (this.shouldShowOnTextMessage()) {
this.show();
} else {
this.scrollDown();
}
this.scrollDown();
},
handleErrorMessage (message) {

View File

@ -86,7 +86,7 @@
*
* NB: These plugins need to have already been loaded via require.js.
*/
dependencies: ["converse-chatboxes", "converse-rosterview"],
dependencies: ["converse-chatboxes", "converse-rosterview", "converse-chatview"],
overrides: {
// Overrides mentioned here will be picked up by converse.js's
@ -126,15 +126,6 @@
return this.__super__.chatBoxMayBeShown.apply(this, arguments) &&
chatbox.get('id') !== 'controlbox';
},
onChatBoxesFetched (collection, resp) {
this.__super__.onChatBoxesFetched.apply(this, arguments);
const { _converse } = this.__super__;
if (!_.includes(_.map(collection, 'id'), 'controlbox')) {
_converse.addControlBox();
}
this.get('controlbox').save({connected:true});
},
},
ChatBoxViews: {
@ -715,8 +706,10 @@
Promise.all([
_converse.api.waitUntil('connectionInitialized'),
_converse.api.waitUntil('chatBoxesInitialized')
]).then(_converse.addControlBox)
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
]).then(() => {
_converse.addControlBox();
_converse.chatboxes.get('controlbox').save({connected:true});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
const disconnect = function () {
/* Upon disconnection, set connected to `false`, so that if

View File

@ -65,6 +65,8 @@
ChatBox: {
initialize () {
this.__super__.initialize.apply(this, arguments);
this.on('show', this.maximize, this);
if (this.get('id') === 'controlbox') {
return;
}
@ -114,11 +116,6 @@
this.__super__.isNewMessageHidden.apply(this, arguments);
},
shouldShowOnTextMessage () {
return !this.model.get('minimized') &&
this.__super__.shouldShowOnTextMessage.apply(this, arguments);
},
setChatBoxHeight (height) {
if (!this.model.get('minimized')) {
return this.__super__.setChatBoxHeight.apply(this, arguments);
@ -211,17 +208,6 @@
},
ChatBoxViews: {
showChat (attrs) {
/* Find the chat box and show it. If it doesn't exist, create it.
*/
const chatbox = this.__super__.showChat.apply(this, arguments);
const maximize = _.isUndefined(attrs.maximize) ? true : attrs.maximize;
if (chatbox.get('minimized') && maximize) {
chatbox.maximize();
}
return chatbox;
},
getChatBoxWidth (view) {
if (!view.model.get('minimized') && u.isVisible(view.el)) {
return u.getOuterWidth(view.el, true);

File diff suppressed because it is too large Load Diff

View File

@ -47,8 +47,8 @@
initialize () {
this.render().insertIntoDOM();
this.modal = new bootstrap.Modal(this.el, {
backdrop: 'static', // we don't want to dismiss Modal when Modal or backdrop is the click event target
keyboard: true // we want to dismiss Modal on pressing Esc key
backdrop: 'static',
keyboard: true
});
},

View File

@ -17,7 +17,7 @@
"tpl!rooms_list_item"
], factory);
}(this, function (utils, converse, muc, tpl_rooms_list, tpl_rooms_list_item) {
const { Backbone, Promise, b64_sha1, sizzle, _ } = converse.env;
const { Backbone, Promise, Strophe, b64_sha1, sizzle, _ } = converse.env;
const u = converse.env.utils;
converse.plugins.add('converse-roomslist', {
@ -137,6 +137,7 @@
'click .close-room': 'closeRoom',
'click .open-rooms-toggle': 'toggleRoomsList',
'click .remove-bookmark': 'removeBookmark',
'click a.open-room': 'openRoom',
},
listSelector: '.rooms-list',
ItemView: _converse.RoomsListElementView,
@ -192,6 +193,16 @@
u.showElement(this.el);
},
openRoom (ev) {
ev.preventDefault();
const name = ev.target.textContent;
const jid = ev.target.getAttribute('data-room-jid');
const data = {
'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)) || jid
}
_converse.api.rooms.open(jid, data);
},
closeRoom (ev) {
ev.preventDefault();
const name = ev.target.getAttribute('data-room-name');

View File

@ -379,7 +379,8 @@
openChat (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
return _converse.chatboxviews.showChat(this.model.attributes, true);
const attrs = this.model.attributes;
_converse.api.chats.open(attrs.jid, attrs);
},
removeContact (ev) {

View File

@ -37,7 +37,7 @@
// an error will be raised if the plugin is not found.
//
// NB: These plugins need to have already been loaded via require.js.
dependencies: ['converse-muc', 'converse-controlbox', 'converse-rosterview'],
dependencies: ['converse-chatboxes', 'converse-muc', 'converse-controlbox', 'converse-rosterview'],
enabled (_converse) {
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
@ -49,80 +49,37 @@
// relevant objects or classes.
//
// new functions which don't exist yet can also be added.
ChatBoxes: {
chatBoxMayBeShown (chatbox) {
return !chatbox.get('hidden');
},
createChatBox (jid, attrs) {
/* Make sure new chat boxes are hidden by default.
*/
/* Make sure new chat boxes are hidden by default. */
attrs = attrs || {};
attrs.hidden = true;
return this.__super__.createChatBox.call(this, jid, attrs);
}
},
RoomsPanel: {
parseRoomDataFromEvent (ev) {
/* We set hidden to false for rooms opened manually by the
* user. They should always be shown.
*/
const result = this.__super__.parseRoomDataFromEvent.apply(this, arguments);
if (_.isUndefined(result)) {
return
}
result.hidden = false;
return result;
}
},
ChatBoxViews: {
showChat (attrs, force) {
/* We only have one chat visible at any one
* time. So before opening a chat, we make sure all other
* chats are hidden.
*/
const { _converse } = this.__super__;
const chatbox = this.getChatBox(attrs, true);
const hidden = _.isUndefined(attrs.hidden) ? chatbox.get('hidden') : attrs.hidden;
if ((force || !hidden) && _converse.connection.authenticated) {
_.each(_converse.chatboxviews.xget(chatbox.get('id')), hideChat);
chatbox.save({'hidden': false});
}
return this.__super__.showChat.apply(this, arguments);
}
},
ChatBoxView: {
show (focus) {
_show (focus) {
/* We only have one chat visible at any one
* time. So before opening a chat, we make sure all other
* chats are hidden.
*/
if (!this.model.get('hidden')) {
_.each(this.__super__._converse.chatboxviews.xget(this.model.get('id')), hideChat);
return this.__super__.show.apply(this, arguments);
}
_.each(this.__super__._converse.chatboxviews.xget(this.model.get('id')), hideChat);
this.model.set('hidden', false);
return this.__super__._show.apply(this, arguments);
}
},
ChatRoomView: {
show (focus) {
if (!this.model.get('hidden')) {
_.each(this.__super__._converse.chatboxviews.xget(this.model.get('id')), hideChat);
return this.__super__.show.apply(this, arguments);
}
_.each(this.__super__._converse.chatboxviews.xget(this.model.get('id')), hideChat);
this.model.set('hidden', false);
return this.__super__.show.apply(this, arguments);
}
},
RosterContactView: {
openChat (ev) {
/* We only have one chat visible at any one
* time. So before opening a chat, we make sure all other
* chats are hidden.
*/
_.each(this.__super__._converse.chatboxviews.xget('controlbox'), hideChat);
this.model.save({'hidden': false});
return this.__super__.openChat.apply(this, arguments);
},
}
}
});

View File

@ -1,7 +1,7 @@
<!-- <div id="chatrooms"> -->
<form class="add-chatroom"></form>
<div class="d-flex">
<span class="w-100">Chatrooms</span>
<span class="w-100">{{{o.heading_chatrooms}}}</span>
<a class="chatbox-btn fa fa-users" title="{{{o.title_new_room}}}" data-toggle="modal" data-target="#chatroomsModal"></a>
</div>
<div class="list-container open-rooms-list rooms-list-container"></div>