diff --git a/spec/muc.js b/spec/muc.js index 8c7ab5792..2cc2ffc4c 100644 --- a/spec/muc.js +++ b/spec/muc.js @@ -2138,6 +2138,7 @@ const __ = _converse.__; await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'oldnick'); const view = _converse.chatboxviews.get('lounge@localhost'); + expect(view.model.get('connection_status')).toBe(converse.ROOMSTATUS.ENTERED); const chat_content = view.el.querySelector('.chat-content'); let occupants = view.el.querySelector('.occupant-list'); @@ -2169,6 +2170,7 @@ expect(sizzle('div.chat-info:last').pop().textContent).toBe( __(_converse.muc.new_nickname_messages["303"], "newnick") ); + expect(view.model.get('connection_status')).toBe(converse.ROOMSTATUS.DISCONNECTED); occupants = view.el.querySelector('.occupant-list'); expect(occupants.childNodes.length).toBe(1); @@ -2187,6 +2189,7 @@ .c('status').attrs({code:'110'}).nodeTree; _converse.connection._dataRecv(test_utils.createRequest(presence)); + expect(view.model.get('connection_status')).toBe(converse.ROOMSTATUS.ENTERED); // XXX: currently we still have an additional "has entered the groupchat" // notification for the new nickname. Ideally we'd not have // that, but that's probably not possible without some diff --git a/src/headless/converse-muc.js b/src/headless/converse-muc.js index 43dfde232..48a33f29c 100644 --- a/src/headless/converse-muc.js +++ b/src/headless/converse-muc.js @@ -1281,30 +1281,33 @@ converse.plugins.add('converse-muc', { _converse.api.trigger('message', {'stanza': original_stanza, 'chatbox': this}); }, + onErrorPresence (pres) { + // TODO: currently showErrorMessageFromPresence handles + // 'error" presences in converse-muc-views. + // Instead, they should be handled here and the presence + // handler removed from there. + if (sizzle(`error not-authorized[xmlns="${Strophe.NS.STANZAS}"]`, pres).length) { + this.save('connection_status', converse.ROOMSTATUS.PASSWORD_REQUIRED); + } else { + this.save('connection_status', converse.ROOMSTATUS.DISCONNECTED); + } + }, + /** * Handles all MUC presence stanzas. * @private * @method _converse.ChatRoom#onPresence - * @param { XMLElement } pres - The stanza + * @param { XMLElement } stanza */ - onPresence (pres) { - if (pres.getAttribute('type') === 'error') { - // TODO: currently showErrorMessageFromPresence handles - // 'error" presences in converse-muc-views. - // Instead, they should be handled here and the presence - // handler removed from there. - if (sizzle(`error not-authorized[xmlns="${Strophe.NS.STANZAS}"]`, pres).length) { - this.save('connection_status', converse.ROOMSTATUS.PASSWORD_REQUIRED); - } else { - this.save('connection_status', converse.ROOMSTATUS.DISCONNECTED); - } - return; + onPresence (stanza) { + if (stanza.getAttribute('type') === 'error') { + return this.onErrorPresence(stanza); } - const is_self = pres.querySelector("status[code='110']"); - if (is_self && pres.getAttribute('type') !== 'unavailable') { - this.onOwnPresence(pres); + if (stanza.querySelector("status[code='110']")) { + this.onOwnPresence(stanza); } - this.updateOccupantsOnPresence(pres); + this.updateOccupantsOnPresence(stanza); + if (this.get('role') !== 'none' && this.get('connection_status') === converse.ROOMSTATUS.CONNECTING) { this.save('connection_status', converse.ROOMSTATUS.CONNECTED); } @@ -1325,41 +1328,45 @@ converse.plugins.add('converse-muc', { * @method _converse.ChatRoom#onOwnPresence * @param { XMLElement } pres - The stanza */ - onOwnPresence (pres) { - this.saveAffiliationAndRole(pres); + onOwnPresence (stanza) { + this.saveAffiliationAndRole(stanza); - const locked_room = pres.querySelector("status[code='201']"); - if (locked_room) { - if (this.get('auto_configure')) { - this.autoConfigureChatRoom().then(() => this.refreshRoomFeatures()); - } else if (_converse.muc_instant_rooms) { - // Accept default configuration - this.saveConfiguration().then(() => this.refreshRoomFeatures()); - } else { - /** - * Triggered when a new room has been created which first needs to be configured - * and when `auto_configure` is set to `false`. - * Used by `_converse.ChatRoomView` in order to know when to render the - * configuration form for a new room. - * @event _converse.ChatRoom#configurationNeeded - * @example _converse.api.listen.on('configurationNeeded', () => { ... }); - */ - this.trigger('configurationNeeded'); - return; // We haven't yet entered the groupchat, so bail here. - } - } else if (!this.features.get('fetched')) { - // The features for this groupchat weren't fetched. - // That must mean it's a new groupchat without locking - // (in which case Prosody doesn't send a 201 status), - // otherwise the features would have been fetched in - // the "initialize" method already. - if (this.get('affiliation') === 'owner' && this.get('auto_configure')) { - this.autoConfigureChatRoom().then(() => this.refreshRoomFeatures()); - } else { - this.getRoomFeatures(); + if (stanza.getAttribute('type') === 'unavailable') { + this.save('connection_status', converse.ROOMSTATUS.DISCONNECTED); + } else { + const locked_room = stanza.querySelector("status[code='201']"); + if (locked_room) { + if (this.get('auto_configure')) { + this.autoConfigureChatRoom().then(() => this.refreshRoomFeatures()); + } else if (_converse.muc_instant_rooms) { + // Accept default configuration + this.saveConfiguration().then(() => this.refreshRoomFeatures()); + } else { + /** + * Triggered when a new room has been created which first needs to be configured + * and when `auto_configure` is set to `false`. + * Used by `_converse.ChatRoomView` in order to know when to render the + * configuration form for a new room. + * @event _converse.ChatRoom#configurationNeeded + * @example _converse.api.listen.on('configurationNeeded', () => { ... }); + */ + this.trigger('configurationNeeded'); + return; // We haven't yet entered the groupchat, so bail here. + } + } else if (!this.features.get('fetched')) { + // The features for this groupchat weren't fetched. + // That must mean it's a new groupchat without locking + // (in which case Prosody doesn't send a 201 status), + // otherwise the features would have been fetched in + // the "initialize" method already. + if (this.get('affiliation') === 'owner' && this.get('auto_configure')) { + this.autoConfigureChatRoom().then(() => this.refreshRoomFeatures()); + } else { + this.getRoomFeatures(); + } } + this.save('connection_status', converse.ROOMSTATUS.ENTERED); } - this.save('connection_status', converse.ROOMSTATUS.ENTERED); }, /**