From e18fe5e21219d747b6613bfad10d92882eaf31db Mon Sep 17 00:00:00 2001 From: JC Brand Date: Mon, 6 Apr 2020 17:21:38 +0200 Subject: [PATCH] Use the `getHeadingButtons` hook instead of overrides --- spec/headline.js | 2 +- src/converse-bookmark-views.js | 48 +++++++++------------- src/converse-chatview.js | 22 +++++++--- src/converse-headlines-view.js | 23 +++++++++++ src/converse-minimize.js | 74 +++++++++++++++++----------------- src/converse-muc-views.js | 11 ++++- 6 files changed, 107 insertions(+), 73 deletions(-) diff --git a/spec/headline.js b/spec/headline.js index aaf5e8513..c24f96701 100644 --- a/spec/headline.js +++ b/spec/headline.js @@ -150,7 +150,7 @@ await u.waitUntil(() => cbview.el.querySelectorAll(".open-headline").length); const hlview = _converse.chatboxviews.get('notify.example.com'); await u.isVisible(hlview.el); - const close_el = hlview.el.querySelector('.close-chatbox-button'); + const close_el = await u.waitUntil(() => hlview.el.querySelector('.close-chatbox-button')); close_el.click(); await u.waitUntil(() => cbview.el.querySelectorAll(".open-headline").length === 0); expect(cbview.el.querySelectorAll('.open-headline').length).toBe(0); diff --git a/src/converse-bookmark-views.js b/src/converse-bookmark-views.js index ce9f66daf..8a61af033 100644 --- a/src/converse-bookmark-views.js +++ b/src/converse-bookmark-views.js @@ -31,35 +31,6 @@ converse.plugins.add('converse-bookmark-views', { */ dependencies: ["converse-chatboxes", "converse-muc", "converse-muc-views"], - overrides: { - // Overrides mentioned here will be picked up by converse.js's - // plugin architecture they will replace existing methods on the - // relevant objects or classes. - ChatRoomView: { - getHeadingButtons () { - const { _converse } = this.__super__; - const buttons = this.__super__.getHeadingButtons.apply(this, arguments); - if (_converse.allow_bookmarks) { - const supported = _converse.checkBookmarksSupport(); - const bookmarked = this.model.get('bookmarked'); - const data = { - 'i18n_title': bookmarked ? __('Unbookmark this groupchat') : __('Bookmark this groupchat'), - 'i18n_text': bookmarked ? __('Unbookmark') : __('Bookmark'), - 'handler': ev => this.toggleBookmark(ev), - 'a_class': 'toggle-bookmark', - 'icon_class': 'fa-bookmark', - 'name': 'bookmark' - } - const names = buttons.map(t => t.name); - const idx = names.indexOf('details'); - const data_promise = supported.then(s => s ? data : ''); - return idx > -1 ? [...buttons.slice(0, idx), data_promise, ...buttons.slice(idx)] : [data_promise, ...buttons]; - } - return buttons; - } - } - }, - initialize () { /* The initialize function gets called as soon as the plugin is * loaded by converse.js's plugin machinery. @@ -266,6 +237,25 @@ converse.plugins.add('converse-bookmark-views', { api.trigger('bookmarkViewsInitialized'); } + api.listen.on('getHeadingButtons', (view, buttons) => { + if (_converse.allow_bookmarks && view.model.get('type') === _converse.CHATROOMS_TYPE) { + const bookmarked = view.model.get('bookmarked'); + const data = { + 'i18n_title': bookmarked ? __('Unbookmark this groupchat') : __('Bookmark this groupchat'), + 'i18n_text': bookmarked ? __('Unbookmark') : __('Bookmark'), + 'handler': ev => view.toggleBookmark(ev), + 'a_class': 'toggle-bookmark', + 'icon_class': 'fa-bookmark', + 'name': 'bookmark' + } + const names = buttons.map(t => t.name); + const idx = names.indexOf('details'); + const data_promise = _converse.checkBookmarksSupport().then(s => s ? data : ''); + return idx > -1 ? [...buttons.slice(0, idx), data_promise, ...buttons.slice(idx)] : [data_promise, ...buttons]; + } + return buttons; + }); + api.listen.on('bookmarksInitialized', initBookmarkViews); api.listen.on('chatRoomViewInitialized', view => view.setBookmarkState()); /************************ END Event Handlers ************************/ diff --git a/src/converse-chatview.js b/src/converse-chatview.js index 84241243c..3895fae18 100644 --- a/src/converse-chatview.js +++ b/src/converse-chatview.js @@ -383,8 +383,9 @@ converse.plugins.add('converse-chatview', { } }, - renderHeading () { - render(this.generateHeadingTemplate(), this.el.querySelector('.chat-head-chatbox')); + async renderHeading () { + const tpl = await this.generateHeadingTemplate(); + render(tpl, this.el.querySelector('.chat-head-chatbox')); }, async getHeadingStandaloneButton (promise_or_data) { @@ -403,10 +404,10 @@ converse.plugins.add('converse-chatview', { title="${data.i18n_title}">${data.i18n_text}`; }, - generateHeadingTemplate () { + async generateHeadingTemplate () { const vcard = this.model?.vcard; const vcard_json = vcard ? vcard.toJSON() : {}; - const heading_btns = this.getHeadingButtons(); + const heading_btns = await this.getHeadingButtons(); const standalone_btns = heading_btns.filter(b => b.standalone); const dropdown_btns = heading_btns.filter(b => !b.standalone); return tpl_chatbox_head( @@ -422,6 +423,13 @@ converse.plugins.add('converse-chatview', { ); }, + /** + * Returns a list of objects which represent buttons for the chat's header. + * @async + * @emits _converse#getHeadingButtons + * @private + * @method _converse.ChatBoxView#getHeadingButtons + */ getHeadingButtons () { const buttons = [{ 'a_class': 'show-user-details-modal', @@ -443,7 +451,11 @@ converse.plugins.add('converse-chatview', { 'standalone': api.settings.get("view_mode") === 'overlayed', }); } - return buttons; + /** + * *Hook* which allows plugins to add more buttons to a chat's heading. + * @event _converse#getHeadingButtons + */ + return _converse.api.hook('getHeadingButtons', this, buttons); }, getToolbarOptions () { diff --git a/src/converse-headlines-view.js b/src/converse-headlines-view.js index b127de355..a394ccc73 100644 --- a/src/converse-headlines-view.js +++ b/src/converse-headlines-view.js @@ -171,6 +171,29 @@ converse.plugins.add('converse-headlines-view', { return this; }, + /** + * Returns a list of objects which represent buttons for the headlines header. + * @async + * @emits _converse#getHeadingButtons + * @private + * @method _converse.HeadlinesBoxView#getHeadingButtons + */ + getHeadingButtons () { + const buttons = []; + if (!api.settings.get("singleton")) { + buttons.push({ + 'a_class': 'close-chatbox-button', + 'handler': ev => this.close(ev), + 'i18n_text': __('Close'), + 'i18n_title': __('Close these announcements'), + 'icon_class': 'fa-times', + 'name': 'close', + 'standalone': api.settings.get("view_mode") === 'overlayed', + }); + } + return _converse.api.hook('getHeadingButtons', this, buttons); + }, + // Override to avoid the methods in converse-chatview.js 'renderMessageForm': function renderMessageForm () {}, 'afterShown': function afterShown () {} diff --git a/src/converse-minimize.js b/src/converse-minimize.js index c5c9817bc..31b436d12 100644 --- a/src/converse-minimize.js +++ b/src/converse-minimize.js @@ -105,42 +105,6 @@ converse.plugins.add('converse-minimize', { return this.__super__.setChatBoxWidth.call(this, width); } }, - - getHeadingButtons () { - const { _converse } = this.__super__; - const buttons = this.__super__.getHeadingButtons.call(this); - const data = { - 'a_class': 'toggle-chatbox-button', - 'handler': ev => this.minimize(ev), - 'i18n_text': __('Minimize'), - 'i18n_title': __('Minimize this chat'), - 'icon_class': "fa-minus", - 'name': 'minimize', - 'standalone': _converse.api.settings.get("view_mode") === 'overlayed' - } - const names = buttons.map(t => t.name); - const idx = names.indexOf('close'); - return idx > -1 ? [...buttons.slice(0, idx), data, ...buttons.slice(idx)] : [data, ...buttons]; - } - }, - - ChatRoomView: { - getHeadingButtons () { - const { _converse } = this.__super__; - const buttons = this.__super__.getHeadingButtons.apply(this, arguments); - const data = { - 'a_class': 'toggle-chatbox-button', - 'handler': ev => this.minimize(ev), - 'i18n_text': __('Minimize'), - 'i18n_title': __('Minimize this groupchat'), - 'icon_class': "fa-minus", - 'name': 'minimize', - 'standalone': _converse.api.settings.get("view_mode") === 'overlayed' - } - const names = buttons.map(t => t.name); - const idx = names.indexOf('signout'); - return idx > -1 ? [...buttons.slice(0, idx), data, ...buttons.slice(idx)] : [data, ...buttons]; - } } }, @@ -551,6 +515,36 @@ converse.plugins.add('converse-minimize', { api.trigger('minimizedChatsInitialized'); } + function addMinimizeButtonToChat (view, buttons) { + const data = { + 'a_class': 'toggle-chatbox-button', + 'handler': ev => view.minimize(ev), + 'i18n_text': __('Minimize'), + 'i18n_title': __('Minimize this chat'), + 'icon_class': "fa-minus", + 'name': 'minimize', + 'standalone': _converse.api.settings.get("view_mode") === 'overlayed' + } + const names = buttons.map(t => t.name); + const idx = names.indexOf('close'); + return idx > -1 ? [...buttons.slice(0, idx), data, ...buttons.slice(idx)] : [data, ...buttons]; + } + + function addMinimizeButtonToMUC (view, buttons) { + const data = { + 'a_class': 'toggle-chatbox-button', + 'handler': ev => view.minimize(ev), + 'i18n_text': __('Minimize'), + 'i18n_title': __('Minimize this groupchat'), + 'icon_class': "fa-minus", + 'name': 'minimize', + 'standalone': _converse.api.settings.get("view_mode") === 'overlayed' + } + const names = buttons.map(t => t.name); + const idx = names.indexOf('signout'); + return idx > -1 ? [...buttons.slice(0, idx), data, ...buttons.slice(idx)] : [data, ...buttons]; + } + /************************ BEGIN Event Handlers ************************/ api.listen.on('chatBoxInsertedIntoDOM', view => _converse.chatboxviews.trimChats(view)); api.listen.on('chatBoxViewsInitialized', () => initMinimizedChats()); @@ -562,6 +556,14 @@ converse.plugins.add('converse-minimize', { view.model.get('minimized') && view.hide(); }); + api.listen.on('getHeadingButtons', (view, buttons) => { + if (view.model.get('type') === _converse.CHATROOMS_TYPE) { + return addMinimizeButtonToMUC(view, buttons); + } else { + return addMinimizeButtonToChat(view, buttons); + } + }); + const debouncedTrimChats = debounce(() => _converse.chatboxviews.trimChats(), 250); api.listen.on('registeredGlobalEventHandlers', () => window.addEventListener("resize", debouncedTrimChats)); api.listen.on('unregisteredGlobalEventHandlers', () => window.removeEventListener("resize", debouncedTrimChats)); diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js index 5fb0da35c..3165fc26f 100644 --- a/src/converse-muc-views.js +++ b/src/converse-muc-views.js @@ -1174,6 +1174,13 @@ converse.plugins.add('converse-muc-views', { } }, + /** + * Returns a list of objects which represent buttons for the groupchat header. + * @async + * @emits _converse#getHeadingButtons + * @private + * @method _converse.ChatRoomView#getHeadingButtons + */ getHeadingButtons (subject_hidden) { const buttons = [{ 'i18n_text': __('Details'), @@ -1259,7 +1266,7 @@ converse.plugins.add('converse-muc-views', { 'name': 'signout' }); } - return buttons; + return _converse.api.hook('getHeadingButtons', this, buttons); }, /** @@ -1270,7 +1277,7 @@ converse.plugins.add('converse-muc-views', { async generateHeadingTemplate () { const jids = await api.user.settings.get('mucs_with_hidden_subject', []) const subject_hidden = jids.includes(this.model.get('jid')); - const heading_btns = this.getHeadingButtons(subject_hidden); + const heading_btns = await this.getHeadingButtons(subject_hidden); const standalone_btns = heading_btns.filter(b => b.standalone); const dropdown_btns = heading_btns.filter(b => !b.standalone); return tpl_chatroom_head(