瀏覽代碼

Create new config setting `stanza_timeout`

And move STANZA_TIMEOUT off `_converse` and into constants.js
JC Brand 2 年之前
父節點
當前提交
4d2a8e9f8d

+ 2 - 0
CHANGES.md

@@ -9,6 +9,8 @@
 - Generate TypeScript declaration files into `dist/types`
 - #3156: Add function to prevent drag stutter effect over iframes when resize is called in overlay mode
 
+- New config option [stanza_timeout](https://conversejs.org/docs/html/configuration.html#stanza-timeout)
+
 ## 10.1.2 (2023-02-17)
 
 - #1490: Busy-loop when fetching registration form fails

+ 7 - 0
docs/source/configuration.rst

@@ -2089,6 +2089,13 @@ themselves).
 In order to support all browsers we need both an MP3 and an Ogg file. Make sure
 to name your files ``msg_received.ogg`` and ``msg_received.mp3``.
 
+stanza_timeout
+--------------
+
+* Default: ``20000`` (20 seconds)
+
+The time to wait, in milliseconds, for a response stanza (for example to an IQ
+request), before a timeout error is thrown and Converse stops waiting.
 
 sticky_controlbox
 -----------------

+ 4 - 3
src/headless/plugins/muc/muc.js

@@ -5,17 +5,17 @@ import p from '../../utils/parse-helpers';
 import pick from 'lodash-es/pick';
 import sizzle from 'sizzle';
 import { Model } from '@converse/skeletor/src/model.js';
+import { ROOMSTATUS } from './constants.js';
 import { Strophe, $build, $iq, $msg, $pres } from 'strophe.js/src/strophe';
 import { _converse, api, converse } from '../../core.js';
 import { computeAffiliationsDelta, setAffiliations, getAffiliationList }  from './affiliations/utils.js';
-import { handleCorrection } from '../../shared/chat/utils.js';
 import { getOpenPromise } from '@converse/openpromise';
+import { handleCorrection } from '../../shared/chat/utils.js';
 import { initStorage } from '../../utils/storage.js';
 import { isArchived, getMediaURLsMetadata } from '../../shared/parsers.js';
 import { isUniView, getUniqueId, safeSave } from '../../utils/core.js';
 import { parseMUCMessage, parseMUCPresence } from './parsers.js';
 import { sendMarker } from '../../shared/actions.js';
-import { ROOMSTATUS } from './constants.js';
 
 const { u } = converse.env;
 
@@ -723,7 +723,8 @@ const ChatRoomMixin = {
             el.setAttribute('id', id);
         }
         const promise = getOpenPromise();
