Browse Source

Add `force` parameter to `_converse.chats.open`

This changes the API method's current behavior by not automatically
maximizing (in `overlayed` view mode) or bringing a background chat into
foreground (in `fullscreen` view mode). Instead `force` needs to be set
to `true` for that to happen.
JC Brand 6 years ago
parent
commit
ee78ec1333

+ 8 - 1
CHANGES.md

@@ -1,6 +1,6 @@
 # Changelog
 
-## 4.2.1 (Unreleased)
+## 5.0.0 (Unreleased)
 
 * Bugfix: Don't set `muc_domain` for roomspanel if `locked_muc_domain` is `true`.
 * Bugfix: Modal auto-closes when you open it for a second time.
@@ -9,6 +9,13 @@
 * #1296: `embedded` view mode shows `chatbox-navback` arrow in header  
 * #1532: Converse reloads on enter pressed in the filter box
 
+### API changes
+
+* `_converse.chats.open` and `_converse.rooms.open` now take a `force`
+  parameter to force maximizing (in `overlayed` view mode) or bringing a
+  background chat into the foreground (in `fullscreen` view mode). Previously
+  this was the default behavior.
+
 ## 4.2.0 (2019-04-04)
 
 **Note:** This release introduces a hard requirement on [MAM:2](https://xmpp.org/extensions/xep-0313.html),

+ 61 - 43
dist/converse.js

@@ -48214,9 +48214,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins
         if (_converse.muc_respect_autojoin && bookmark.get('autojoin')) {
           const groupchat = _converse.api.rooms.create(bookmark.get('jid'), bookmark.get('nick'));
 
-          if (!groupchat.get('hidden') && !groupchat.get('minimized')) {
-            groupchat.trigger('show');
-          }
+          groupchat.maybeShow();
         }
 
         return bookmark;
@@ -48465,7 +48463,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins
           'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)) || jid
         };
 
-        _converse.api.rooms.open(jid, data);
+        _converse.api.rooms.open(jid, data, true);
       },
 
       removeBookmark: _converse.removeBookmarkViaEvent,
@@ -50196,7 +50194,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         this.focus();
       },
 
