瀏覽代碼

converse-muc: Support for XEP-0410 to check whether we're joined

JC Brand 6 年之前
父節點
當前提交
f2ac9ef4d7
共有 6 個文件被更改,包括 78 次插入15 次删除
  1. 1 0
      CHANGES.md
  2. 2 2
      package-lock.json
  3. 9 5
      src/headless/converse-chatboxes.js
  4. 8 7
      src/headless/converse-core.js
  5. 57 0
      src/headless/converse-muc.js
  6. 1 1
      src/headless/package.json

+ 1 - 0
CHANGES.md

@@ -1,6 +1,7 @@
 # Changelog
 
 ## 5.0.0 (Unreleased)
+- Support for XEP-0410 to check whether we're still present in a room
 - Initial support for the [CredentialsContainer](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer) web API
 - Allow for synchronous events. When a synchronous event is fired, Converse will
   wait for all promises returned by the event's handlers to finish before continuing.

+ 2 - 2
package-lock.json

@@ -13716,8 +13716,8 @@
       }
     },
     "strophe.js": {
-      "version": "github:strophe/strophejs#bc8a6b62203a17ada6bd78945c993c6f7dccd1de",
-      "from": "github:strophe/strophejs#bc8a6b62203a17ada6bd78945c993c6f7dccd1de"
+      "version": "github:strophe/strophejs#c675bcfcf44527ba1cf844a1aaa68fe7003c6140",
+      "from": "github:strophe/strophejs#c675bcfcf44527ba1cf844a1aaa68fe7003c6140"
     },
     "style-loader": {
       "version": "0.23.1",

+ 9 - 5
src/headless/converse-chatboxes.js

@@ -401,6 +401,11 @@ converse.plugins.add('converse-chatboxes', {
                 }
             },
 
+            shouldShowErrorMessage () {
+                // Gets overridden in ChatRoom
+                return true;
+            },
+
             /**
              * If the passed in `message` stanza contains an
              * [XEP-0308](https://xmpp.org/extensions/xep-0308.html#usecase)
@@ -987,11 +992,10 @@ converse.plugins.add('converse-chatboxes', {
                         // We also ignore duplicate error messages.
                         return;
                     }
-                } else {
-                    // An error message without id likely means that we
-                    // sent a message without id (which shouldn't happen).
-                    _converse.log('Received an error message without id attribute!', Strophe.LogLevel.ERROR);
-                    _converse.log(message, Strophe.LogLevel.ERROR);
+                }
+                const should_show = await chatbox.shouldShowErrorMessage(message);
+                if (!should_show) {
+                    return;
                 }
                 const attrs = await chatbox.getMessageAttributesFromStanza(message, message);
                 chatbox.messages.create(attrs);

+ 8 - 7
src/headless/converse-core.js

@@ -1350,7 +1350,7 @@ _converse.initialize = async function (settings, callback) {
             }
         } else if (reconnecting) {
             this.autoLogin();
-        } else if (window.PasswordCredential) {
+        } else if (!isTestEnv() && window.PasswordCredential) {
             const creds = await navigator.credentials.get({'password': true});
             if (creds && creds.type == 'password' && u.isValidJID(creds.id)) {
                 setUserJID(creds.id);
@@ -1514,7 +1514,7 @@ _converse.api = {
          * @returns {string} The current user's full JID (Jabber ID)
          * @example _converse.api.user.jid())
          */
-        'jid' () {
+        jid () {
             return _converse.connection.jid;
         },
 
@@ -1577,19 +1577,20 @@ _converse.api = {
              */
             _converse.api.trigger('logout');
         },
+
         /**
          * Set and get the user's chat status, also called their *availability*.
          *
          * @namespace _converse.api.user.status
          * @memberOf _converse.api.user
          */
-        'status': {
+        status: {
             /** Return the current user's availability status.
              *
              * @method _converse.api.user.status.get
              * @example _converse.api.user.status.get();
              */
-            'get' () {
+            get () {
                 return _converse.xmppstatus.get('status');
             },
             /**
@@ -1602,7 +1603,7 @@ _converse.api = {
              * @example this._converse.api.user.status.set('dnd');
              * @example this._converse.api.user.status.set('dnd', 'In a meeting');
              */
-            'set' (value, message) {
+            set (value, message) {
                 const data = {'status': value};
                 if (!_.includes(Object.keys(_converse.STATUS_WEIGHTS), value)) {
                     throw new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1');
@@ -1626,7 +1627,7 @@ _converse.api = {
                  * @returns {string} The status message
                  * @example const message = _converse.api.user.status.message.get()
                  */
-                'get' () {
+                get () {
                     return _converse.xmppstatus.get('status_message');
                 },
                 /**
@@ -1634,7 +1635,7 @@ _converse.api = {
                  * @param {string} status The status message
                  * @example _converse.api.user.status.message.set('In a meeting');
                  */
-                'set' (status) {
+                set (status) {
                     _converse.xmppstatus.save({'status_message': status});
                 }
             }

+ 57 - 0
src/headless/converse-muc.js

@@ -1224,9 +1224,66 @@ converse.plugins.add('converse-muc', {
                 return attrs;
             },
 
+            /**
+             * Send a MUC-0410 MUC Self-Ping stanza to room to determine
+             * whether we're still joined.
+             * @async
+             * @private
+             * @method _converse.ChatRoom#isJoined
+             * @returns {Promise<boolean>}
+             */
+            async isJoined () {
+                const ping = $iq({
+                    'to': `${this.get('jid')}/${this.get('nick')}`,
+                    'type': "get"
+                }).c("ping", {'xmlns': Strophe.NS.PING});
+                let result;
+                try {
+                    result = await _converse.api.sendIQ(ping);
+                } catch (e) {
+                    const sel = `error[type="cancel"] not-acceptable[xmlns="${Strophe.NS.STANZAS}"]`;
+                    if (_.isElement(e) && sizzle(sel, e).length) {
+                        return false;
+                    }
+                }
+                return true;
+            },
+
+            /**
+             * Check whether we're still joined and re-join if not
+             * @async
+             * @private
+             * @method _converse.ChatRoom#rejoinIfNecessary
+             */
+            async rejoinIfNecessary () {
+                const is_joined = await this.isJoined();
+                if (!is_joined) {
+                    this.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
+                    this.enterRoom();
+                    return true;
+                }
+            },
+
+            /**
+             * @async
+             * @private
+             * @method _converse.ChatRoom#shouldShowErrorMessage
+             * @returns {Promise<boolean>}
+             */
+            async shouldShowErrorMessage (stanza) {
+                if (sizzle(`not-acceptable[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) {
+                    if (await this.rejoinIfNecessary()) {
+                        return false;
+                    }
+                }
+                return true;
+            },
+
             getErrorMessage (stanza) {
                 if (sizzle(`forbidden[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) {
                     return __("Your message was not delivered because you're not allowed to send messages in this groupchat.");
+                } else if (sizzle(`not-acceptable[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) {
+                    return __("Your message was not delivered because you're not present in the groupchat.");
                 } else {
                     return _converse.ChatBox.prototype.getErrorMessage.apply(this, arguments);
                 }

+ 1 - 1
src/headless/package.json

@@ -29,7 +29,7 @@
     "jed": "1.1.1",
     "lodash": "^4.17.11",
     "pluggable.js": "2.0.1",
-    "strophe.js": "strophe/strophejs#bc8a6b62203a17ada6bd78945c993c6f7dccd1de",
+    "strophe.js": "strophe/strophejs#c675bcfcf44527ba1cf844a1aaa68fe7003c6140",
     "twemoji": "^11.0.1",
     "urijs": "^1.19.1"
   }