-        const timeoutHandler = _converse.connection.addTimedHandler(_converse.STANZA_TIMEOUT, () => {
+        const timeout = api.settings.get('stanza_timeout');
+        const timeoutHandler = _converse.connection.addTimedHandler(timeout, () => {
             _converse.connection.deleteHandler(handler);
             const err = new _converse.TimeoutError('Timeout Error: No response from server');
             promise.resolve(err);

+ 3 - 2
src/headless/plugins/roster/utils.js

@@ -1,6 +1,7 @@
 import log from "@converse/headless/log";
 import { Model } from '@converse/skeletor/src/model.js';
 import { RosterFilter } from '@converse/headless/plugins/roster/filter.js';
+import { STATUS_WEIGHTS } from "../../shared/constants";
 import { _converse, api, converse } from "@converse/headless/core";
 import { initStorage } from '@converse/headless/utils/storage.js';
 import { shouldClearCache } from '@converse/headless/utils/core.js';
@@ -198,12 +199,12 @@ export function rejectPresenceSubscription (jid, message) {
 export function contactsComparator (contact1, contact2) {
     const status1 = contact1.presence.get('show') || 'offline';
     const status2 = contact2.presence.get('show') || 'offline';
-    if (_converse.STATUS_WEIGHTS[status1] === _converse.STATUS_WEIGHTS[status2]) {
+    if (STATUS_WEIGHTS[status1] === STATUS_WEIGHTS[status2]) {
         const name1 = (contact1.getDisplayName()).toLowerCase();
         const name2 = (contact2.getDisplayName()).toLowerCase();
         return name1 < name2 ? -1 : (name1 > name2? 1 : 0);
     } else  {
-        return _converse.STATUS_WEIGHTS[status1] < _converse.STATUS_WEIGHTS[status2] ? -1 : 1;
+        return STATUS_WEIGHTS[status1] < STATUS_WEIGHTS[status2] ? -1 : 1;
     }
 }
 

+ 3 - 2
src/headless/plugins/status/api.js

@@ -1,4 +1,5 @@
-import { _converse, api } from '@converse/headless/core';
+import { _converse, api } from '../../core';
+import { STATUS_WEIGHTS } from '../../shared/constants';
 
 
 export default {
@@ -32,7 +33,7 @@ export default {
          */
         async set (value, message) {
             const data = {'status': value};
-            if (!Object.keys(_converse.STATUS_WEIGHTS).includes(value)) {
+            if (!Object.keys(STATUS_WEIGHTS).includes(value)) {
                 throw new Error(
                     'Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1'
                 );

+ 1 - 17
src/headless/shared/_converse.js

@@ -1,7 +1,7 @@
 import i18n from './i18n.js';
 import log from '../log.js';
 import pluggable from 'pluggable.js/src/pluggable.js';
-import { CONNECTION_STATUS, VERSION_NAME } from './constants';
+import { VERSION_NAME } from './constants';
 import { Events } from '@converse/skeletor/src/events.js';
 import { Router } from '@converse/skeletor/src/router.js';
 import { TimeoutError } from './errors.js';
@@ -21,7 +21,6 @@ const _converse = {
     log,
 
     shouldClearCache, // TODO: Should be moved to utils with next major release
-    CONNECTION_STATUS, // TODO: remove in next major release
     VERSION_NAME,
 
     templates: {},
@@ -29,15 +28,6 @@ const _converse = {
         'initialized': getOpenPromise()
     },
 
-    STATUS_WEIGHTS: {
-        'offline':      6,
-        'unavailable':  5,
-        'xa':           4,
-        'away':         3,
-        'dnd':          2,
-        'chat':         1, // We currently don't differentiate between "chat" and "online"
-        'online':       1
-    },
     ANONYMOUS: 'anonymous',
     CLOSED: 'closed',
     EXTERNAL: 'external',
@@ -46,12 +36,6 @@ const _converse = {
     OPENED: 'opened',
     PREBIND: 'prebind',
 
-    /**
-     * @constant
-     * @type { number }
-     */
-    STANZA_TIMEOUT: 20000,
-
     SUCCESS: 'success',
     FAILURE: 'failure',
 

+ 2 - 1
src/headless/shared/api/public.js

@@ -6,7 +6,7 @@ import i18n from '../i18n';
 import log from '../../log.js';
 import sizzle from 'sizzle';
 import u, { setUnloadEvent } from '../../utils/core.js';
-import { CHAT_STATES, KEYCODES } from '../constants.js';
+import { CHAT_STATES, KEYCODES, VERSION_NAME } from '../constants.js';
 import { Collection } from "@converse/skeletor/src/collection";
 import { Model } from '@converse/skeletor/src/model.js';
 import { Strophe, $build, $iq, $msg, $pres } from 'strophe.js/src/strophe';
@@ -185,6 +185,7 @@ export const converse = Object.assign(window.converse || {}, {
      * @memberOf converse
      */
     'env': {
+        VERSION_NAME,
         $build,
         $iq,
         $msg,

+ 5 - 4
src/headless/shared/api/send.js

@@ -1,4 +1,4 @@
-import _converse from '@converse/headless/shared/_converse.js';
+import _converse from '../../shared/_converse.js';
 import log from '../../log.js';
 import { Strophe } from 'strophe.js/src/strophe';
 import { TimeoutError } from '../errors.js';
@@ -43,7 +43,8 @@ export default {
      * Send an IQ stanza
      * @method _converse.api.sendIQ
      * @param { Element } stanza
-     * @param { number } [timeout=_converse.STANZA_TIMEOUT]
+     * @param { number } [timeout] - The default timeout value is taken from
+     *  the `stanza_timeout` configuration setting.
      * @param { Boolean } [reject=true] - Whether an error IQ should cause the promise
      *  to be rejected. If `false`, the promise will resolve instead of being rejected.
      * @returns { Promise } A promise which resolves (or potentially rejected) once we
@@ -51,13 +52,13 @@ export default {
      *  If the IQ stanza being sent is of type `result` or `error`, there's
      *  nothing to wait for, so an already resolved promise is returned.
      */
-    sendIQ (stanza, timeout=_converse.STANZA_TIMEOUT, reject=true) {
+    sendIQ (stanza, timeout, reject=true) {
         const { api, connection } = _converse;
 
         let promise;
         stanza = stanza.tree?.() ?? stanza;
         if (['get', 'set'].includes(stanza.getAttribute('type'))) {
-            timeout = timeout || _converse.STANZA_TIMEOUT;
+            timeout = timeout || api.settings.get('stanza_timeout');
             if (reject) {
                 promise = new Promise((resolve, reject) => connection.sendIQ(stanza, resolve, reject, timeout));
                 promise.catch((e) => {

+ 14 - 4
src/headless/shared/constants.js

@@ -1,7 +1,17 @@
 import { Strophe } from 'strophe.js/src/strophe';
 
 export const BOSH_WAIT = 59;
-export const VERSION_NAME = "v10.1.2";
+export const VERSION_NAME = 'v10.1.2';
+
+export const STATUS_WEIGHTS = {
+    offline: 6,
+    unavailable: 5,
+    xa: 4,
+    away: 3,
+    dnd: 2,
+    chat: 1, // We don't differentiate between "chat" and "online"
+    online: 1,
+};
 
 export const CONNECTION_STATUS = {};
 CONNECTION_STATUS[Strophe.Status.ATTACHED] = 'ATTACHED';
@@ -73,7 +83,7 @@ export const CORE_PLUGINS = [
     'converse-roster',
     'converse-smacks',
     'converse-status',
-    'converse-vcard'
+    'converse-vcard',
 ];
 
 export const URL_PARSE_OPTIONS = { 'start': /(\b|_)(?:([a-z][a-z0-9.+-]*:\/\/)|xmpp:|mailto:|www\.)/gi };
@@ -94,5 +104,5 @@ export const KEYCODES = {
     FORWARD_SLASH: 47,
     AT: 50,
     META: 91,
-    META_RIGHT: 93
-}
+    META_RIGHT: 93,
+};

+ 1 - 0
src/headless/shared/settings/constants.js

@@ -101,6 +101,7 @@ export const DEFAULT_SETTINGS = {
     sid: undefined,
     singleton: false,
     strict_plugin_dependencies: false,
+    stanza_timeout: 20000,
     view_mode: 'overlayed', // Choices are 'overlayed', 'fullscreen', 'mobile'
     websocket_url: undefined,
     whitelisted_plugins: [],

+ 1 - 3
src/plugins/muc-views/tests/retractions.js

@@ -661,9 +661,7 @@ describe("Message Retractions", function () {
         }));
 
         it("can be retracted by its author, causing a timeout error in response",
-                mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
-
-            _converse.STANZA_TIMEOUT = 1;
+                mock.initConverse(['chatBoxesFetched'], { stanza_timeout: 1 }, async function (_converse) {
 
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];