Browse Source

muc: Refactored how MAM messages are fetched.

Listen for the `afterMessagesFetched` event.
Wait until `discoInitialized` before fetching.
Add `fetchArchivedMessagesIfNecessary` method(s).
JC Brand 8 years ago
parent
commit
084d9914b0
2 changed files with 69 additions and 71 deletions
  1. 45 48
      src/converse-mam.js
  2. 24 23
      src/converse-muc.js

+ 45 - 48
src/converse-mam.js

@@ -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));
+            });
         }
     });
 }));

+ 24 - 23
src/converse-muc.js

@@ -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);
                     }
                 });
             }