diff --git a/CHANGES.md b/CHANGES.md index 7e033c1d7..34aaf2d0b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -52,9 +52,14 @@ * `_converse.api.rooms.create` * `_converse.api.roomviews.close` +- Changes the events: + * The `chatBoxInitialized` event now triggers when a `_converse.ChatBox` (not the view) is opened. + * Renamed the old `chatBoxInitialized` to `chatBoxViewInitialized` and trigger only for `ChatBoxView` instances. + * Renamed `chatRoomOpened` event to `chatRoomViewInitialized` + * The order of certain events have now changed: `statusInitialized` is now triggered after `initialized` and `connected` and `reconnected`. + - `_converse.api.chats.get()` now only returns one-on-one chats, not the control box or headline notifications. - The `show_only_online_users` setting has been removed. -- The order of certain events have now changed: `statusInitialized` is now triggered after `initialized` and `connected` and `reconnected`. - `_converse.api.alert.show` is now `_converse.api.show` and instead of taking an integer for the `type`, "info", "warn" or "error" should be passed in. - The `converse-headline` plugin has been split up into `converse-headlines` and `converse-headlines-view`. diff --git a/spec/bookmarks.js b/spec/bookmarks.js index 82908e5ee..e72d63e11 100644 --- a/spec/bookmarks.js +++ b/spec/bookmarks.js @@ -143,8 +143,8 @@ it("will be automatically opened if 'autojoin' is set on the bookmark", mock.initConverse( - ['rosterGroupsFetched'], {}, - async function (done, _converse) { + ['rosterGroupsFetched'], {}, + async function (done, _converse) { await test_utils.waitUntilDiscoConfirmed( _converse, _converse.bare_jid, @@ -168,7 +168,7 @@ 'name': 'The Play', 'nick': ' Othello' }); - await new Promise(resolve => _converse.api.listen.once('chatBoxInitialized', resolve)); + await new Promise(resolve => _converse.api.listen.once('chatRoomViewInitialized', resolve)); expect(_.isUndefined(_converse.chatboxviews.get(jid))).toBeFalsy(); // Check that we don't auto-join if muc_respect_autojoin is false diff --git a/spec/chatbox.js b/spec/chatbox.js index b43d8bec3..adf331c1c 100644 --- a/spec/chatbox.js +++ b/spec/chatbox.js @@ -136,7 +136,7 @@ const message_promise = new Promise(resolve => _converse.api.listen.on('message', resolve)); _converse.connection._dataRecv(test_utils.createRequest(stanza)); - await new Promise(resolve => _converse.api.listen.once('chatBoxInitialized', resolve)); + await new Promise(resolve => _converse.api.listen.once('chatBoxViewInitialized', resolve)); await u.waitUntil(() => message_promise); expect(_converse.chatboxviews.keys().length).toBe(2); done(); @@ -390,7 +390,7 @@ await u.waitUntil(() => _converse.chatboxes.length == 7) expect(_converse.chatboxviews.trimChats).toHaveBeenCalled(); expect(_converse.chatboxes.length).toEqual(7); - expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxInitialized', jasmine.any(Object)); + expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxViewInitialized', jasmine.any(Object)); await test_utils.closeAllChatBoxes(_converse); expect(_converse.chatboxes.length).toEqual(1); @@ -1427,7 +1427,7 @@ await u.waitUntil(() => chatbox.messages.length > 1); expect(select_msgs_indicator().textContent).toBe('2'); view.model.maximize(); - expect(select_msgs_indicator()).toBeUndefined(); + u.waitUntil(() => typeof select_msgs_indicator() === 'undefined'); done(); })); diff --git a/spec/controlbox.js b/spec/controlbox.js index 5bd3b1b67..d4d4b74a0 100644 --- a/spec/controlbox.js +++ b/spec/controlbox.js @@ -106,8 +106,8 @@ expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('2'); expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('2'); chatview.model.set({'minimized': false}); - expect(_.isNull(_converse.chatboxviews.el.querySelector('.restore-chat .message-count'))).toBeTruthy(); - expect(_.isNull(_converse.rosterview.el.querySelector('.msgs-indicator'))).toBeTruthy(); + expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count')).toBe(null); + await u.waitUntil(() => _converse.rosterview.el.querySelector('.msgs-indicator') === null); done(); })); }); diff --git a/spec/emojis.js b/spec/emojis.js index 5f57fb763..2b15afd07 100644 --- a/spec/emojis.js +++ b/spec/emojis.js @@ -170,7 +170,7 @@ 'id': _converse.connection.getUniqueId() }).c('body').t('😇').up() .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()); - await new Promise(resolve => _converse.on('chatBoxInitialized', resolve)); + await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve)); const view = _converse.api.chatviews.get(sender_jid); await new Promise(resolve => view.once('messageInserted', resolve)); const chat_content = view.el.querySelector('.chat-content'); diff --git a/spec/messages.js b/spec/messages.js index af7fd59d5..7686e463b 100644 --- a/spec/messages.js +++ b/spec/messages.js @@ -1082,7 +1082,7 @@ 'id': (new Date()).getTime() }).c('body').t('A message').up() .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()); - await new Promise(resolve => _converse.on('chatBoxInitialized', resolve)); + await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve)); const view = _converse.api.chatviews.get(sender_jid); await new Promise(resolve => view.once('messageInserted', resolve)); diff --git a/spec/protocol.js b/spec/protocol.js index c64addd52..e6ffceed0 100644 --- a/spec/protocol.js +++ b/spec/protocol.js @@ -360,7 +360,7 @@ expect(_converse.roster.updateContact).toHaveBeenCalled(); // The class on the contact will now have switched. - expect(u.hasClass('to', contacts[0])).toBe(false); + await u.waitUntil(() => !u.hasClass('to', contacts[0])); expect(u.hasClass('both', contacts[0])).toBe(true); done(); diff --git a/spec/spoilers.js b/spec/spoilers.js index 9d978edf1..57d81eda6 100644 --- a/spec/spoilers.js +++ b/spec/spoilers.js @@ -35,7 +35,7 @@ }).t(spoiler_hint) .tree(); _converse.connection._dataRecv(test_utils.createRequest(msg)); - await new Promise(resolve => _converse.api.listen.once('chatBoxInitialized', resolve)); + await new Promise(resolve => _converse.api.listen.once('chatBoxViewInitialized', resolve)); const view = _converse.chatboxviews.get(sender_jid); await new Promise(resolve => view.once('messageInserted', resolve)); await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio') @@ -70,7 +70,7 @@ 'xmlns': 'urn:xmpp:spoiler:0', }).tree(); _converse.connection._dataRecv(test_utils.createRequest(msg)); - await new Promise(resolve => _converse.api.listen.once('chatBoxInitialized', resolve)); + await new Promise(resolve => _converse.api.listen.once('chatBoxViewInitialized', resolve)); const view = _converse.chatboxviews.get(sender_jid); await u.waitUntil(() => u.isVisible(view.el)); await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio') diff --git a/src/converse-bookmark-views.js b/src/converse-bookmark-views.js index 91d6f6a23..deca42f95 100644 --- a/src/converse-bookmark-views.js +++ b/src/converse-bookmark-views.js @@ -308,8 +308,7 @@ converse.plugins.add('converse-bookmark-views', { } _converse.api.listen.on('bookmarksInitialized', initBookmarkViews); - - _converse.api.listen.on('chatRoomOpened', view => view.setBookmarkState()); + _converse.api.listen.on('chatRoomViewInitialized', view => view.setBookmarkState()); /************************ END Event Handlers ************************/ } }); diff --git a/src/converse-chatview.js b/src/converse-chatview.js index 2b0586c04..258921e71 100644 --- a/src/converse-chatview.js +++ b/src/converse-chatview.js @@ -81,9 +81,8 @@ converse.plugins.add('converse-chatview', { this.listenTo(this.model, 'change:status', this.onStatusMessageChanged); this.debouncedRender = debounce(this.render, 50); - if (this.model.vcard) { - this.listenTo(this.model.vcard, 'change', this.debouncedRender); - } + this.listenTo(this.model, 'vcard:change', this.debouncedRender); + if (this.model.contact) { this.listenTo(this.model.contact, 'destroy', this.debouncedRender); } @@ -264,11 +263,11 @@ converse.plugins.add('converse-chatview', { /** * Triggered once the {@link _converse.ChatBoxView} has been initialized - * @event _converse#chatBoxInitialized - * @type { _converse.ChatBoxView | _converse.HeadlinesBoxView } - * @example _converse.api.listen.on('chatBoxInitialized', view => { ... }); + * @event _converse#chatBoxViewInitialized + * @type { _converse.HeadlinesBoxView } + * @example _converse.api.listen.on('chatBoxViewInitialized', view => { ... }); */ - _converse.api.trigger('chatBoxInitialized', this); + _converse.api.trigger('chatBoxViewInitialized', this); }, initDebounced () { diff --git a/src/converse-controlbox.js b/src/converse-controlbox.js index b63c11516..62fe171dc 100644 --- a/src/converse-controlbox.js +++ b/src/converse-controlbox.js @@ -196,7 +196,6 @@ converse.plugins.add('converse-controlbox', { * @example _converse.api.listen.on('controlBoxInitialized', view => { ... }); */ _converse.api.trigger('controlBoxInitialized', this); - _converse.api.trigger('chatBoxInitialized', this); }, render () { diff --git a/src/converse-headlines-view.js b/src/converse-headlines-view.js index 94006ce76..b47698e0c 100644 --- a/src/converse-headlines-view.js +++ b/src/converse-headlines-view.js @@ -53,7 +53,13 @@ converse.plugins.add('converse-headlines-view', { this.render().insertHeading() this.updateAfterMessagesFetched(); this.insertIntoDOM().hide(); - _converse.api.trigger('chatBoxInitialized', this); + /** + * Triggered once the {@link _converse.HeadlinesBoxView} has been initialized + * @event _converse#headlinesBoxViewInitialized + * @type { _converse.HeadlinesBoxView } + * @example _converse.api.listen.on('headlinesBoxViewInitialized', view => { ... }); + */ + _converse.api.trigger('headlinesBoxViewInitialized', this); }, render () { diff --git a/src/converse-message-view.js b/src/converse-message-view.js index fd7888e8a..39f6fab31 100644 --- a/src/converse-message-view.js +++ b/src/converse-message-view.js @@ -103,10 +103,6 @@ converse.plugins.add('converse-message-view', { } }, 50); - if (this.model.vcard) { - this.listenTo(this.model.vcard, 'change', this.debouncedRender); - } - if (this.model.rosterContactAdded) { this.model.rosterContactAdded.then(() => { this.listenTo(this.model.contact, 'change:nickname', this.debouncedRender); @@ -122,6 +118,7 @@ converse.plugins.add('converse-message-view', { this.listenTo(this.model, 'change', this.onChanged); this.listenTo(this.model, 'destroy', this.fadeOut); + this.listenTo(this.model, 'vcard:change', this.debouncedRender); }, async render () { diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js index fbfe434ce..dd7f98d01 100644 --- a/src/converse-muc-views.js +++ b/src/converse-muc-views.js @@ -688,13 +688,12 @@ converse.plugins.add('converse-muc-views', { await this.updateAfterMessagesFetched(); this.onConnectionStatusChanged(); /** - * Triggered once a groupchat has been opened - * @event _converse#chatRoomOpened + * Triggered once a { @link _converse.ChatRoomView } has been opened + * @event _converse#chatRoomViewInitialized * @type { _converse.ChatRoomView } - * @example _converse.api.listen.on('chatRoomOpened', view => { ... }); + * @example _converse.api.listen.on('chatRoomViewInitialized', view => { ... }); */ - _converse.api.trigger('chatRoomOpened', this); - _converse.api.trigger('chatBoxInitialized', this); + _converse.api.trigger('chatRoomViewInitialized', this); }, render () { @@ -1707,7 +1706,7 @@ converse.plugins.add('converse-muc-views', { } }, - insertDayIndicator (next_msg_el) { + insertDayIndicator () { this.removeEmptyHistoryFeedback(); return _converse.ChatBoxView.prototype.insertDayIndicator.apply(this, arguments); }, diff --git a/src/converse-rosterview.js b/src/converse-rosterview.js index bd21a955a..97f9779d5 100644 --- a/src/converse-rosterview.js +++ b/src/converse-rosterview.js @@ -339,14 +339,14 @@ converse.plugins.add('converse-rosterview', { async initialize () { await this.model.initialized; - this.listenTo(this.model, "change", this.render); - this.listenTo(this.model, "highlight", this.highlight); + this.debouncedRender = debounce(this.render, 50); + this.listenTo(this.model, "change", this.debouncedRender); this.listenTo(this.model, "destroy", this.remove); + this.listenTo(this.model, "highlight", this.highlight); this.listenTo(this.model, "open", this.openChat); this.listenTo(this.model, "remove", this.remove); - - this.listenTo(this.model.presence, "change:show", this.render); - this.listenTo(this.model.vcard, 'change:fullname', this.render); + this.listenTo(this.model, 'vcard:change', this.debouncedRender); + this.listenTo(this.model.presence, "change:show", this.debouncedRender); this.render(); }, diff --git a/src/headless/converse-chat.js b/src/headless/converse-chat.js index 17205b2d5..8550d12f3 100644 --- a/src/headless/converse-chat.js +++ b/src/headless/converse-chat.js @@ -89,6 +89,12 @@ converse.plugins.add('converse-chat', { this.on('change:put', this.uploadFile, this); } this.setTimerForEphemeralMessage(); + /** + * Triggered once a {@link _converse.Message} has been created and initialized. + * @event _converse#messageInitialized + * @type { _converse.Message} + * @example _converse.api.listen.on('messageInitialized', model => { ... }); + */ await _converse.api.trigger('messageInitialized', this, {'Synchronous': true}); this.initialized.resolve(); }, @@ -298,9 +304,6 @@ converse.plugins.add('converse-chat', { } this.set({'box_id': `box-${btoa(jid)}`}); - if (_converse.vcards) { - this.vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid}); - } if (this.get('type') === _converse.PRIVATE_CHAT_TYPE) { this.presence = _converse.presences.findWhere({'jid': jid}) || _converse.presences.create({'jid': jid}); await this.setRosterContact(jid); @@ -308,6 +311,13 @@ converse.plugins.add('converse-chat', { this.on('change:chat_state', this.sendChatState, this); this.initMessages(); await this.fetchMessages(); + /** + * Triggered once a {@link _converse.ChatBox} has been created and initialized. + * @event _converse#chatBoxInitialized + * @type { _converse.ChatBox} + * @example _converse.api.listen.on('chatBoxInitialized', model => { ... }); + */ + await _converse.api.trigger('chatBoxInitialized', this, {'Synchronous': true}); this.initialized.resolve(); }, diff --git a/src/headless/converse-mam.js b/src/headless/converse-mam.js index c1d19a564..cba5e2242 100644 --- a/src/headless/converse-mam.js +++ b/src/headless/converse-mam.js @@ -235,7 +235,7 @@ converse.plugins.add('converse-mam', { /************************ BEGIN Event Handlers ************************/ _converse.api.listen.on('addClientFeatures', () => _converse.api.disco.own.features.add(Strophe.NS.MAM)); _converse.api.listen.on('serviceDiscovered', getMAMPrefsFromFeature); - _converse.api.listen.on('chatRoomOpened', view => { + _converse.api.listen.on('chatRoomViewInitialized', view => { if (_converse.muc_show_logs_before_join) { // If we want to show MAM logs before entering the MUC, we need // to be informed once it's clear that this MUC supports MAM. diff --git a/src/headless/converse-muc.js b/src/headless/converse-muc.js index c6aba5283..25fdd96e6 100644 --- a/src/headless/converse-muc.js +++ b/src/headless/converse-muc.js @@ -249,8 +249,14 @@ converse.plugins.add('converse-muc', { } if (!this.setTimerForEphemeralMessage()) { this.setOccupant(); - this.setVCard(); } + /** + * Triggered once a {@link _converse.ChatRoomMessageInitialized} has been created and initialized. + * @event _converse#chatRoomMessageInitialized + * @type { _converse.ChatRoomMessages} + * @example _converse.api.listen.on('chatRoomMessageInitialized', model => { ... }); + */ + _converse.api.trigger('chatRoomMessageInitialized', this); }, onOccupantRemoved () { @@ -288,37 +294,7 @@ converse.plugins.add('converse-muc', { } else { this.listenTo(chatbox.occupants, 'add', this.onOccupantAdded); } - - }, - - getVCardForChatroomOccupant () { - const chatbox = get(this, 'collection.chatbox'); - const nick = Strophe.getResourceFromJid(this.get('from')); - - if (chatbox && chatbox.get('nick') === nick) { - return _converse.xmppstatus.vcard; - } else { - const jid = this.occupant && this.occupant.get('jid') || this.get('from'); - if (jid) { - return _converse.vcards.findWhere({jid}) || _converse.vcards.create({jid}); - } else { - log.error(`Could not assign VCard for message because no JID found! msgid: ${this.get('msgid')}`); - return; - } - } - }, - - async setVCard () { - await _converse.api.waitUntil('VCardsInitialized'); - if (!_converse.vcards) { - return; // VCards aren't supported - } - if (['error', 'info'].includes(this.get('type'))) { - return; - } else { - this.vcard = this.getVCardForChatroomOccupant(); - } - }, + } }); @@ -378,10 +354,9 @@ converse.plugins.add('converse-muc', { } }, - async initialize() { + async initialize () { this.initialized = u.getResolveablePromise(); - this.setVCard(); this.set('box_id', `box-${btoa(this.get('jid'))}`); await this.restoreSession(); @@ -397,17 +372,16 @@ converse.plugins.add('converse-muc', { if (!restored) { this.join(); } + /** + * Triggered once a {@link _converse.ChatRoom} has been created and initialized. + * @event _converse#chatRoomInitialized + * @type { _converse.ChatRoom } + * @example _converse.api.listen.on('chatRoomInitialized', model => { ... }); + */ + await _converse.api.trigger('chatRoomInitialized', this, {'Synchronous': true}); this.initialized.resolve(); }, - async setVCard () { - await _converse.api.waitUntil('VCardsInitialized'); - if (_converse.vcards) { - this.vcard = _converse.vcards.findWhere({'jid': this.get('jid')}) || - _converse.vcards.create({'jid': this.get('jid')}); - } - }, - /** * Checks whether we're still joined and if so, restores the MUC state from cache. * @private diff --git a/src/headless/converse-vcard.js b/src/headless/converse-vcard.js index 641c2f301..ff4f23fbb 100644 --- a/src/headless/converse-vcard.js +++ b/src/headless/converse-vcard.js @@ -9,8 +9,9 @@ import "./converse-status"; import converse from "./converse-core"; import tpl_vcard from "./templates/vcard.html"; +import { get, has, isString } from "lodash"; -const { Backbone, Strophe, _, $iq, dayjs, } = converse.env; +const { Backbone, Strophe, $iq, dayjs } = converse.env; const u = converse.env.utils; @@ -84,7 +85,7 @@ converse.plugins.add('converse-vcard', { } else { (attrs = {})[key] = val; } - if (_.has(attrs, 'image') && !attrs['image']) { + if (has(attrs, 'image') && !attrs['image']) { attrs['image'] = _converse.DEFAULT_IMAGE; attrs['image_type'] = _converse.DEFAULT_IMAGE_TYPE; return Backbone.Model.prototype.set.call(this, attrs, options); @@ -116,13 +117,13 @@ converse.plugins.add('converse-vcard', { if (vcard !== null) { result = { 'stanza': iq, - 'fullname': _.get(vcard.querySelector('FN'), 'textContent'), - 'nickname': _.get(vcard.querySelector('NICKNAME'), 'textContent'), - 'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'), - 'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'), - 'url': _.get(vcard.querySelector('URL'), 'textContent'), - 'role': _.get(vcard.querySelector('ROLE'), 'textContent'), - 'email': _.get(vcard.querySelector('EMAIL USERID'), 'textContent'), + 'fullname': get(vcard.querySelector('FN'), 'textContent'), + 'nickname': get(vcard.querySelector('NICKNAME'), 'textContent'), + 'image': get(vcard.querySelector('PHOTO BINVAL'), 'textContent'), + 'image_type': get(vcard.querySelector('PHOTO TYPE'), 'textContent'), + 'url': get(vcard.querySelector('URL'), 'textContent'), + 'role': get(vcard.querySelector('ROLE'), 'textContent'), + 'email': get(vcard.querySelector('EMAIL USERID'), 'textContent'), 'vcard_updated': (new Date()).toISOString(), 'vcard_error': undefined }; @@ -135,6 +136,7 @@ converse.plugins.add('converse-vcard', { return result; } + function createStanza (type, jid, vcard_el) { const iq = $iq(jid ? {'type': type, 'to': jid} : {'type': type}); if (!vcard_el) { @@ -145,6 +147,7 @@ converse.plugins.add('converse-vcard', { return iq; } + async function getVCard (_converse, jid) { const to = Strophe.getBareJidFromJid(jid) === _converse.bare_jid ? null : jid; let iq; @@ -160,7 +163,54 @@ converse.plugins.add('converse-vcard', { return onVCardData(jid, iq); } - /************************ BEGIN Event Handlers ************************/ + + async function setVCardOnModel (model) { + let jid; + if (model instanceof _converse.Message) { + if (model.get('type') === 'error') { + return; + } + jid = model.get('from'); + } else { + jid = model.get('jid'); + } + await _converse.api.waitUntil('VCardsInitialized'); + model.vcard = _converse.vcards.findWhere({'jid': jid}); + if (!model.vcard) { + model.vcard = _converse.vcards.create({'jid': jid}); + } + model.vcard.on('change', () => model.trigger('vcard:change')); + } + + + function getVCardForChatroomOccupant (message) { + const chatbox = get(message, 'collection.chatbox'); + const nick = Strophe.getResourceFromJid(message.get('from')); + + if (chatbox && chatbox.get('nick') === nick) { + return _converse.xmppstatus.vcard; + } else { + const jid = message.occupant && message.occupant.get('jid') || message.get('from'); + if (jid) { + return _converse.vcards.findWhere({jid}) || _converse.vcards.create({jid}); + } else { + log.error(`Could not assign VCard for message because no JID found! msgid: ${message.get('msgid')}`); + return; + } + } + } + + + async function setVCardOnMUCMessage (message) { + await _converse.api.waitUntil('VCardsInitialized'); + if (['error', 'info'].includes(message.get('type'))) { + return; + } else { + message.vcard = getVCardForChatroomOccupant(message); + } + } + + _converse.initVCardCollection = async function () { _converse.vcards = new _converse.VCards(); _converse.vcards.browserStorage = _converse.createStore(`${_converse.bare_jid}-converse.vcards`); @@ -182,9 +232,8 @@ converse.plugins.add('converse-vcard', { _converse.api.trigger('VCardsInitialized'); } - _converse.api.listen.on('statusInitialized', _converse.initVCardCollection); - _converse.api.listen.on('clearSession', () => { + function clearVCardsSession () { if (_converse.shouldClearCache()) { _converse.api.promises.add('VCardsInitialized'); if (_converse.vcards) { @@ -192,30 +241,19 @@ converse.plugins.add('converse-vcard', { delete _converse.vcards; } } - }); - - - _converse.api.listen.on('addClientFeatures', () => _converse.api.disco.own.features.add(Strophe.NS.VCARD)); - - - async function setVCardOnModel (model) { - let jid; - if (model instanceof _converse.Message) { - if (model.get('type') === 'error') { - return; - } - jid = model.get('from'); - } else { - jid = model.get('jid'); - } - await _converse.api.waitUntil('VCardsInitialized'); - model.vcard = _converse.vcards.findWhere({'jid': jid}); - if (!model.vcard) { - model.vcard = _converse.vcards.create({'jid': jid}); - } } - _converse.api.listen.on('rosterContactInitialized', m => setVCardOnModel(m)); + + + /************************ BEGIN Event Handlers ************************/ + + _converse.api.listen.on('chatBoxInitialized', m => setVCardOnModel(m)); + _converse.api.listen.on('chatRoomInitialized', m => setVCardOnModel(m)); + _converse.api.listen.on('chatRoomMessageInitialized', m => setVCardOnMUCMessage(m)); + _converse.api.listen.on('addClientFeatures', () => _converse.api.disco.own.features.add(Strophe.NS.VCARD)); + _converse.api.listen.on('clearSession', () => clearVCardsSession()); _converse.api.listen.on('messageInitialized', m => setVCardOnModel(m)); + _converse.api.listen.on('rosterContactInitialized', m => setVCardOnModel(m)); + _converse.api.listen.on('statusInitialized', _converse.initVCardCollection); /************************ BEGIN API ************************/ @@ -275,7 +313,7 @@ converse.plugins.add('converse-vcard', { * }); */ get (model, force) { - if (_.isString(model)) { + if (isString(model)) { return getVCard(_converse, model); } else if (force || !model.get('vcard_updated') ||