muc: Refactored how MAM messages are fetched.

Listen for the `afterMessagesFetched` event.
Wait until `discoInitialized` before fetching.
Add `fetchArchivedMessagesIfNecessary` method(s).
This commit is contained in:
JC Brand 2017-07-21 15:05:22 +02:00
parent 0a47f60f94
commit 084d9914b0
2 changed files with 69 additions and 71 deletions

View File

@ -49,24 +49,19 @@
return result;
},
afterMessagesFetched () {
const { _converse } = this.__super__;
if (this.disable_mam ||
!_converse.disco_entities.get(_converse.domain)
.features.findWhere({'var': Strophe.NS.MAM})) {
return this.__super__.afterMessagesFetched.apply(this, arguments);
}
if (!this.model.get('mam_initialized') &&
this.model.messages.length < _converse.archived_messages_page_size) {
fetchArchivedMessagesIfNecessary () {
/* Check if archived messages should be fetched, and if so, do so. */
const { _converse } = this.__super__,
entity = _converse.disco_entities.get(_converse.domain),
server_supports_mam = entity.features.findWhere({'var': Strophe.NS.MAM});
this.fetchArchivedMessages({
'before': '', // Page backwards from the most recent message
'with': this.model.get('jid'),
'max': _converse.archived_messages_page_size
});
this.model.save({'mam_initialized': true});
if (this.disable_mam ||
!server_supports_mam ||
this.model.get('mam_initialized')) {
return;
}
return this.__super__.afterMessagesFetched.apply(this, arguments);
this.fetchArchivedMessages();
this.model.save({'mam_initialized': true});
},
fetchArchivedMessages (options) {
@ -90,7 +85,11 @@
}
this.addSpinner();
_converse.queryForArchivedMessages(
options,
_.extend({
'before': '', // Page backwards from the most recent message
'max': _converse.archived_messages_page_size,
'with': this.model.get('jid'),
}, options),
(messages) => { // Success
this.clearSpinner();
if (messages.length) {
@ -110,9 +109,7 @@
const { _converse } = this.__super__;
if ($(ev.target).scrollTop() === 0 && this.model.messages.length) {
this.fetchArchivedMessages({
'before': this.model.messages.at(0).get('archive_id'),
'with': this.model.get('jid'),
'max': _converse.archived_messages_page_size
'before': this.model.messages.at(0).get('archive_id')
});
}
},
@ -123,17 +120,8 @@
initialize () {
const { _converse } = this.__super__;
this.__super__.initialize.apply(this, arguments);
this.model.on('change:mam_enabled', function () {
// Fetch messages again if we find out that mam has
// been enabled (because the first attempt would then
// have failed.
this.fetchArchivedMessages({
'before': '', // Page backwards from the most recent message
'with': this.model.get('jid'),
'max': _converse.archived_messages_page_size
});
this.model.save({'mam_initialized': true});
}, this);
this.model.on('change:mam_enabled', this.fetchArchivedMessagesIfNecessary, this);
this.model.on('change:connection_status', this.fetchArchivedMessagesIfNecessary, this);
},
render () {
@ -155,29 +143,33 @@
return this.__super__.handleMUCMessage.apply(this, arguments);
},
fetchArchivedMessagesIfNecessary () {
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED ||
!this.model.get('mam_enabled') ||
this.model.get('mam_initialized')) {
return;
}
this.fetchArchivedMessages();
this.model.save({'mam_initialized': true});
},
fetchArchivedMessages (options) {
/* Fetch archived chat messages from the XMPP server.
/* Fetch archived chat messages for this Chat Room
*
* Then, upon receiving them, call onChatRoomMessage
* so that they are displayed inside it.
*/
const { _converse } = this.__super__;
if (!_converse.disco_entities.get(_converse.domain)
.features.findWhere({'var': Strophe.NS.MAM})) {
_converse.log(
"Attempted to fetch archived messages but this "+
"user's server doesn't support XEP-0313",
Strophe.LogLevel.WARN);
return;
}
if (!this.model.get('mam_enabled')) {
return;
}
this.addSpinner();
const that = this;
_converse.api.archive.query(_.extend(options, {'groupchat': true}),
const { _converse } = this.__super__;
_converse.api.archive.query(
_.extend({
'groupchat': true,
'before': '', // Page backwards from the most recent message
'with': this.model.get('jid'),
'max': _converse.archived_messages_page_size
}, options),
function (messages) {
that.clearSpinner();
if (messages.length) {
@ -195,7 +187,6 @@
}
},
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
@ -368,6 +359,12 @@
_converse.on('addClientFeatures', () => {
_converse.connection.disco.addFeature(Strophe.NS.MAM);
});
_converse.on('afterMessagesFetched', (chatboxview) => {
_converse.api.waitUntil('discoInitialized')
.then(chatboxview.fetchArchivedMessagesIfNecessary.bind(chatboxview))
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
});
}
});
}));

