Change when/how chats are shown

Goal is to fix a timing bug that results in `show` being triggered
before the `ChatBoxView` has been initialized, which means that 1:1
chats aren't opened when you reload the page.
This commit is contained in:
JC Brand 2020-02-02 15:38:37 +01:00
parent da493430f8
commit 39d140005e
8 changed files with 23 additions and 18 deletions

View File

@ -1228,9 +1228,7 @@
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
const msg_id = u.getUniqueId();
const sent_stanzas = [];
spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
sent_stanzas.push(stanza);
});
spyOn(_converse.connection, 'send').and.callFake(stanza => sent_stanzas.push(stanza));
const msg = $msg({
'from': sender_jid,
'to': _converse.connection.jid,
@ -1240,8 +1238,9 @@
.c('request', {'xmlns': Strophe.NS.RECEIPTS}).tree();
await _converse.handleMessageStanza(msg);
const sent_messages = sent_stanzas.map(s => _.isElement(s) ? s : s.nodeTree).filter(s => s.nodeName === 'message');
expect(sent_messages.length).toBe(1);
const receipt = sizzle(`received[xmlns="${Strophe.NS.RECEIPTS}"]`, sent_messages[0]).pop();
// A chat state message is also included
expect(sent_messages.length).toBe(2);
const receipt = sizzle(`received[xmlns="${Strophe.NS.RECEIPTS}"]`, sent_messages[1]).pop();
expect(Strophe.serialize(receipt)).toBe(`<received id="${msg_id}" xmlns="${Strophe.NS.RECEIPTS}"/>`);
done();
}));
@ -2116,7 +2115,15 @@
const sent_messages = sent_stanzas
.map(s => _.isElement(s) ? s : s.nodeTree)
.filter(e => e.nodeName === 'message');
expect(sent_messages.length).toBe(0);
expect(sent_messages.length).toBe(1);
expect(Strophe.serialize(sent_messages[0])).toBe(
`<message id="${sent_messages[0].getAttribute('id')}" to="${contact_jid}" type="chat" xmlns="jabber:client">`+
`<active xmlns="http://jabber.org/protocol/chatstates"/>`+
`<no-store xmlns="urn:xmpp:hints"/>`+
`<no-permanent-store xmlns="urn:xmpp:hints"/>`+
`</message>`
);
done();
}));

View File

@ -116,7 +116,7 @@
}, async function (done, _converse) {
const muc_jid = 'coven@chat.shakespeare.lit';
await _converse.api.rooms.open(muc_jid, {'nick': 'some1'});
await _converse.api.rooms.open(muc_jid, {'nick': 'some1'}, true);
const lview = _converse.rooms_list_view
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length);
let room_els = lview.el.querySelectorAll(".available-chatroom");
@ -126,7 +126,7 @@
await u.waitUntil(() => lview.model.get(muc_jid).get('hidden') === false);
await u.waitUntil(() => u.hasClass('open', item), 1000);
expect(item.textContent.trim()).toBe('coven@chat.shakespeare.lit');
await _converse.api.rooms.open('balcony@chat.shakespeare.lit', {'nick': 'some1'});
await _converse.api.rooms.open('balcony@chat.shakespeare.lit', {'nick': 'some1'}, true);
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length > 1);
room_els = lview.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(2);

View File

@ -72,6 +72,7 @@
_converse.connection._dataRecv(test_utils.createRequest(msg));
await new Promise(resolve => _converse.api.listen.once('chatBoxViewInitialized', resolve));
const view = _converse.chatboxviews.get(sender_jid);
await new Promise(resolve => view.model.messages.once('rendered', resolve));
await u.waitUntil(() => u.isVisible(view.el));
await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
expect(view.el.querySelector('.chat-msg__author').textContent.includes('Mercutio')).toBeTruthy();

View File

@ -220,6 +220,7 @@ converse.plugins.add('converse-chatview', {
this.listenTo(this.model.presence, 'change:show', this.onPresenceChanged);
this.render();
await this.updateAfterMessagesFetched();
this.model.maybeShow();
/**
* Triggered once the {@link _converse.ChatBoxView} has been initialized
* @event _converse#chatBoxViewInitialized

View File

@ -142,6 +142,7 @@ converse.plugins.add('converse-headlines-view', {
this.renderHeading();
this.updateAfterMessagesFetched();
this.insertIntoDOM().hide();
this.model.maybeShow();
/**
* Triggered once the {@link _converse.HeadlinesBoxView} has been initialized
* @event _converse#headlinesBoxViewInitialized

View File

@ -702,6 +702,7 @@ converse.plugins.add('converse-muc-views', {
this.createSidebarView();
await this.updateAfterMessagesFetched();
this.onConnectionStatusChanged();
this.model.maybeShow();
/**
* Triggered once a { @link _converse.ChatRoomView } has been opened
* @event _converse#chatRoomViewInitialized

View File

@ -22,11 +22,6 @@ function hideChat (view) {
view.hide();
}
function visibleChats (_converse) {
return _converse.chatboxes
.filter(cb => (cb.get('id') !== 'controlbox' && !cb.get('hidden'))).length > 0;
}
converse.plugins.add('converse-uniview', {
// It's possible however to make optional dependencies non-optional.
@ -53,10 +48,11 @@ converse.plugins.add('converse-uniview', {
},
ChatBox: {
maybeShow () {
maybeShow (force) {
force && u.safeSave(this, {'hidden': false});
const { _converse } = this.__super__;
if (_converse.isUniView() && (!this.get('hidden') || !visibleChats(_converse))) {
return this.trigger("show");
if (_converse.isUniView() && this.get('hidden')) {
return;
} else {
return this.__super__.maybeShow.apply(this, arguments);
}

View File

@ -68,9 +68,7 @@ converse.plugins.add('converse-chatboxes', {
},
onChatBoxesFetched (collection) {
/* Show chat boxes upon receiving them from storage */
collection.filter(c => !c.isValid()).forEach(c => c.destroy());
collection.forEach(c => c.maybeShow());
/**
* Triggered when a message stanza is been received and processed.
* @event _converse#chatBoxesFetched