Browse Source

Move converse-bookmarks plugin into folder

JC Brand 4 years ago
parent
commit
9a2678450a

+ 1 - 1
src/headless/headless.js

@@ -3,7 +3,7 @@
  * Any of the following components may be removed if they're not needed.
  */
 import "./plugins/adhoc.js";       // XEP-0050 Ad Hoc Commands
-import "./plugins/bookmarks.js";   // XEP-0199 XMPP Ping
+import "./plugins/bookmarks/index.js";   // XEP-0199 XMPP Ping
 import "./plugins/bosh.js";        // XEP-0206 BOSH
 import "./plugins/caps.js";        // XEP-0115 Entity Capabilities
 import "./plugins/carbons.js";     // XEP-0280 Message Carbons

+ 0 - 330
src/headless/plugins/bookmarks.js

@@ -1,330 +0,0 @@
-/**
- * @module converse-bookmarks
- * @description
- * Converse.js plugin which adds views for bookmarks specified in XEP-0048.
- * @copyright 2020, the Converse.js contributors
- * @license Mozilla Public License (MPLv2)
- */
-import "@converse/headless/plugins/muc/index.js";
-import log from "../log.js";
-import { Collection } from "@converse/skeletor/src/collection";
-import { Model } from '@converse/skeletor/src/model.js';
-import { _converse, api, converse } from "@converse/headless/core";
-
-const { Strophe, $iq, sizzle } = converse.env;
-const u = converse.env.utils;
-
-Strophe.addNamespace('BOOKMARKS', 'storage:bookmarks');
-
-
-function handleBookmarksPush (message) {
-    if (sizzle(`event[xmlns="${Strophe.NS.PUBSUB}#event"] items[node="${Strophe.NS.BOOKMARKS}"]`, message).length) {
-        api.waitUntil('bookmarksInitialized')
-            .then(() => _converse.bookmarks.createBookmarksFromStanza(message))
-            .catch(e => log.fatal(e));
-    }
-    return true;
-}
-
-
-converse.plugins.add('converse-bookmarks', {
-
-    /* Plugin dependencies are other plugins which might be
-     * overridden or relied upon, and therefore need to be loaded before
-     * this plugin.
-     *
-     * If the setting "strict_plugin_dependencies" is set to true,
-     * an error will be raised if the plugin is not found. By default it's
-     * false, which means these plugins are only loaded opportunistically.
-     *
-     * NB: These plugins need to have already been loaded via require.js.
-     */
-    dependencies: ["converse-chatboxes", "converse-muc"],
-
-    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.
-        //
-        // New functions which don't exist yet can also be added.
-
-        ChatRoom: {
-            getDisplayName () {
-                const { _converse } = this.__super__;
-                if (this.get('bookmarked') && _converse.bookmarks) {
-                    const bookmark = _converse.bookmarks.findWhere({'jid': this.get('jid')});
-                    if (bookmark) {
-                        return bookmark.get('name');
-                    }
-                }
-                return this.__super__.getDisplayName.apply(this, arguments);
-            },
-
-            getAndPersistNickname (nick) {
-                const { _converse } = this.__super__;
-                nick = nick || _converse.getNicknameFromBookmark(this.get('jid'));
-                return this.__super__.getAndPersistNickname.call(this, nick);
-            }
-        }
-    },
-
-    initialize () {
-        /* The initialize function gets called as soon as the plugin is
-         * loaded by converse.js's plugin machinery.
-         */
-        const { __ } = _converse;
-
-        // Configuration values for this plugin
-        // ====================================
-        // Refer to docs/source/configuration.rst for explanations of these
-        // configuration settings.
-        api.settings.extend({
-            allow_bookmarks: true,
-            allow_public_bookmarks: false,
-            muc_respect_autojoin: true
-        });
-
-        api.promises.add('bookmarksInitialized');
-
-        /**
-          * Check if the user has a bookmark with a saved nickanme
-          * for this groupchat and return it.
-          * @private
-          * @method _converse#getNicknameFromBookmark
-          */
-        _converse.getNicknameFromBookmark = function (jid) {
-            if (!_converse.bookmarks || !api.settings.get('allow_bookmarks')) {
-                return null;
-            }
-            const bookmark = _converse.bookmarks.findWhere({'jid': jid});
-            if (bookmark) {
-                return bookmark.get('nick');
-            }
-        }
-
-        _converse.Bookmark = Model.extend({
-            idAttribute: 'jid',
-            getDisplayName () {
-                return Strophe.xmlunescape(this.get('name'));
-            }
-        });
-
-        _converse.Bookmarks = Collection.extend({
-            model: _converse.Bookmark,
-            comparator: (item) => item.get('name').toLowerCase(),
-
-            initialize () {
-                this.on('add', bm => this.openBookmarkedRoom(bm)
-                    .then(bm => this.markRoomAsBookmarked(bm))
-                    .catch(e => log.fatal(e))
-                );
-
-                this.on('remove', this.markRoomAsUnbookmarked, this);
-                this.on('remove', this.sendBookmarkStanza, this);
-
-                const cache_key = `converse.room-bookmarks${_converse.bare_jid}`;
-                this.fetched_flag = cache_key+'fetched';
-                this.browserStorage = _converse.createStore(cache_key);
-            },
-
-            async openBookmarkedRoom (bookmark) {
-                if ( api.settings.get('muc_respect_autojoin') && bookmark.get('autojoin')) {
-                    const groupchat = await api.rooms.create(
-                        bookmark.get('jid'),
-                        {'nick': bookmark.get('nick')}
-                    );
-                    groupchat.maybeShow();
-                }
-                return bookmark;
-            },
-
-            fetchBookmarks () {
-                const deferred = u.getResolveablePromise();
-                if (window.sessionStorage.getItem(this.fetched_flag)) {
-                    this.fetch({
-                        'success': () => deferred.resolve(),
-                        'error': () => deferred.resolve()
-                    });
-                } else {
-                    this.fetchBookmarksFromServer(deferred);
-                }
-                return deferred;
-            },
-
-            createBookmark (options) {
-                this.create(options);
-                this.sendBookmarkStanza().catch(iq => this.onBookmarkError(iq, options));
-            },
-
-            sendBookmarkStanza () {
-                const stanza = $iq({
-                        'type': 'set',
-                        'from': _converse.connection.jid,
-                    })
-                    .c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
-                        .c('publish', {'node': Strophe.NS.BOOKMARKS})
-                            .c('item', {'id': 'current'})
-                                .c('storage', {'xmlns': Strophe.NS.BOOKMARKS});
-                this.forEach(model => {
-                    stanza.c('conference', {
-                        'name': model.get('name'),
-                        'autojoin': model.get('autojoin'),
-                        'jid': model.get('jid'),
-                    }).c('nick').t(model.get('nick')).up().up();
-                });
-                stanza.up().up().up();
-                stanza.c('publish-options')
-                    .c('x', {'xmlns': Strophe.NS.XFORM, 'type':'submit'})
-                        .c('field', {'var':'FORM_TYPE', 'type':'hidden'})
-                            .c('value').t('http://jabber.org/protocol/pubsub#publish-options').up().up()
-                        .c('field', {'var':'pubsub#persist_items'})
-                            .c('value').t('true').up().up()
-                        .c('field', {'var':'pubsub#access_model'})
-                            .c('value').t('whitelist');
-                return api.sendIQ(stanza);
-            },
-
-            onBookmarkError (iq, options) {
-                log.error("Error while trying to add bookmark");
-                log.error(iq);
-                api.alert(
-                    'error', __('Error'), [__("Sorry, something went wrong while trying to save your bookmark.")]
-                );
-                this.findWhere({'jid': options.jid}).destroy();
-            },
-
-            fetchBookmarksFromServer (deferred) {
-                const stanza = $iq({
-                    'from': _converse.connection.jid,
-                    'type': 'get',
-                }).c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
-                    .c('items', {'node': Strophe.NS.BOOKMARKS});
-                api.sendIQ(stanza)
-                    .then(iq => this.onBookmarksReceived(deferred, iq))
-                    .catch(iq => this.onBookmarksReceivedError(deferred, iq)
-                );
-            },
-
-            markRoomAsBookmarked (bookmark) {
-                const groupchat = _converse.chatboxes.get(bookmark.get('jid'));
-                if (groupchat !== undefined) {
-                    groupchat.save('bookmarked', true);
-                }
-            },
-
-            markRoomAsUnbookmarked (bookmark) {
-                const groupchat = _converse.chatboxes.get(bookmark.get('jid'));
-                if (groupchat !== undefined) {
-                    groupchat.save('bookmarked', false);
-                }
-            },
-
-            createBookmarksFromStanza (stanza) {
-                const xmlns = Strophe.NS.BOOKMARKS;
-                const sel = `items[node="${xmlns}"] item storage[xmlns="${xmlns}"] conference`;
-                sizzle(sel, stanza).forEach(el => {
-                    const jid = el.getAttribute('jid');
-                    const bookmark = this.get(jid);
-                    const attrs = {
-                        'jid': jid,
-                        'name': el.getAttribute('name') || jid,
-                        'autojoin': el.getAttribute('autojoin') === 'true',
-                        'nick': el.querySelector('nick')?.textContent || ''
-                    }
-                    bookmark ? bookmark.save(attrs) : this.create(attrs);
-                });
-            },
-
-            onBookmarksReceived (deferred, iq) {
-                this.createBookmarksFromStanza(iq);
-                window.sessionStorage.setItem(this.fetched_flag, true);
-                if (deferred !== undefined) {
-                    return deferred.resolve();
-                }
-            },
-
-            onBookmarksReceivedError (deferred, iq) {
-                if (iq === null) {
-                    log.error('Error: timeout while fetching bookmarks');
-                    api.alert('error', __('Timeout Error'),
-                        [__("The server did not return your bookmarks within the allowed time. "+
-                            "You can reload the page to request them again.")]
-                    );
-                } else if (deferred) {
-                    if (iq.querySelector('error[type="cancel"] item-not-found')) {
-                        // Not an exception, the user simply doesn't have any bookmarks.
-                        window.sessionStorage.setItem(this.fetched_flag, true);
-                        return deferred.resolve();
-                    } else {
-                        log.error('Error while fetching bookmarks');
-                        log.error(iq);
-                        return deferred.reject(new Error("Could not fetch bookmarks"));
-                    }
-                } else {
-                    log.error('Error while fetching bookmarks');
-                    log.error(iq);
-                }
-            },
-
-            getUnopenedBookmarks () {
-                return this.filter(b => !_converse.chatboxes.get(b.get('jid')));
-            }
-        });
-
-        _converse.BookmarksList = Model.extend({
-            defaults: {
-                "toggle-state":  _converse.OPENED
-            }
-        });
-
-        _converse.checkBookmarksSupport = async function () {
-            const identity = await api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid);
-            if (_converse.allow_public_bookmarks) {
-                return !!identity;
-            } else {
-                return api.disco.supports(Strophe.NS.PUBSUB+'#publish-options', _converse.bare_jid);
-            }
-        }
-
-        const initBookmarks = async function () {
-            if (!api.settings.get('allow_bookmarks')) {
-                return;
-            }
-            if (await _converse.checkBookmarksSupport()) {
-                _converse.bookmarks = new _converse.Bookmarks();
-                await _converse.bookmarks.fetchBookmarks();
-                /**
-                 * Triggered once the _converse.Bookmarks collection
-                 * has been created and cached bookmarks have been fetched.
-                 * @event _converse#bookmarksInitialized
-                 * @example _converse.api.listen.on('bookmarksInitialized', () => { ... });
-                 */
-                api.trigger('bookmarksInitialized');
-            }
-        }
-
-        api.listen.on('addClientFeatures', () => {
-            if (api.settings.get('allow_bookmarks')) {
-                api.disco.own.features.add(Strophe.NS.BOOKMARKS + '+notify')
-            }
-        })
-
-        api.listen.on('clearSession', () => {
-            if (_converse.bookmarks !== undefined) {
-                _converse.bookmarks.clearStore({'silent': true});
-                window.sessionStorage.removeItem(_converse.bookmarks.fetched_flag);
-                delete _converse.bookmarks;
-            }
-        });
-
-        api.listen.on('reconnected', initBookmarks);
-
-        api.listen.on('connected', async () =>  {
-            // Add a handler for bookmarks pushed from other connected clients
-            const { connection } = _converse;
-            connection.addHandler(handleBookmarksPush, null, 'message', 'headline', null, _converse.bare_jid);
-            await Promise.all([api.waitUntil('chatBoxesFetched')]);
-            initBookmarks();
-        });
-    }
-});