View File

@ -92,7 +92,8 @@
'moderated': 'unmoderated',
'unmoderated': 'moderated'
};
const ROOMSTATUS = {
converse.ROOMSTATUS = {
CONNECTED: 0,
CONNECTING: 1,
NICKNAME_REQUIRED: 2,
@ -126,7 +127,7 @@
_tearDown () {
const rooms = this.chatboxes.where({'type': CHATROOMS_TYPE});
_.each(rooms, function (room) {
utils.safeSave(room, {'connection_status': ROOMSTATUS.DISCONNECTED});
utils.safeSave(room, {'connection_status': converse.ROOMSTATUS.DISCONNECTED});
});
this.__super__._tearDown.call(this, arguments);
},
@ -365,7 +366,7 @@
'num_unread_general': 0,
'affiliation': null,
'connection_status': ROOMSTATUS.DISCONNECTED,
'connection_status': converse.ROOMSTATUS.DISCONNECTED,
'name': '',
'description': '',
'features_fetched': false,
@ -450,7 +451,7 @@
this.render().insertIntoDOM();
this.registerHandlers();
if (this.model.get('connection_status') !== ROOMSTATUS.ENTERED) {
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
const handler = () => {
this.join();
this.fetchMessages();
@ -468,7 +469,7 @@
this.el.innerHTML = tpl_chatroom();
this.renderHeading();
this.renderChatArea();
if (this.model.get('connection_status') !== ROOMSTATUS.ENTERED) {
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
this.showSpinner();
}
utils.refreshWebkit();
@ -554,7 +555,7 @@
},
afterConnected () {
if (this.model.get('connection_status') === ROOMSTATUS.ENTERED) {
if (this.model.get('connection_status') === converse.ROOMSTATUS.ENTERED) {
this.setChatState(_converse.ACTIVE);
this.scrollDown();
this.focus();
@ -907,7 +908,7 @@
* as taken from the 'chat_state' attribute of the chat box.
* See XEP-0085 Chat State Notifications.
*/
if (this.model.get('connection_status') !== ROOMSTATUS.ENTERED) {
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
return;
}
const chat_state = this.model.get('chat_state');
@ -1195,7 +1196,7 @@
if (!nick) {
return this.checkForReservedNick();
}
if (this.model.get('connection_status') === ROOMSTATUS.ENTERED) {
if (this.model.get('connection_status') === converse.ROOMSTATUS.ENTERED) {
// We have restored a chat room from session storage,
// so we don't send out a presence stanza again.
return this;
@ -1208,7 +1209,7 @@
if (password) {
stanza.cnode(Strophe.xmlElement("password", [], password));
}
this.model.save('connection_status', ROOMSTATUS.CONNECTING);
this.model.save('connection_status', converse.ROOMSTATUS.CONNECTING);
_converse.connection.send(stanza);
return this;
},
@ -1240,7 +1241,7 @@
}
utils.safeSave(
this.model,
{'connection_status': ROOMSTATUS.DISCONNECTED}
{'connection_status': converse.ROOMSTATUS.DISCONNECTED}
);
this.removeHandlers();
_converse.ChatBoxView.prototype.close.apply(this, arguments);
@ -1616,7 +1617,7 @@
label_join: __('Enter room'),
validation_message: message
}));
this.model.save('connection_status', ROOMSTATUS.NICKNAME_REQUIRED);
this.model.save('connection_status', converse.ROOMSTATUS.NICKNAME_REQUIRED);
this.$('.chatroom-form').on('submit', this.submitNickname.bind(this));
},
@ -1636,7 +1637,7 @@
label_password: __('Password: '),
label_submit: __('Submit')
}));
this.model.save('connection_status', ROOMSTATUS.PASSWORD_REQUIRED);
this.model.save('connection_status', converse.ROOMSTATUS.PASSWORD_REQUIRED);
this.$('.chatroom-form').on('submit', this.submitPassword.bind(this));
},
@ -1752,7 +1753,7 @@
if (notification.reason) {
this.showDisconnectMessage(__(___('The reason given is: "%1$s".'), notification.reason));
}
this.model.save('connection_status', ROOMSTATUS.DISCONNECTED);
this.model.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
return;
}
_.each(notification.messages, (message) => {
@ -1809,7 +1810,7 @@
if (_.isEmpty(notifications) &&
_converse.muc_show_join_leave &&
stanza.nodeName === 'presence' &&
this.model.get('connection_status') === ROOMSTATUS.ENTERED
this.model.get('connection_status') === converse.ROOMSTATUS.ENTERED
) {
notifications = this.getJoinLeaveMessages(stanza);
}
@ -1852,9 +1853,9 @@
* example after the spinner has been removed or after a
* form has been submitted and removed.
*/
if (this.model.get('connection_status') == ROOMSTATUS.NICKNAME_REQUIRED) {
if (this.model.get('connection_status') == converse.ROOMSTATUS.NICKNAME_REQUIRED) {
this.renderNicknameForm();
} else if (this.model.get('connection_status') == ROOMSTATUS.PASSWORD_REQUIRED) {
} else if (this.model.get('connection_status') == converse.ROOMSTATUS.PASSWORD_REQUIRED) {
this.renderPasswordForm();
} else {
this.$el.find('.chat-area').removeClass('hidden');
@ -1923,7 +1924,7 @@
this.getRoomFeatures();
}
}
this.model.save('connection_status', ROOMSTATUS.ENTERED);
this.model.save('connection_status', converse.ROOMSTATUS.ENTERED);
},
onChatRoomPresence (pres) {
@ -1933,7 +1934,7 @@
* (XMLElement) pres: The stanza
*/
if (pres.getAttribute('type') === 'error') {
this.model.save('connection_status', ROOMSTATUS.DISCONNECTED);
this.model.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
this.showErrorMessage(pres);
return true;
}
@ -1946,8 +1947,8 @@
// "join" messages are correctly shown.
this.occupantsview.updateOccupantsOnPresence(pres);
if (this.model.get('role') !== 'none' &&
this.model.get('connection_status') === ROOMSTATUS.CONNECTING) {
this.model.save('connection_status', ROOMSTATUS.CONNECTED);
this.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING) {
this.model.save('connection_status', converse.ROOMSTATUS.CONNECTED);
}
return true;
},
@ -2662,7 +2663,7 @@
'box_id': b64_sha1(room_jid),
'password': $x.attr('password')
});
if (chatroom.get('connection_status') === ROOMSTATUS.DISCONNECTED) {
if (chatroom.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED) {
_converse.chatboxviews.get(room_jid).join();
}
}
@ -2795,7 +2796,7 @@
*/
_converse.chatboxviews.each(function (view) {
if (view.model.get('type') === CHATROOMS_TYPE) {
view.model.save('connection_status', ROOMSTATUS.DISCONNECTED);
view.model.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
view.registerHandlers();
view.join();
view.fetchMessages();
@ -2810,7 +2811,7 @@
*/
_converse.chatboxes.each(function (model) {
if (model.get('type') === CHATROOMS_TYPE) {
model.save('connection_status', ROOMSTATUS.DISCONNECTED);
model.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
}
});
}