MUC: Queue messages received before we're ready
This commit is contained in:
parent
58f6d36564
commit
49817a850f
89
package-lock.json
generated
89
package-lock.json
generated
|
@ -9988,6 +9988,11 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"filesize": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/filesize/-/filesize-4.2.1.tgz",
|
||||
"integrity": "sha512-bP82Hi8VRZX/TUBKfE24iiUGsB/sfm2WUrwTQyAzQrhO3V9IhcBBNBXMyzLY5orACxRyYJ3d2HeRVX+eFv4lmA=="
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||
|
@ -10299,7 +10304,6 @@
|
|||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
|
@ -10309,8 +10313,7 @@
|
|||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -11535,8 +11538,7 @@
|
|||
"graceful-fs": {
|
||||
"version": "4.1.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
|
||||
},
|
||||
"handle-thing": {
|
||||
"version": "2.0.0",
|
||||
|
@ -12004,6 +12006,11 @@
|
|||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
|
||||
},
|
||||
"import-cwd": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
|
||||
|
@ -12567,6 +12574,11 @@
|
|||
"integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
|
||||
"dev": true
|
||||
},
|
||||
"jed": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz",
|
||||
"integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ="
|
||||
},
|
||||
"jest-worker": {
|
||||
"version": "25.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz",
|
||||
|
@ -12726,7 +12738,6 @@
|
|||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
|
@ -12963,6 +12974,14 @@
|
|||
"type-check": "~0.3.2"
|
||||
}
|
||||
},
|
||||
"lie": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||
"integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
|
||||
"requires": {
|
||||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"linkify-it": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
|
||||
|
@ -13025,6 +13044,14 @@
|
|||
"json5": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"localforage": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.3.tgz",
|
||||
"integrity": "sha512-1TulyYfc4udS7ECSBT2vwJksWbkwwTX8BzeUIiq8Y07Riy7bDAAnxDaPU/tWyOVmQAcWJIEIFP9lPfBGqVoPgQ==",
|
||||
"requires": {
|
||||
"lie": "3.1.1"
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||
|
@ -19160,6 +19187,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"pluggable.js": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pluggable.js/-/pluggable.js-2.0.1.tgz",
|
||||
"integrity": "sha512-SBt6v6Tbp20Jf8hU0cpcc/+HBHGMY8/Q+yA6Ih0tBQE8tfdZ6U4PRG0iNvUUjLx/hVyOP53n0UfGBymlfaaXCg==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.11"
|
||||
}
|
||||
},
|
||||
"po-loader": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/po-loader/-/po-loader-0.5.0.tgz",
|
||||
|
@ -21068,6 +21103,13 @@
|
|||
"integrity": "sha512-Mf37VjirD7RqCVeYgI8jb5K0DymIho/jNJqDgIkMs4cgKbEkvsow8Q6hpvF7Zmys9iEif0oW41hgbeWVZwABJw==",
|
||||
"dev": true
|
||||
},
|
||||
"skeletor.js": {
|
||||
"version": "github:skeletorjs/skeletor#dea2d5791ee894493e30b92662c953efec0e58f6",
|
||||
"from": "github:skeletorjs/skeletor#dea2d5791ee894493e30b92662c953efec0e58f6",
|
||||
"requires": {
|
||||
"lodash": "^4.17.14"
|
||||
}
|
||||
},
|
||||
"slash": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
|
||||
|
@ -21742,6 +21784,11 @@
|
|||
"through": "^2.3.4"
|
||||
}
|
||||
},
|
||||
"strophe.js": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.3.4.tgz",
|
||||
"integrity": "sha512-jSLDG8jolhAwGOSgiJ7DTMSYK3wVoEJHKtpVRyEacQZ6CWA6z2WRPJpcFMjsIweq5aP9/XIvKUQqHBu/ZhvESA=="
|
||||
},
|
||||
"style-loader": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz",
|
||||
|
@ -22195,6 +22242,33 @@
|
|||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"dev": true
|
||||
},
|
||||
"twemoji": {
|
||||
"version": "12.1.5",
|
||||
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-12.1.5.tgz",
|
||||
"integrity": "sha512-B0PBVy5xomwb1M/WZxf/IqPZfnoIYy1skXnlHjMwLwTNfZ9ljh8VgWQktAPcJXu8080WoEh6YwQGPVhDVqvrVQ==",
|
||||
"requires": {
|
||||
"fs-extra": "^8.0.1",
|
||||
"jsonfile": "^5.0.0",
|
||||
"twemoji-parser": "12.1.3",
|
||||
"universalify": "^0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonfile": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz",
|
||||
"integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^0.1.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"twemoji-parser": {
|
||||
"version": "12.1.3",
|
||||
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-12.1.3.tgz",
|
||||
"integrity": "sha512-ND4LZXF4X92/PFrzSgGkq6KPPg8swy/U0yRw1k/+izWRVmq1HYi3khPwV3XIB6FRudgVICAaBhJfW8e8G3HC7Q=="
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
||||
|
@ -22415,8 +22489,7 @@
|
|||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
|
|
16
spec/muc.js
16
spec/muc.js
|
@ -580,12 +580,15 @@
|
|||
|
||||
it("shows join/leave messages when users enter or exit a groupchat",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'muc_fetch_members': false},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
await test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1');
|
||||
const nick = 'some1';
|
||||
const room_creation_promise = await _converse.api.rooms.open(muc_jid, {nick});
|
||||
await test_utils.getRoomFeatures(_converse, muc_jid);
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
await u.waitUntil(() => sent_stanzas.filter(iq => sizzle('presence history', iq).length).pop());
|
||||
|
||||
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
|
||||
const chat_content = view.el.querySelector('.chat-content');
|
||||
|
@ -627,6 +630,10 @@
|
|||
expect(sizzle('div.chat-info:first', chat_content).pop().textContent.trim())
|
||||
.toBe("some1 has entered the groupchat");
|
||||
|
||||
await room_creation_promise;
|
||||
await u.waitUntil(() => (view.model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
||||
await view.model.messages.fetched;
|
||||
|
||||
presence = $pres({
|
||||
to: 'romeo@montague.lit/_converse.js-29092160',
|
||||
from: 'coven@chat.shakespeare.lit/newguy'
|
||||
|
@ -664,7 +671,7 @@
|
|||
'role': 'participant'
|
||||
});
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
expect(chat_content.querySelectorAll('div.chat-info').length).toBe(3);
|
||||
await u.waitUntil(() => chat_content.querySelectorAll('div.chat-info').length === 3);
|
||||
expect(sizzle('div.chat-info:last', chat_content).pop().textContent.trim())
|
||||
.toBe("newgirl has entered the groupchat");
|
||||
|
||||
|
@ -5184,13 +5191,14 @@
|
|||
});
|
||||
|
||||
describe("A paused notification", function () {
|
||||
|
||||
it("will be shown if received",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1');
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'some1');
|
||||
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
|
||||
const chat_content = view.el.querySelector('.chat-content');
|
||||
|
||||
|
|
|
@ -185,9 +185,10 @@
|
|||
mock.initConverse(
|
||||
['chatBoxesInitialized'],
|
||||
{ 'auto_login': false,
|
||||
'enable_smacks': true,
|
||||
'show_controlbox_by_default': true,
|
||||
'blacklisted_plugins': 'converse-mam',
|
||||
'enable_smacks': true,
|
||||
'muc_fetch_members': false,
|
||||
'show_controlbox_by_default': true,
|
||||
'smacks_max_unacked_stanzas': 2
|
||||
},
|
||||
async function (done, _converse) {
|
||||
|
@ -243,9 +244,11 @@
|
|||
_converse.connection._dataRecv(test_utils.createRequest(result));
|
||||
expect(_converse.session.get('smacks_enabled')).toBe(true);
|
||||
|
||||
|
||||
const nick = 'romeo';
|
||||
const func = _converse.chatboxes.onChatBoxesFetched;
|
||||
spyOn(_converse.chatboxes, 'onChatBoxesFetched').and.callFake(collection => {
|
||||
const muc = new _converse.ChatRoom({'jid': muc_jid, 'id': muc_jid}, {'collection': _converse.chatboxes});
|
||||
const muc = new _converse.ChatRoom({'jid': muc_jid, 'id': muc_jid, nick}, {'collection': _converse.chatboxes});
|
||||
_converse.chatboxes.add(muc);
|
||||
func.call(_converse.chatboxes, collection);
|
||||
});
|
||||
|
@ -262,7 +265,15 @@
|
|||
|
||||
await _converse.api.waitUntil('chatBoxesFetched');
|
||||
const muc = _converse.chatboxes.get(muc_jid);
|
||||
await u.waitUntil(() => muc.messages.length === 1);
|
||||
await u.waitUntil(() => muc.message_queue.length === 1);
|
||||
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
await test_utils.getRoomFeatures(_converse, muc_jid);
|
||||
await test_utils.receiveOwnMUCPresence(_converse, muc_jid, nick);
|
||||
await u.waitUntil(() => (view.model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
||||
await view.model.messages.fetched;
|
||||
|
||||
await u.waitUntil(() => muc.messages.length);
|
||||
expect(muc.messages.at(0).get('message')).toBe('First message')
|
||||
done();
|
||||
}));
|
||||
|
|
|
@ -384,6 +384,7 @@ converse.plugins.add('converse-muc', {
|
|||
await new Promise(resolve => this.features.fetch({'success': resolve, 'error': resolve}));
|
||||
await this.fetchOccupants();
|
||||
await this.fetchMessages();
|
||||
await this.clearMessageQueue();
|
||||
return true;
|
||||
} else {
|
||||
await this.clearCache();
|
||||
|
@ -451,12 +452,23 @@ converse.plugins.add('converse-muc', {
|
|||
return this.join();
|
||||
},
|
||||
|
||||
initMessages () {
|
||||
_converse.ChatBox.prototype.initMessages.call(this);
|
||||
this.message_queue = [];
|
||||
},
|
||||
|
||||
async clearMessageQueue () {
|
||||
await Promise.all(this.message_queue.map(m => this.onMessage(m)));
|
||||
this.message_queue = [];
|
||||
},
|
||||
|
||||
async onConnectionStatusChanged () {
|
||||
if (this.session.get('connection_status') === converse.ROOMSTATUS.ENTERED) {
|
||||
if (_converse.muc_fetch_members) {
|
||||
await this.occupants.fetchMembers();
|
||||
}
|
||||
await this.fetchMessages();
|
||||
await this.clearMessageQueue();
|
||||
/**
|
||||
* Triggered when the user has entered a new MUC
|
||||
* @event _converse#enteredNewRoom
|
||||
|
@ -1780,6 +1792,13 @@ converse.plugins.add('converse-muc', {
|
|||
* @param { XMLElement } stanza - The message stanza.
|
||||
*/
|
||||
async onMessage (stanza) {
|
||||
if (!this.messages.fetched || this.messages.fetched.isPending) {
|
||||
// We're not ready to accept messages before we've fetched
|
||||
// from our store, so we stuff them into a queue.
|
||||
this.message_queue.push(stanza);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sizzle(`message > forwarded[xmlns="${Strophe.NS.FORWARD}"]`, stanza).length) {
|
||||
return log.warn('onMessage: Ignoring unencapsulated forwarded groupchat message');
|
||||
}
|
||||
|
|
|
@ -140,9 +140,7 @@
|
|||
};
|
||||
|
||||
utils.openChatRoom = async function (_converse, room, server) {
|
||||
const model = await _converse.api.rooms.open(`${room}@${server}`);
|
||||
await model.messages.fetched;
|
||||
return model;
|
||||
return _converse.api.rooms.open(`${room}@${server}`);
|
||||
};
|
||||
|
||||
utils.getRoomFeatures = async function (_converse, muc_jid, features=[]) {
|
||||
|
@ -273,7 +271,9 @@
|
|||
return new Promise(resolve => _converse.api.listen.on('membersFetched', resolve));
|
||||
};
|
||||
|
||||
utils.receiveOwnMUCPresence = function (_converse, muc_jid, nick) {
|
||||
utils.receiveOwnMUCPresence = async function (_converse, muc_jid, nick) {
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
await u.waitUntil(() => sent_stanzas.filter(iq => sizzle('presence history', iq).length).pop());
|
||||
const presence = $pres({
|
||||
to: _converse.connection.jid,
|
||||
from: `${muc_jid}/${nick}`,
|
||||
|
@ -297,7 +297,7 @@
|
|||
// The user has just entered the room (because join was called)
|
||||
// and receives their own presence from the server.
|
||||
// See example 24: https://xmpp.org/extensions/xep-0045.html#enter-pres
|
||||
utils.receiveOwnMUCPresence(_converse, muc_jid, nick);
|
||||
await utils.receiveOwnMUCPresence(_converse, muc_jid, nick);
|
||||
|
||||
await room_creation_promise;
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
|
|
Loading…
Reference in New Issue
Block a user