+ 176 - 0
src/headless/plugins/bookmarks/collection.js

@@ -0,0 +1,176 @@
+import "@converse/headless/plugins/muc/index.js";
+import log from "@converse/headless/log.js";
+import { __ } from 'i18n';
+import { _converse, api, converse } from "@converse/headless/core";
+
+const { Strophe, $iq, sizzle } = converse.env;
+const u = converse.env.utils;
+
+
+const Bookmarks = {
+
+    comparator: (item) => item.get('name').toLowerCase(),
+
+    initialize () {
+        this.on('add', bm => this.openBookmarkedRoom(bm)
+            .then(bm => this.markRoomAsBookmarked(bm))
+            .catch(e => log.fatal(e))
+        );
+
+        this.on('remove', this.markRoomAsUnbookmarked, this);
+        this.on('remove', this.sendBookmarkStanza, this);
+
+        const cache_key = `converse.room-bookmarks${_converse.bare_jid}`;
+        this.fetched_flag = cache_key+'fetched';
+        this.browserStorage = _converse.createStore(cache_key);
+    },
+
+    model (attrs, options) {
+        return new _converse.Bookmark(attrs, options);
+    },
+
+    async openBookmarkedRoom (bookmark) {
+        if ( api.settings.get('muc_respect_autojoin') && bookmark.get('autojoin')) {
+            const groupchat = await api.rooms.create(
+                bookmark.get('jid'),
+                {'nick': bookmark.get('nick')}
+            );
+            groupchat.maybeShow();
+        }
+        return bookmark;
+    },
+
+    fetchBookmarks () {
+        const deferred = u.getResolveablePromise();
+        if (window.sessionStorage.getItem(this.fetched_flag)) {
+            this.fetch({
+                'success': () => deferred.resolve(),
+                'error': () => deferred.resolve()
+            });
+        } else {
+            this.fetchBookmarksFromServer(deferred);
+        }
+        return deferred;
+    },
+
+    createBookmark (options) {
+        this.create(options);
+        this.sendBookmarkStanza().catch(iq => this.onBookmarkError(iq, options));
+    },
+
+    sendBookmarkStanza () {
+        const stanza = $iq({
+                'type': 'set',
+                'from': _converse.connection.jid,
+            })
+            .c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
+                .c('publish', {'node': Strophe.NS.BOOKMARKS})
+                    .c('item', {'id': 'current'})
+                        .c('storage', {'xmlns': Strophe.NS.BOOKMARKS});
+        this.forEach(model => {
+            stanza.c('conference', {
+                'name': model.get('name'),
+                'autojoin': model.get('autojoin'),
+                'jid': model.get('jid'),
+            }).c('nick').t(model.get('nick')).up().up();
+        });
+        stanza.up().up().up();
+        stanza.c('publish-options')
+            .c('x', {'xmlns': Strophe.NS.XFORM, 'type':'submit'})
+                .c('field', {'var':'FORM_TYPE', 'type':'hidden'})
+                    .c('value').t('http://jabber.org/protocol/pubsub#publish-options').up().up()
+                .c('field', {'var':'pubsub#persist_items'})
+                    .c('value').t('true').up().up()
+                .c('field', {'var':'pubsub#access_model'})
+                    .c('value').t('whitelist');
+        return api.sendIQ(stanza);
+    },
+
+    onBookmarkError (iq, options) {
+        log.error("Error while trying to add bookmark");
+        log.error(iq);
+        api.alert(
+            'error', __('Error'), [__("Sorry, something went wrong while trying to save your bookmark.")]
+        );
+        this.findWhere({'jid': options.jid}).destroy();
+    },
+
+    fetchBookmarksFromServer (deferred) {
+        const stanza = $iq({
+            'from': _converse.connection.jid,
+            'type': 'get',
+        }).c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
+            .c('items', {'node': Strophe.NS.BOOKMARKS});
+        api.sendIQ(stanza)
+            .then(iq => this.onBookmarksReceived(deferred, iq))
+            .catch(iq => this.onBookmarksReceivedError(deferred, iq)
+        );
+    },
+
+    markRoomAsBookmarked (bookmark) {
+        const groupchat = _converse.chatboxes.get(bookmark.get('jid'));
+        if (groupchat !== undefined) {
+            groupchat.save('bookmarked', true);
+        }
+    },
+
+    markRoomAsUnbookmarked (bookmark) {
+        const groupchat = _converse.chatboxes.get(bookmark.get('jid'));
+        if (groupchat !== undefined) {
+            groupchat.save('bookmarked', false);
+        }
+    },
+
+    createBookmarksFromStanza (stanza) {
+        const xmlns = Strophe.NS.BOOKMARKS;
+        const sel = `items[node="${xmlns}"] item storage[xmlns="${xmlns}"] conference`;
+        sizzle(sel, stanza).forEach(el => {
+            const jid = el.getAttribute('jid');
+            const bookmark = this.get(jid);
+            const attrs = {
+                'jid': jid,
+                'name': el.getAttribute('name') || jid,
+                'autojoin': el.getAttribute('autojoin') === 'true',
+                'nick': el.querySelector('nick')?.textContent || ''
+            }
+            bookmark ? bookmark.save(attrs) : this.create(attrs);
+        });
+    },
+
+    onBookmarksReceived (deferred, iq) {
+        this.createBookmarksFromStanza(iq);
+        window.sessionStorage.setItem(this.fetched_flag, true);
+        if (deferred !== undefined) {
+            return deferred.resolve();
+        }
+    },
+
+    onBookmarksReceivedError (deferred, iq) {
+        if (iq === null) {
+            log.error('Error: timeout while fetching bookmarks');
+            api.alert('error', __('Timeout Error'),
+                [__("The server did not return your bookmarks within the allowed time. "+
+                    "You can reload the page to request them again.")]
+            );
+        } else if (deferred) {
+            if (iq.querySelector('error[type="cancel"] item-not-found')) {
+                // Not an exception, the user simply doesn't have any bookmarks.
+                window.sessionStorage.setItem(this.fetched_flag, true);
+                return deferred.resolve();
+            } else {
+                log.error('Error while fetching bookmarks');
+                log.error(iq);
+                return deferred.reject(new Error("Could not fetch bookmarks"));
+            }
+        } else {
+            log.error('Error while fetching bookmarks');
+            log.error(iq);
+        }
+    },
+
+    getUnopenedBookmarks () {
+        return this.filter(b => !_converse.chatboxes.get(b.get('jid')));
+    }
+}
+
+export default Bookmarks;