-      _show(f) {
+      _show() {
         /* Inner show method that gets debounced */
         if (_converse_headless_utils_emoji__WEBPACK_IMPORTED_MODULE_21__["default"].isVisible(this.el)) {
           this.focus();
@@ -50539,8 +50537,13 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         return this.__super__.validate.apply(this, arguments);
       },
 
-      mayBeShown() {
-        return this.__super__.mayBeShown.apply(this, arguments) && this.get('id') !== 'controlbox';
+      maybeShow(force) {
+        if (!force && this.get('id') === 'controlbox') {
+          // Must return the chatbox
+          return this;
+        }
+
+        return this.__super__.maybeShow.apply(this, arguments);
       },
 
       initialize() {
@@ -51011,7 +51014,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
         if (_converse.connection.connected) {
           controlbox.save({
-            closed: false
+            'closed': false
           });
         } else {
           controlbox.trigger('show');
@@ -52520,8 +52523,13 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_1__["default"].plugins
         });
       },
 
-      mayBeShown() {
-        return this.__super__.mayBeShown.apply(this, arguments) && !this.get('minimized');
+      maybeShow(force) {
+        if (!force && this.get('minimized')) {
+          // Must return the chatbox
+          return this;
+        }
+
+        return this.__super__.maybeShow.apply(this, arguments);
       }
 
     },
@@ -59004,7 +59012,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins
         const data = {
           'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)) || jid
         };
-        await _converse.api.rooms.open(jid, data);
+        await _converse.api.rooms.open(jid, data, true);
 
         _converse.api.chatviews.get(jid).focus();
       },
@@ -59715,7 +59723,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_4__["default"].plugins
 
         const attrs = this.model.attributes;
 
-        _converse.api.chats.open(attrs.jid, attrs);
+        _converse.api.chats.open(attrs.jid, attrs, true);
       },
 
       async removeContact(ev) {
@@ -60344,23 +60352,22 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_1__["default"].plugins
     //
     // new functions which don't exist yet can also be added.
     ChatBox: {
-      mayBeShown() {
+      maybeShow(force) {
+        // This method must return the chatbox
         const _converse = this.__super__._converse;
 
-        if (_converse.isUniView()) {
+        if (!force && _converse.isUniView()) {
           if (this.get('id') === 'controlbox') {
-            return true;
+            return this.trigger('show');
           }
 
           const any_chats_visible = _converse.chatboxes.filter(cb => cb.get('id') != 'controlbox').filter(cb => !cb.get('hidden')).length > 0;
 
-          if (any_chats_visible) {
-            return !this.get('hidden');
-          } else {
-            return true;
+          if (!any_chats_visible || !this.get('hidden')) {
+            return this.trigger('show');
           }
         } else {
-          return this.__super__.mayBeShown.apply(this, arguments);
+          return this.__super__.maybeShow.apply(this, arguments);
         }
       }
 
@@ -62611,8 +62618,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         return attrs;
       },
 
-      mayBeShown() {
-        return true;
+      maybeShow() {
+        // Returns the chatbox
+        return this.trigger("show");
       },
 
       isHidden() {
@@ -62689,11 +62697,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
 
       onChatBoxesFetched(collection) {
         /* Show chat boxes upon receiving them from sessionStorage */
-        collection.each(chatbox => {
-          if (chatbox.mayBeShown()) {
-            chatbox.trigger('show');
-          }
-        });
+        collection.each(chatbox => chatbox.maybeShow());
         /**
          * Triggered when a message stanza is been received and processed.
          * @event _converse#message
@@ -62979,7 +62983,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         /**
          * @method _converse.api.chats.create
          * @param {string|string[]} jid|jids An jid or array of jids
-         * @param {object} attrs An object containing configuration attributes.
+         * @param {object} [attrs] An object containing configuration attributes.
          */
         'create'(jids, attrs) {
           if (_.isUndefined(jids)) {
@@ -63006,7 +63010,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
 
           return _.map(jids, jid => {
             attrs.fullname = _.get(_converse.api.contacts.get(jid), 'attributes.fullname');
-            return _converse.chatboxes.getChatBox(jid, attrs, true).trigger('show');
+            return _converse.chatboxes.getChatBox(jid, attrs, true).maybeShow();
           });
         },
 
@@ -63015,7 +63019,15 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
          *
          * @method _converse.api.chats.open
          * @param {String|string[]} name - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
-         * @returns {Promise} Promise which resolves with the Backbone.Model representing the chat.
+         * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model.
+         * @param {Boolean} [force=false] - By default, a minimized
+         *   chat won't be maximized (in `overlayed` view mode) and in
+         *   `fullscreen` view mode a newly opened chat won't replace
+         *   another chat already in the foreground.
+         *   Set `force` to `true` if you want to force the chat to be
+         *   maximized or shown.
+         * @returns {Promise} Promise which resolves with the
+         *   _converse.ChatBox representing the chat.
          *
          * @example
          * // To open a single chat, provide the JID of the contact you're chatting with in that chat:
@@ -63023,7 +63035,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
          *     initialize: function() {
          *         var _converse = this._converse;
          *         // Note, buddy@example.org must be in your contacts roster!
-         *         _converse.api.chats.open('buddy@example.com').then((chat) => {
+         *         _converse.api.chats.open('buddy@example.com').then(chat => {
          *             // Now you can do something with the chat model
          *         });
          *     }
@@ -63035,14 +63047,13 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
          *     initialize: function () {
          *         var _converse = this._converse;
          *         // Note, these users must first be in your contacts roster!
-         *         _converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then((chats) => {
+         *         _converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then(chats => {
          *             // Now you can do something with the chat models
          *         });
          *     }
          * });
-         *
          */
-        'open'(jids, attrs) {
+        'open'(jids, attrs, force) {
           return new Promise((resolve, reject) => {
             Promise.all([_converse.api.waitUntil('rosterContactsFetched'), _converse.api.waitUntil('chatBoxesFetched')]).then(() => {
               if (_.isUndefined(jids)) {
@@ -63052,9 +63063,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
 
                 reject(new Error(err_msg));
               } else if (_.isString(jids)) {
-                resolve(_converse.api.chats.create(jids, attrs).trigger('show'));
+                resolve(_converse.api.chats.create(jids, attrs).maybeShow(force));
               } else {
-                resolve(_.map(jids, jid => _converse.api.chats.create(jid, attrs).trigger('show')));
+                resolve(_.map(jids, jid => _converse.api.chats.create(jid, attrs).maybeShow(force)));
               }
             }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
           });
@@ -63064,7 +63075,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
          * Returns a chat model. The chat should already be open.
          *
          * @method _converse.api.chats.get
-         * @param {String|string[]} name - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
+         * @param {String|string[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
          * @returns {_converse.ChatBox}
          *
          * @example
@@ -66650,7 +66661,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
       }
     };
 
-    _converse.openChatRoom = function (jid, settings, bring_to_foreground) {
+    function openChatRoom(jid, settings) {
       /* Opens a groupchat, making sure that certain attributes
        * are correct, for example that the "type" is set to
        * "chatroom".
@@ -66661,9 +66672,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
 
       const chatbox = _converse.chatboxes.getChatBox(jid, settings, true);
 
-      chatbox.trigger('show', true);
+      chatbox.maybeShow(true);
       return chatbox;
-    };
+    }
     /**
      * Represents an open/ongoing groupchat conversation.
      *
@@ -68033,7 +68044,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
       }
 
       if (result === true) {
-        const chatroom = _converse.openChatRoom(room_jid, {
+        const chatroom = openChatRoom(room_jid, {
           'password': x_el.getAttribute('password')
         });
 
@@ -68246,6 +68257,12 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
          * @param {boolean} [attrs.bring_to_foreground] A boolean indicating whether the room should be
          *     brought to the foreground and therefore replace the currently shown chat.
          *     If there is no chat currently open, then this option is ineffective.
+         * @param {Boolean} [force=false] - By default, a minimized
+         *   room won't be maximized (in `overlayed` view mode) and in
+         *   `fullscreen` view mode a newly opened room won't replace
+         *   another chat already in the foreground.
+         *   Set `force` to `true` if you want to force the room to be
+         *   maximized or shown.
          *
          * @example
          * this._converse.api.rooms.open('group@muc.example.com')
@@ -68277,6 +68294,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
          * );
          */
         'open': async function open(jids, attrs) {
+          let force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
           await _converse.api.waitUntil('chatBoxesFetched');
 
           if (_.isUndefined(jids)) {
@@ -68286,9 +68304,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
 
             throw new TypeError(err_msg);
           } else if (_.isString(jids)) {
-            return _converse.api.rooms.create(jids, attrs).trigger('show');
+            return _converse.api.rooms.create(jids, attrs).maybeShow(force);
           } else {
-            return _.map(jids, jid => _converse.api.rooms.create(jid, attrs).trigger('show'));
+            return _.map(jids, jid => _converse.api.rooms.create(jid, attrs).maybeShow(force));
           }
         },
 

+ 2 - 4
src/converse-bookmarks.js

@@ -259,9 +259,7 @@ converse.plugins.add('converse-bookmarks', {
             openBookmarkedRoom (bookmark) {
                 if ( _converse.muc_respect_autojoin && bookmark.get('autojoin')) {
                     const groupchat = _converse.api.rooms.create(bookmark.get('jid'), bookmark.get('nick'));
-                    if (!groupchat.get('hidden') && !groupchat.get('minimized')) {
-                        groupchat.trigger('show');
-                    }
+                    groupchat.maybeShow();
                 }
                 return bookmark;
             },
@@ -483,7 +481,7 @@ converse.plugins.add('converse-bookmarks', {
                 const data = {
                     'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)) || jid
                 }
-                _converse.api.rooms.open(jid, data);
+                _converse.api.rooms.open(jid, data, true);
             },
 
             removeBookmark: _converse.removeBookmarkViaEvent,

+ 1 - 1
src/converse-chatview.js

@@ -1288,7 +1288,7 @@ converse.plugins.add('converse-chatview', {
                 this.focus();
             },
 
-            _show (f) {
+            _show () {
                 /* Inner show method that gets debounced */
                 if (u.isVisible(this.el)) {
                     this.focus();

+ 7 - 4
src/converse-controlbox.js

@@ -138,9 +138,12 @@ converse.plugins.add('converse-controlbox', {
                 return this.__super__.validate.apply(this, arguments);
             },
 
-            mayBeShown () {
-                return this.__super__.mayBeShown.apply(this, arguments) &&
-                       this.get('id') !== 'controlbox';
+            maybeShow (force) {
+                if (!force && this.get('id') === 'controlbox') {
+                   // Must return the chatbox
+                   return this;
+                }
+                return this.__super__.maybeShow.apply(this, arguments);
             },
 
             initialize () {
@@ -573,7 +576,7 @@ converse.plugins.add('converse-controlbox', {
                     controlbox = addControlBox();
                 }
                 if (_converse.connection.connected) {
-                    controlbox.save({closed: false});
+                    controlbox.save({'closed': false});
                 } else {
                     controlbox.trigger('show');
                 }

+ 6 - 3
src/converse-minimize.js

@@ -69,9 +69,12 @@ converse.plugins.add('converse-minimize', {
                 });
             },
 
-            mayBeShown () {
-                return this.__super__.mayBeShown.apply(this, arguments) &&
-                       !this.get('minimized');
+            maybeShow (force) {
+                if (!force && this.get('minimized')) {
+                    // Must return the chatbox
+                    return this;
+                }
+                return this.__super__.maybeShow.apply(this, arguments);
             }
         },
 

+ 1 - 1
src/converse-roomslist.js

@@ -219,7 +219,7 @@ converse.plugins.add('converse-roomslist', {
                 const data = {
                     'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)) || jid
                 }
-                await _converse.api.rooms.open(jid, data);
+                await _converse.api.rooms.open(jid, data, true);
                 _converse.api.chatviews.get(jid).focus();
             },
 

+ 1 - 1
src/converse-rosterview.js

@@ -544,7 +544,7 @@ converse.plugins.add('converse-rosterview', {
             openChat (ev) {
                 if (ev && ev.preventDefault) { ev.preventDefault(); }
                 const attrs = this.model.attributes;
-                _converse.api.chats.open(attrs.jid, attrs);
+                _converse.api.chats.open(attrs.jid, attrs, true);
             },
 
             async removeContact (ev) {

+ 7 - 8
src/converse-singleton.js

@@ -45,23 +45,22 @@ converse.plugins.add('converse-singleton', {
         // new functions which don't exist yet can also be added.
 
         ChatBox: {
-            mayBeShown () {
+            maybeShow (force) {
+                // This method must return the chatbox
                 const { _converse } = this.__super__;
-                if (_converse.isUniView()) {
+                if (!force && _converse.isUniView()) {
                     if (this.get('id') === 'controlbox') {
-                        return true;
+                        return this.trigger('show');
                     }
                     const any_chats_visible = _converse.chatboxes
                         .filter(cb => cb.get('id') != 'controlbox')
                         .filter(cb => !cb.get('hidden')).length > 0;
 
-                    if (any_chats_visible) {
-                        return !this.get('hidden');
-                    } else {
-                        return true;
+                    if (!any_chats_visible || !this.get('hidden')) {
+                        return this.trigger('show');
                     }
                 } else {
-                    return this.__super__.mayBeShown.apply(this, arguments);
+                    return this.__super__.maybeShow.apply(this, arguments);
                 }
             }
         },

+ 21 - 17
src/headless/converse-chatboxes.js

@@ -776,8 +776,9 @@ converse.plugins.add('converse-chatboxes', {
                 return attrs;
             },
 
-            mayBeShown () {
-                return true;
+            maybeShow () {
+                // Returns the chatbox
+                return this.trigger("show");
             },
 
             isHidden () {
@@ -846,11 +847,7 @@ converse.plugins.add('converse-chatboxes', {
 
             onChatBoxesFetched (collection) {
                 /* Show chat boxes upon receiving them from sessionStorage */
-                collection.each(chatbox => {
-                    if (chatbox.mayBeShown()) {
-                        chatbox.trigger('show');
-                    }
-                });
+                collection.each(chatbox => chatbox.maybeShow());
                 /**
                  * Triggered when a message stanza is been received and processed.
                  * @event _converse#message
@@ -1106,7 +1103,7 @@ converse.plugins.add('converse-chatboxes', {
                 /**
                  * @method _converse.api.chats.create
                  * @param {string|string[]} jid|jids An jid or array of jids
-                 * @param {object} attrs An object containing configuration attributes.
+                 * @param {object} [attrs] An object containing configuration attributes.
                  */
                 'create' (jids, attrs) {
                     if (_.isUndefined(jids)) {
@@ -1129,7 +1126,7 @@ converse.plugins.add('converse-chatboxes', {
                     }
                     return _.map(jids, (jid) => {
                         attrs.fullname = _.get(_converse.api.contacts.get(jid), 'attributes.fullname');
-                        return _converse.chatboxes.getChatBox(jid, attrs, true).trigger('show');
+                        return _converse.chatboxes.getChatBox(jid, attrs, true).maybeShow();
                     });
                 },
 
@@ -1138,7 +1135,15 @@ converse.plugins.add('converse-chatboxes', {
                  *
                  * @method _converse.api.chats.open
                  * @param {String|string[]} name - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
-                 * @returns {Promise} Promise which resolves with the Backbone.Model representing the chat.
+                 * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model.
+                 * @param {Boolean} [force=false] - By default, a minimized
+                 *   chat won't be maximized (in `overlayed` view mode) and in
+                 *   `fullscreen` view mode a newly opened chat won't replace
+                 *   another chat already in the foreground.
+                 *   Set `force` to `true` if you want to force the chat to be
+                 *   maximized or shown.
+                 * @returns {Promise} Promise which resolves with the
+                 *   _converse.ChatBox representing the chat.
                  *
                  * @example
                  * // To open a single chat, provide the JID of the contact you're chatting with in that chat:
@@ -1146,7 +1151,7 @@ converse.plugins.add('converse-chatboxes', {
                  *     initialize: function() {
                  *         var _converse = this._converse;
                  *         // Note, buddy@example.org must be in your contacts roster!
-                 *         _converse.api.chats.open('buddy@example.com').then((chat) => {
+                 *         _converse.api.chats.open('buddy@example.com').then(chat => {
                  *             // Now you can do something with the chat model
                  *         });
                  *     }
@@ -1158,14 +1163,13 @@ converse.plugins.add('converse-chatboxes', {
                  *     initialize: function () {
                  *         var _converse = this._converse;
                  *         // Note, these users must first be in your contacts roster!
-                 *         _converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then((chats) => {
+                 *         _converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then(chats => {
                  *             // Now you can do something with the chat models
                  *         });
                  *     }
                  * });
-                 *
                  */
-                'open' (jids, attrs) {
+                'open' (jids, attrs, force) {
                     return new Promise((resolve, reject) => {
                         Promise.all([
                             _converse.api.waitUntil('rosterContactsFetched'),
@@ -1176,9 +1180,9 @@ converse.plugins.add('converse-chatboxes', {
                                 _converse.log(err_msg, Strophe.LogLevel.ERROR);
                                 reject(new Error(err_msg));
                             } else if (_.isString(jids)) {
-                                resolve(_converse.api.chats.create(jids, attrs).trigger('show'));
+                                resolve(_converse.api.chats.create(jids, attrs).maybeShow(force));
                             } else {
-                                resolve(_.map(jids, (jid) => _converse.api.chats.create(jid, attrs).trigger('show')));
+                                resolve(_.map(jids, jid => _converse.api.chats.create(jid, attrs).maybeShow(force)));
                             }
                         }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
                     });
@@ -1188,7 +1192,7 @@ converse.plugins.add('converse-chatboxes', {
                  * Returns a chat model. The chat should already be open.
                  *
                  * @method _converse.api.chats.get
-                 * @param {String|string[]} name - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
+                 * @param {String|string[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
                  * @returns {_converse.ChatBox}
                  *
                  * @example

+ 12 - 6
src/headless/converse-muc.js

@@ -155,7 +155,7 @@ converse.plugins.add('converse-muc', {
             }
         }
 
-        _converse.openChatRoom = function (jid, settings, bring_to_foreground) {
+        function openChatRoom (jid, settings) {
             /* Opens a groupchat, making sure that certain attributes
              * are correct, for example that the "type" is set to
              * "chatroom".
@@ -164,7 +164,7 @@ converse.plugins.add('converse-muc', {
             settings.id = jid;
             settings.box_id = b64_sha1(jid)
             const chatbox = _converse.chatboxes.getChatBox(jid, settings, true);
-            chatbox.trigger('show', true);
+            chatbox.maybeShow(true);
             return chatbox;
         }
 
@@ -1362,7 +1362,7 @@ converse.plugins.add('converse-muc', {
                 }
             }
             if (result === true) {
-                const chatroom = _converse.openChatRoom(room_jid, {'password': x_el.getAttribute('password') });
+                const chatroom = openChatRoom(room_jid, {'password': x_el.getAttribute('password') });
 
                 if (chatroom.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED) {
                     // XXX: Leaky abstraction from views here
@@ -1555,6 +1555,12 @@ converse.plugins.add('converse-muc', {
                  * @param {boolean} [attrs.bring_to_foreground] A boolean indicating whether the room should be
                  *     brought to the foreground and therefore replace the currently shown chat.
                  *     If there is no chat currently open, then this option is ineffective.
+                 * @param {Boolean} [force=false] - By default, a minimized
+                 *   room won't be maximized (in `overlayed` view mode) and in
+                 *   `fullscreen` view mode a newly opened room won't replace
+                 *   another chat already in the foreground.
+                 *   Set `force` to `true` if you want to force the room to be
+                 *   maximized or shown.
                  *
                  * @example
                  * this._converse.api.rooms.open('group@muc.example.com')
@@ -1585,16 +1591,16 @@ converse.plugins.add('converse-muc', {
                  *     true
                  * );
                  */
-                'open': async function (jids, attrs) {
+                'open': async function (jids, attrs, force=false) {
                     await _converse.api.waitUntil('chatBoxesFetched');
                     if (_.isUndefined(jids)) {
                         const err_msg = 'rooms.open: You need to provide at least one JID';
                         _converse.log(err_msg, Strophe.LogLevel.ERROR);
                         throw(new TypeError(err_msg));
                     } else if (_.isString(jids)) {
-                        return _converse.api.rooms.create(jids, attrs).trigger('show');
+                        return _converse.api.rooms.create(jids, attrs).maybeShow(force);
                     } else {
-                        return _.map(jids, (jid) => _converse.api.rooms.create(jid, attrs).trigger('show'));
+                        return _.map(jids, jid => _converse.api.rooms.create(jid, attrs).maybeShow(force));
                     }
                 },
 

+ 34 - 23
src/headless/dist/converse-headless.js

@@ -41123,8 +41123,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         return attrs;
       },
 
-      mayBeShown() {
-        return true;
+      maybeShow() {
+        // Returns the chatbox
+        return this.trigger("show");
       },
 
       isHidden() {
@@ -41201,11 +41202,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
 
       onChatBoxesFetched(collection) {
         /* Show chat boxes upon receiving them from sessionStorage */
-        collection.each(chatbox => {
-          if (chatbox.mayBeShown()) {
-            chatbox.trigger('show');
-          }
-        });
+        collection.each(chatbox => chatbox.maybeShow());
         /**
          * Triggered when a message stanza is been received and processed.
          * @event _converse#message
@@ -41491,7 +41488,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         /**
          * @method _converse.api.chats.create
          * @param {string|string[]} jid|jids An jid or array of jids
-         * @param {object} attrs An object containing configuration attributes.
+         * @param {object} [attrs] An object containing configuration attributes.
          */
         'create'(jids, attrs) {
           if (_.isUndefined(jids)) {
@@ -41518,7 +41515,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
 
           return _.map(jids, jid => {
             attrs.fullname = _.get(_converse.api.contacts.get(jid), 'attributes.fullname');
-            return _converse.chatboxes.getChatBox(jid, attrs, true).trigger('show');
+            return _converse.chatboxes.getChatBox(jid, attrs, true).maybeShow();
           });
         },
 
@@ -41527,7 +41524,15 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
          *
          * @method _converse.api.chats.open
          * @param {String|string[]} name - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
-         * @returns {Promise} Promise which resolves with the Backbone.Model representing the chat.
+         * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model.
+         * @param {Boolean} [force=false] - By default, a minimized
+         *   chat won't be maximized (in `overlayed` view mode) and in
+         *   `fullscreen` view mode a newly opened chat won't replace
+         *   another chat already in the foreground.
+         *   Set `force` to `true` if you want to force the chat to be
+         *   maximized or shown.
+         * @returns {Promise} Promise which resolves with the
+         *   _converse.ChatBox representing the chat.
          *
          * @example
          * // To open a single chat, provide the JID of the contact you're chatting with in that chat:
@@ -41535,7 +41540,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
          *     initialize: function() {
          *         var _converse = this._converse;
          *         // Note, buddy@example.org must be in your contacts roster!
-         *         _converse.api.chats.open('buddy@example.com').then((chat) => {
+         *         _converse.api.chats.open('buddy@example.com').then(chat => {
          *             // Now you can do something with the chat model
          *         });
          *     }
@@ -41547,14 +41552,13 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
          *     initialize: function () {
          *         var _converse = this._converse;
          *         // Note, these users must first be in your contacts roster!
-         *         _converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then((chats) => {
+         *         _converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then(chats => {
          *             // Now you can do something with the chat models
          *         });
          *     }
          * });
-         *
          */
-        'open'(jids, attrs) {
+        'open'(jids, attrs, force) {
           return new Promise((resolve, reject) => {
             Promise.all([_converse.api.waitUntil('rosterContactsFetched'), _converse.api.waitUntil('chatBoxesFetched')]).then(() => {
               if (_.isUndefined(jids)) {
@@ -41564,9 +41568,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
 
                 reject(new Error(err_msg));
               } else if (_.isString(jids)) {
-                resolve(_converse.api.chats.create(jids, attrs).trigger('show'));
+                resolve(_converse.api.chats.create(jids, attrs).maybeShow(force));
               } else {
-                resolve(_.map(jids, jid => _converse.api.chats.create(jid, attrs).trigger('show')));
+                resolve(_.map(jids, jid => _converse.api.chats.create(jid, attrs).maybeShow(force)));
               }
             }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
           });
@@ -41576,7 +41580,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
          * Returns a chat model. The chat should already be open.
          *
          * @method _converse.api.chats.get
-         * @param {String|string[]} name - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
+         * @param {String|string[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
          * @returns {_converse.ChatBox}
          *
          * @example
@@ -45162,7 +45166,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
       }
     };
 
-    _converse.openChatRoom = function (jid, settings, bring_to_foreground) {
+    function openChatRoom(jid, settings) {
       /* Opens a groupchat, making sure that certain attributes
        * are correct, for example that the "type" is set to
        * "chatroom".
@@ -45173,9 +45177,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
 
       const chatbox = _converse.chatboxes.getChatBox(jid, settings, true);
 
-      chatbox.trigger('show', true);
+      chatbox.maybeShow(true);
       return chatbox;
-    };
+    }
     /**
      * Represents an open/ongoing groupchat conversation.
      *
@@ -46545,7 +46549,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
       }
 
       if (result === true) {
-        const chatroom = _converse.openChatRoom(room_jid, {
+        const chatroom = openChatRoom(room_jid, {
           'password': x_el.getAttribute('password')
         });
 
@@ -46758,6 +46762,12 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
          * @param {boolean} [attrs.bring_to_foreground] A boolean indicating whether the room should be
          *     brought to the foreground and therefore replace the currently shown chat.
          *     If there is no chat currently open, then this option is ineffective.
+         * @param {Boolean} [force=false] - By default, a minimized
+         *   room won't be maximized (in `overlayed` view mode) and in
+         *   `fullscreen` view mode a newly opened room won't replace
+         *   another chat already in the foreground.
+         *   Set `force` to `true` if you want to force the room to be
+         *   maximized or shown.
          *
          * @example
          * this._converse.api.rooms.open('group@muc.example.com')
@@ -46789,6 +46799,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
          * );
          */
         'open': async function open(jids, attrs) {
+          let force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
           await _converse.api.waitUntil('chatBoxesFetched');
 
           if (_.isUndefined(jids)) {
@@ -46798,9 +46809,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
 
             throw new TypeError(err_msg);
           } else if (_.isString(jids)) {
-            return _converse.api.rooms.create(jids, attrs).trigger('show');
+            return _converse.api.rooms.create(jids, attrs).maybeShow(force);
           } else {
-            return _.map(jids, jid => _converse.api.rooms.create(jid, attrs).trigger('show'));
+            return _.map(jids, jid => _converse.api.rooms.create(jid, attrs).maybeShow(force));
           }
         },