+ 138 - 0
src/headless/plugins/bookmarks/index.js

@@ -0,0 +1,138 @@
+/**
+ * @description
+ * Converse.js plugin which adds views for bookmarks specified in XEP-0048.
+ * @copyright 2020, the Converse.js contributors
+ * @license Mozilla Public License (MPLv2)
+ */
+import "@converse/headless/plugins/muc/index.js";
+import Bookmark from './model.js';
+import Bookmarks from './collection.js';
+import log from "@converse/headless/log.js";
+import { Collection } from "@converse/skeletor/src/collection";
+import { Model } from '@converse/skeletor/src/model.js';
+import { _converse, api, converse } from "@converse/headless/core";
+import { checkBookmarksSupport, getNicknameFromBookmark } from './utils.js';
+
+const { Strophe, sizzle } = converse.env;
+
+Strophe.addNamespace('BOOKMARKS', 'storage:bookmarks');
+
+
+async function initBookmarks () {
+    if (!api.settings.get('allow_bookmarks')) {
+        return;
+    }
+    if (await checkBookmarksSupport()) {
+        _converse.bookmarks = new _converse.Bookmarks();
+        await _converse.bookmarks.fetchBookmarks();
+        /**
+         * Triggered once the _converse.Bookmarks collection
+         * has been created and cached bookmarks have been fetched.
+         * @event _converse#bookmarksInitialized
+         * @example _converse.api.listen.on('bookmarksInitialized', () => { ... });
+         */
+        api.trigger('bookmarksInitialized');
+    }
+}
+
+function handleBookmarksPush (message) {
+    if (sizzle(`event[xmlns="${Strophe.NS.PUBSUB}#event"] items[node="${Strophe.NS.BOOKMARKS}"]`, message).length) {
+        api.waitUntil('bookmarksInitialized')
+            .then(() => _converse.bookmarks.createBookmarksFromStanza(message))
+            .catch(e => log.fatal(e));
+    }
+    return true;
+}
+
+
+converse.plugins.add('converse-bookmarks', {
+
+    /* Plugin dependencies are other plugins which might be
+     * overridden or relied upon, and therefore need to be loaded before
+     * this plugin.
+     *
+     * If the setting "strict_plugin_dependencies" is set to true,
+     * an error will be raised if the plugin is not found. By default it's
+     * false, which means these plugins are only loaded opportunistically.
+     *
+     * NB: These plugins need to have already been loaded via require.js.
+     */
+    dependencies: ["converse-chatboxes", "converse-muc"],
+
+    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.
+        //
+        // New functions which don't exist yet can also be added.
+
+        ChatRoom: {
+            getDisplayName () {
+                const { _converse } = this.__super__;
+                if (this.get('bookmarked') && _converse.bookmarks) {
+                    const bookmark = _converse.bookmarks.findWhere({'jid': this.get('jid')});
+                    if (bookmark) {
+                        return bookmark.get('name');
+                    }
+                }
+                return this.__super__.getDisplayName.apply(this, arguments);
+            },
+
+            getAndPersistNickname (nick) {
+                nick = nick || getNicknameFromBookmark(this.get('jid'));
+                return this.__super__.getAndPersistNickname.call(this, nick);
+            }
+        }
+    },
+
+    initialize () {
+        /* The initialize function gets called as soon as the plugin is
+         * loaded by converse.js's plugin machinery.
+         */
+
+        // Configuration values for this plugin
+        // ====================================
+        // Refer to docs/source/configuration.rst for explanations of these
+        // configuration settings.
+        api.settings.extend({
+            allow_bookmarks: true,
+            allow_public_bookmarks: false,
+            muc_respect_autojoin: true
+        });
+
+        api.promises.add('bookmarksInitialized');
+
+        _converse.Bookmark = Model.extend(Bookmark);
+        _converse.Bookmarks = Collection.extend(Bookmarks);
+
+        _converse.BookmarksList = Model.extend({
+            defaults: {
+                "toggle-state":  _converse.OPENED
+            }
+        });
+
+        api.listen.on('addClientFeatures', () => {
+            if (api.settings.get('allow_bookmarks')) {
+                api.disco.own.features.add(Strophe.NS.BOOKMARKS + '+notify')
+            }
+        })
+
+        api.listen.on('clearSession', () => {
+            if (_converse.bookmarks !== undefined) {
+                _converse.bookmarks.clearStore({'silent': true});
+                window.sessionStorage.removeItem(_converse.bookmarks.fetched_flag);
+                delete _converse.bookmarks;
+            }
+        });
+
+        api.listen.on('reconnected', initBookmarks);
+
+        api.listen.on('connected', async () =>  {
+            // Add a handler for bookmarks pushed from other connected clients
+            const { connection } = _converse;
+            connection.addHandler(handleBookmarksPush, null, 'message', 'headline', null, _converse.bare_jid);
+            await Promise.all([api.waitUntil('chatBoxesFetched')]);
+            initBookmarks();
+        });
+    }
+});

+ 12 - 0
src/headless/plugins/bookmarks/model.js

@@ -0,0 +1,12 @@
+import { converse } from '@converse/headless/core';
+
+const { Strophe } = converse.env;
+
+const Bookmark = {
+    idAttribute: 'jid',
+    getDisplayName () {
+        return Strophe.xmlunescape(this.get('name'));
+    }
+};
+
+export default Bookmark;

+ 25 - 0
src/headless/plugins/bookmarks/utils.js

@@ -0,0 +1,25 @@
+import { _converse, api, converse } from '@converse/headless/core';
+const { Strophe } = converse.env;
+
+export async function checkBookmarksSupport () {
+    const identity = await api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid);
+    if (_converse.allow_public_bookmarks) {
+        return !!identity;
+    } else {
+        return api.disco.supports(Strophe.NS.PUBSUB + '#publish-options', _converse.bare_jid);
+    }
+}
+
+/**
+  * Check if the user has a bookmark with a saved nickanme
+  * for this groupchat and return it.
+  */
+export function getNicknameFromBookmark (jid) {
+    if (!_converse.bookmarks || !api.settings.get('allow_bookmarks')) {
+        return null;
+    }
+    const bookmark = _converse.bookmarks.findWhere({'jid': jid});
+    if (bookmark) {
+        return bookmark.get('nick');
+    }
+}

+ 2 - 1
src/plugins/bookmark-views/index.js

@@ -10,6 +10,7 @@ import BookmarksView from './bookmarks-list.js';
 import { __ } from 'i18n';
 import { _converse, api, converse } from '@converse/headless/core';
 import { bookmarkableChatRoomView, eventMethods } from './mixins.js';
+import { checkBookmarksSupport } from '@converse/headless/plugins/bookmarks/utils';
 
 const initBookmarkViews = async function () {
     await api.waitUntil('roomsPanelRendered');
@@ -65,7 +66,7 @@ converse.plugins.add('converse-bookmark-views', {
                 };
                 const names = buttons.map(t => t.name);
                 const idx = names.indexOf('details');
-                const data_promise = _converse.checkBookmarksSupport().then(s => (s ? data : ''));
+                const data_promise = checkBookmarksSupport().then(s => (s ? data : ''));
                 return idx > -1
                     ? [...buttons.slice(0, idx), data_promise, ...buttons.slice(idx)]
                     : [data_promise, ...buttons];