quickblox 2.24.0 → 2.24.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/quickblox.d.ts +34 -1
- package/quickblox.js +218 -67
- package/quickblox.min.js +1 -1
- package/src/modules/chat/qbChat.js +214 -64
- package/src/modules/chat/qbNoticeConsts.js +2 -1
- package/src/qbConfig.js +2 -2
package/package.json
CHANGED
package/quickblox.d.ts
CHANGED
|
@@ -418,6 +418,26 @@ export declare interface QBChatMessage {
|
|
|
418
418
|
* Available since SDK 2.24.0.
|
|
419
419
|
*/
|
|
420
420
|
reactions?: QBReaction[]
|
|
421
|
+
/**
|
|
422
|
+
* Message editing flag (SR-2955). The server sets `1` when the message was
|
|
423
|
+
* edited, `0`/`null` otherwise. Delivered on the message object in REST
|
|
424
|
+
* responses (`message.list` / `message.getById`). Note: the server also carries it
|
|
425
|
+
* in `NoticeUpdatedMessage` (server release 2.94.0), but the SDK's real-time
|
|
426
|
+
* `onMessageUpdatedListener` object does not currently include it — read it from
|
|
427
|
+
* a REST fetch of the message.
|
|
428
|
+
* Available since SDK 2.24.0.
|
|
429
|
+
*/
|
|
430
|
+
is_edited?: 0 | 1 | boolean | null
|
|
431
|
+
/**
|
|
432
|
+
* ID of the user who last edited the message (SR-2955). Omitted/`null` when the
|
|
433
|
+
* message was never edited. Available since SDK 2.24.0.
|
|
434
|
+
*/
|
|
435
|
+
editor_id?: number | null
|
|
436
|
+
/**
|
|
437
|
+
* ISO timestamp of the last edit (SR-2955). Omitted/`null` when the message was
|
|
438
|
+
* never edited. Available since SDK 2.24.0.
|
|
439
|
+
*/
|
|
440
|
+
edited_at?: string | null
|
|
421
441
|
/**
|
|
422
442
|
* Name of the custom field.
|
|
423
443
|
* Chat message can be extended with additional fields and contain any other user key-value custom parameters.
|
|
@@ -683,7 +703,8 @@ interface QBChatModule {
|
|
|
683
703
|
/**
|
|
684
704
|
* Subscribe the current XMPP session to Notice Feature stanzas (urn:xmpp:notice:0).
|
|
685
705
|
* After a successful IQ result the server starts delivering NoticeUpdatedMessage /
|
|
686
|
-
* NoticeDeletedMessage / NoticeUpdatedDialog / NoticeDeletedDialog
|
|
706
|
+
* NoticeDeletedMessage / NoticeCreatedDialog / NoticeUpdatedDialog / NoticeDeletedDialog
|
|
707
|
+
* headline stanzas.
|
|
687
708
|
* The local enabled flag is reset on chat disconnect — call enableNotices() again after reconnect.
|
|
688
709
|
* @since 2.24.0
|
|
689
710
|
*/
|
|
@@ -749,6 +770,18 @@ interface QBChatModule {
|
|
|
749
770
|
* @since 2.24.0
|
|
750
771
|
*/
|
|
751
772
|
onDialogUpdatedListener?: (dialog: QBChatDialog) => void
|
|
773
|
+
/**
|
|
774
|
+
* Notice Feature: a Group or Private dialog was created (SR-2952). Delivered via the
|
|
775
|
+
* XMPP `NoticeCreatedDialog` headline stanza after `enableNotices()`, only to users
|
|
776
|
+
* with the Notice feature enabled. NOT sent for Public dialogs.
|
|
777
|
+
*
|
|
778
|
+
* The dialog object is a PARTIAL snapshot captured at creation time: it carries
|
|
779
|
+
* `created_at` / `updated_at` / `user_id` (creator) and the base fields, but has no
|
|
780
|
+
* `last_message*` fields (the dialog is brand new) and, for a private dialog, no
|
|
781
|
+
* `xmpp_room_jid`. Preserves the existing QBChatDialog snake_case shape.
|
|
782
|
+
* @since 2.24.1
|
|
783
|
+
*/
|
|
784
|
+
onDialogCreatedListener?: (dialog: QBChatDialog) => void
|
|
752
785
|
/** Blocked entities receive an error when try to chat with a user in a 1-1 chat and receivie nothing in a group chat. */
|
|
753
786
|
onMessageErrorListener?: (messageId: QBChatMessage['_id'], error: any) => void
|
|
754
787
|
/**
|
package/quickblox.js
CHANGED
|
@@ -30507,6 +30507,13 @@ var chatUtils = require('./qbChatHelpers'),
|
|
|
30507
30507
|
|
|
30508
30508
|
var unsupportedError = 'This function isn\'t supported outside of the browser (...yet)';
|
|
30509
30509
|
|
|
30510
|
+
/**
|
|
30511
|
+
* [CROS-1061] How long to wait for the server to answer a Notice enable/disable
|
|
30512
|
+
* IQ before reporting an error to the caller. Without a bound the callback is
|
|
30513
|
+
* never invoked when the server stays silent.
|
|
30514
|
+
*/
|
|
30515
|
+
var NOTICE_IQ_TIMEOUT_MS = 10000;
|
|
30516
|
+
|
|
30510
30517
|
var XMPP;
|
|
30511
30518
|
|
|
30512
30519
|
/** create StropheJS or NodeXMPP connection object */
|
|
@@ -30540,6 +30547,7 @@ NOTICE_KNOWN_MODULE_IDS[noticeConsts.NOTICE_MODULE_IDENTIFIER.UPDATED_MESSAGE] =
|
|
|
30540
30547
|
NOTICE_KNOWN_MODULE_IDS[noticeConsts.NOTICE_MODULE_IDENTIFIER.DELETED_MESSAGE] = true;
|
|
30541
30548
|
NOTICE_KNOWN_MODULE_IDS[noticeConsts.NOTICE_MODULE_IDENTIFIER.UPDATED_DIALOG] = true;
|
|
30542
30549
|
NOTICE_KNOWN_MODULE_IDS[noticeConsts.NOTICE_MODULE_IDENTIFIER.DELETED_DIALOG] = true;
|
|
30550
|
+
NOTICE_KNOWN_MODULE_IDS[noticeConsts.NOTICE_MODULE_IDENTIFIER.CREATED_DIALOG] = true;
|
|
30543
30551
|
|
|
30544
30552
|
/**
|
|
30545
30553
|
* Cross-env: get all direct child elements of `parent` whose tag name equals
|
|
@@ -30823,6 +30831,91 @@ function _parseCustomData(extraParams) {
|
|
|
30823
30831
|
return out;
|
|
30824
30832
|
}
|
|
30825
30833
|
|
|
30834
|
+
/**
|
|
30835
|
+
* Build a partial QBChatDialog object from a dialog-notice <extraParams>.
|
|
30836
|
+
* Shared by NoticeUpdatedDialog and NoticeCreatedDialog (SR-2952) — the server
|
|
30837
|
+
* sends a full dialog snapshot in both cases. Fields with null/empty values are
|
|
30838
|
+
* omitted by the server, so every read is guarded.
|
|
30839
|
+
*
|
|
30840
|
+
* CreatedDialog additionally carries created_at/updated_at/user_id (creator) and
|
|
30841
|
+
* has no last_message* fields (dialog just created); UpdatedDialog carries
|
|
30842
|
+
* last_message* and (per server contract) may also carry created_at/updated_at/
|
|
30843
|
+
* user_id. Reading them here for both is safe — absent fields are simply skipped.
|
|
30844
|
+
*
|
|
30845
|
+
* @param {Element} extraParams
|
|
30846
|
+
* @param {String} dialogId - already-resolved dialog_id text.
|
|
30847
|
+
* @return {Object} partial dialog snapshot.
|
|
30848
|
+
*/
|
|
30849
|
+
function _parseDialogSnapshot(extraParams, dialogId) {
|
|
30850
|
+
var dlg = {};
|
|
30851
|
+
dlg._id = dialogId;
|
|
30852
|
+
|
|
30853
|
+
var name = chatUtils.getElementText(extraParams, 'name');
|
|
30854
|
+
if (name !== undefined && name !== null && name !== '') {
|
|
30855
|
+
dlg.name = name;
|
|
30856
|
+
}
|
|
30857
|
+
var photo = chatUtils.getElementText(extraParams, 'photo');
|
|
30858
|
+
if (photo !== undefined && photo !== null && photo !== '') {
|
|
30859
|
+
dlg.photo = photo;
|
|
30860
|
+
}
|
|
30861
|
+
var typeText = chatUtils.getElementText(extraParams, 'type');
|
|
30862
|
+
var typeNum = parseInt(typeText, 10);
|
|
30863
|
+
if (!isNaN(typeNum)) {
|
|
30864
|
+
dlg.type = typeNum;
|
|
30865
|
+
}
|
|
30866
|
+
var occupants = _parseNumericIdsCsv(chatUtils.getElementText(extraParams, 'occupants_ids'));
|
|
30867
|
+
if (occupants.length > 0) {
|
|
30868
|
+
dlg.occupants_ids = occupants;
|
|
30869
|
+
}
|
|
30870
|
+
var admins = _parseNumericIdsCsv(chatUtils.getElementText(extraParams, 'admin_ids'));
|
|
30871
|
+
if (admins.length > 0) {
|
|
30872
|
+
dlg.admin_ids = admins;
|
|
30873
|
+
}
|
|
30874
|
+
var isJoinReqText = chatUtils.getElementText(extraParams, 'is_join_required');
|
|
30875
|
+
if (isJoinReqText !== undefined && isJoinReqText !== null && isJoinReqText !== '') {
|
|
30876
|
+
var isJoinReq = parseInt(isJoinReqText, 10);
|
|
30877
|
+
dlg.is_join_required = isNaN(isJoinReq) ? isJoinReqText : isJoinReq;
|
|
30878
|
+
}
|
|
30879
|
+
var roomJid = chatUtils.getElementText(extraParams, 'xmpp_room_jid');
|
|
30880
|
+
if (roomJid !== undefined && roomJid !== null && roomJid !== '') {
|
|
30881
|
+
// Server may pretty-print xmpp_room_jid with surrounding whitespace.
|
|
30882
|
+
dlg.xmpp_room_jid = roomJid.trim();
|
|
30883
|
+
}
|
|
30884
|
+
var customData = _parseCustomData(extraParams);
|
|
30885
|
+
if (customData !== undefined) {
|
|
30886
|
+
dlg.custom_data = customData;
|
|
30887
|
+
}
|
|
30888
|
+
// Creation / modification metadata (present on CreatedDialog; also valid on
|
|
30889
|
+
// UpdatedDialog per server contract). Kept as ISO-8601 strings verbatim.
|
|
30890
|
+
var createdAt = chatUtils.getElementText(extraParams, 'created_at');
|
|
30891
|
+
if (createdAt !== undefined && createdAt !== null && createdAt !== '') {
|
|
30892
|
+
dlg.created_at = createdAt;
|
|
30893
|
+
}
|
|
30894
|
+
var updatedAt = chatUtils.getElementText(extraParams, 'updated_at');
|
|
30895
|
+
if (updatedAt !== undefined && updatedAt !== null && updatedAt !== '') {
|
|
30896
|
+
dlg.updated_at = updatedAt;
|
|
30897
|
+
}
|
|
30898
|
+
var userIdText = chatUtils.getElementText(extraParams, 'user_id');
|
|
30899
|
+
var userId = parseInt(userIdText, 10);
|
|
30900
|
+
if (!isNaN(userId)) {
|
|
30901
|
+
dlg.user_id = userId;
|
|
30902
|
+
}
|
|
30903
|
+
// Last message fields (present on UpdatedDialog; absent on a freshly
|
|
30904
|
+
// CreatedDialog — the guards below simply skip them then).
|
|
30905
|
+
var lmText = chatUtils.getElementText(extraParams, 'last_message');
|
|
30906
|
+
if (lmText) { dlg.last_message = lmText; }
|
|
30907
|
+
var lmId = chatUtils.getElementText(extraParams, 'last_message_id');
|
|
30908
|
+
if (lmId) { dlg.last_message_id = lmId; }
|
|
30909
|
+
var lmDsText = chatUtils.getElementText(extraParams, 'last_message_date_sent');
|
|
30910
|
+
var lmDs = parseInt(lmDsText, 10);
|
|
30911
|
+
if (!isNaN(lmDs)) { dlg.last_message_date_sent = lmDs; }
|
|
30912
|
+
var lmUidText = chatUtils.getElementText(extraParams, 'last_message_user_id');
|
|
30913
|
+
var lmUid = parseInt(lmUidText, 10);
|
|
30914
|
+
if (!isNaN(lmUid)) { dlg.last_message_user_id = lmUid; }
|
|
30915
|
+
|
|
30916
|
+
return dlg;
|
|
30917
|
+
}
|
|
30918
|
+
|
|
30826
30919
|
/**
|
|
30827
30920
|
* Parse a Notice headline stanza into {type, payload} ready for routing.
|
|
30828
30921
|
* Returns null if stanza is not a Notice (no urn:xmpp:notice:0 namespace, or
|
|
@@ -30918,59 +31011,12 @@ function _parseNoticeStanza(stanza) {
|
|
|
30918
31011
|
message: msg
|
|
30919
31012
|
};
|
|
30920
31013
|
}
|
|
30921
|
-
} else if (type === IDS.UPDATED_DIALOG) {
|
|
30922
|
-
//
|
|
30923
|
-
|
|
30924
|
-
dlg._id = dialogId;
|
|
30925
|
-
var name = chatUtils.getElementText(extraParams, 'name');
|
|
30926
|
-
if (name !== undefined && name !== null && name !== '') {
|
|
30927
|
-
dlg.name = name;
|
|
30928
|
-
}
|
|
30929
|
-
var photo = chatUtils.getElementText(extraParams, 'photo');
|
|
30930
|
-
if (photo !== undefined && photo !== null && photo !== '') {
|
|
30931
|
-
dlg.photo = photo;
|
|
30932
|
-
}
|
|
30933
|
-
var typeText = chatUtils.getElementText(extraParams, 'type');
|
|
30934
|
-
var typeNum = parseInt(typeText, 10);
|
|
30935
|
-
if (!isNaN(typeNum)) {
|
|
30936
|
-
dlg.type = typeNum;
|
|
30937
|
-
}
|
|
30938
|
-
var occupants = _parseNumericIdsCsv(chatUtils.getElementText(extraParams, 'occupants_ids'));
|
|
30939
|
-
if (occupants.length > 0) {
|
|
30940
|
-
dlg.occupants_ids = occupants;
|
|
30941
|
-
}
|
|
30942
|
-
var admins = _parseNumericIdsCsv(chatUtils.getElementText(extraParams, 'admin_ids'));
|
|
30943
|
-
if (admins.length > 0) {
|
|
30944
|
-
dlg.admin_ids = admins;
|
|
30945
|
-
}
|
|
30946
|
-
var isJoinReqText = chatUtils.getElementText(extraParams, 'is_join_required');
|
|
30947
|
-
if (isJoinReqText !== undefined && isJoinReqText !== null && isJoinReqText !== '') {
|
|
30948
|
-
var isJoinReq = parseInt(isJoinReqText, 10);
|
|
30949
|
-
dlg.is_join_required = isNaN(isJoinReq) ? isJoinReqText : isJoinReq;
|
|
30950
|
-
}
|
|
30951
|
-
var roomJid = chatUtils.getElementText(extraParams, 'xmpp_room_jid');
|
|
30952
|
-
if (roomJid !== undefined && roomJid !== null && roomJid !== '') {
|
|
30953
|
-
dlg.xmpp_room_jid = roomJid;
|
|
30954
|
-
}
|
|
30955
|
-
var customData = _parseCustomData(extraParams);
|
|
30956
|
-
if (customData !== undefined) {
|
|
30957
|
-
dlg.custom_data = customData;
|
|
30958
|
-
}
|
|
30959
|
-
// Last message fields.
|
|
30960
|
-
var lmText = chatUtils.getElementText(extraParams, 'last_message');
|
|
30961
|
-
if (lmText) { dlg.last_message = lmText; }
|
|
30962
|
-
var lmId = chatUtils.getElementText(extraParams, 'last_message_id');
|
|
30963
|
-
if (lmId) { dlg.last_message_id = lmId; }
|
|
30964
|
-
var lmDsText = chatUtils.getElementText(extraParams, 'last_message_date_sent');
|
|
30965
|
-
var lmDs = parseInt(lmDsText, 10);
|
|
30966
|
-
if (!isNaN(lmDs)) { dlg.last_message_date_sent = lmDs; }
|
|
30967
|
-
var lmUidText = chatUtils.getElementText(extraParams, 'last_message_user_id');
|
|
30968
|
-
var lmUid = parseInt(lmUidText, 10);
|
|
30969
|
-
if (!isNaN(lmUid)) { dlg.last_message_user_id = lmUid; }
|
|
30970
|
-
|
|
31014
|
+
} else if (type === IDS.UPDATED_DIALOG || type === IDS.CREATED_DIALOG) {
|
|
31015
|
+
// Full server dialog snapshot. UpdatedDialog and CreatedDialog (SR-2952)
|
|
31016
|
+
// share the same shape; they differ only by moduleIdentifier (routing).
|
|
30971
31017
|
payload = {
|
|
30972
31018
|
kind: 'dialog',
|
|
30973
|
-
dialog:
|
|
31019
|
+
dialog: _parseDialogSnapshot(extraParams, dialogId)
|
|
30974
31020
|
};
|
|
30975
31021
|
} else {
|
|
30976
31022
|
return null;
|
|
@@ -31017,6 +31063,10 @@ function _routeNoticeEvent(chatProxy, parsed) {
|
|
|
31017
31063
|
if (typeof chatProxy.onDialogUpdatedListener === 'function') {
|
|
31018
31064
|
Utils.safeCallbackCall(chatProxy.onDialogUpdatedListener, p.dialog);
|
|
31019
31065
|
}
|
|
31066
|
+
} else if (type === IDS.CREATED_DIALOG) {
|
|
31067
|
+
if (typeof chatProxy.onDialogCreatedListener === 'function') {
|
|
31068
|
+
Utils.safeCallbackCall(chatProxy.onDialogCreatedListener, p.dialog);
|
|
31069
|
+
}
|
|
31020
31070
|
}
|
|
31021
31071
|
}
|
|
31022
31072
|
|
|
@@ -31117,6 +31167,15 @@ function ChatProxy(service) {
|
|
|
31117
31167
|
this.onMessageReactionChangedListener = null;
|
|
31118
31168
|
this.onDialogDeletedListener = null;
|
|
31119
31169
|
this.onDialogUpdatedListener = null;
|
|
31170
|
+
/**
|
|
31171
|
+
* NoticeCreatedDialog listener (SR-2952). Fired when a Group or Private
|
|
31172
|
+
* dialog is created and the current user has the Notice feature enabled.
|
|
31173
|
+
* Signature: onDialogCreatedListener(dialog). The dialog is a partial
|
|
31174
|
+
* snapshot from the creation notice — it carries created_at/updated_at/
|
|
31175
|
+
* user_id (creator) but no last_message* fields (the dialog is brand new),
|
|
31176
|
+
* and for a private dialog no xmpp_room_jid. Not fired for Public dialogs.
|
|
31177
|
+
*/
|
|
31178
|
+
this.onDialogCreatedListener = null;
|
|
31120
31179
|
|
|
31121
31180
|
// [QC-1550] XMPP connection is considered "verified" only after the first
|
|
31122
31181
|
// successful pong response. Strophe emits Status.CONNECTED at the transport
|
|
@@ -32296,6 +32355,22 @@ ChatProxy.prototype = {
|
|
|
32296
32355
|
self._isConnecting = false;
|
|
32297
32356
|
self._sessionHasExpired = false;
|
|
32298
32357
|
|
|
32358
|
+
// [CROS-1061] A new XMPP session never carries the previous session's
|
|
32359
|
+
// Notice subscription: the server binds <enable xmlns="urn:xmpp:notice:0"/>
|
|
32360
|
+
// to the stream, so it is gone once the stream is gone. Without this
|
|
32361
|
+
// reset the flag stays `true` after a transport reconnect while no
|
|
32362
|
+
// notices are delivered any more, and isNoticesEnabled() misleads the
|
|
32363
|
+
// application into skipping the re-enable (verified against a live
|
|
32364
|
+
// server: socket break -> reconnect -> flag true, zero notice stanzas;
|
|
32365
|
+
// clearing the flag and re-sending <enable> restored delivery).
|
|
32366
|
+
//
|
|
32367
|
+
// Placed in the shared preamble, above the isInitialConnect branch, and
|
|
32368
|
+
// above the onReconnectListener call below: with
|
|
32369
|
+
// config.pingLocalhostTimeInterval === 0 that listener fires
|
|
32370
|
+
// synchronously from this function, and a consumer re-enabling notices
|
|
32371
|
+
// from it must not observe a stale `true`.
|
|
32372
|
+
self._isNoticesEnabled = false;
|
|
32373
|
+
|
|
32299
32374
|
self._enableCarbons();
|
|
32300
32375
|
|
|
32301
32376
|
if (isInitialConnect) {
|
|
@@ -32306,7 +32381,6 @@ ChatProxy.prototype = {
|
|
|
32306
32381
|
self._isConnectionVerified = true;
|
|
32307
32382
|
self._isReconnectListenerPending = false;
|
|
32308
32383
|
|
|
32309
|
-
// TODO(2.25.0): auto-enable Notice Feature here (see qbChat.js enableNotices JSDoc).
|
|
32310
32384
|
self.roster.get(function (contacts) {
|
|
32311
32385
|
xmppClient.send(presence);
|
|
32312
32386
|
|
|
@@ -32314,7 +32388,24 @@ ChatProxy.prototype = {
|
|
|
32314
32388
|
callback(self.roster.contacts);
|
|
32315
32389
|
});
|
|
32316
32390
|
} else {
|
|
32391
|
+
// [CROS-1061] Union of the rooms still tracked on this instance and
|
|
32392
|
+
// the ones an explicit reconnect() had to drop. Consumed once —
|
|
32393
|
+
// clearing it here keeps a later session (or another user after
|
|
32394
|
+
// logout) from resurrecting a stale list.
|
|
32395
|
+
//
|
|
32396
|
+
// Safe to build the join stanzas at this point: setUserCurrentJid()
|
|
32397
|
+
// above has already installed the new JID, and muc.join() derives
|
|
32398
|
+
// the presence `from` out of it. Moving this block above that call
|
|
32399
|
+
// would send from="".
|
|
32317
32400
|
var rooms = Object.keys(self.muc.joinedRooms);
|
|
32401
|
+
var remembered = self.muc._roomsToRejoin || [];
|
|
32402
|
+
|
|
32403
|
+
for (var r = 0; r < remembered.length; r++) {
|
|
32404
|
+
if (rooms.indexOf(remembered[r]) === -1) {
|
|
32405
|
+
rooms.push(remembered[r]);
|
|
32406
|
+
}
|
|
32407
|
+
}
|
|
32408
|
+
self.muc._roomsToRejoin = [];
|
|
32318
32409
|
|
|
32319
32410
|
xmppClient.send(presence);
|
|
32320
32411
|
|
|
@@ -32537,6 +32628,11 @@ ChatProxy.prototype = {
|
|
|
32537
32628
|
// connection had a chance to verify itself.
|
|
32538
32629
|
this._isConnectionVerified = false;
|
|
32539
32630
|
this._isReconnectListenerPending = false;
|
|
32631
|
+
// [CROS-1061] Remember the rooms before dropping them, so the re-join
|
|
32632
|
+
// loop in _postConnectActions has something to restore. Without this the
|
|
32633
|
+
// list is lost and group dialogs stop receiving message-level notices
|
|
32634
|
+
// until the page is reloaded.
|
|
32635
|
+
this.muc._roomsToRejoin = Object.keys(this.muc.joinedRooms);
|
|
32540
32636
|
this.muc.joinedRooms = {};
|
|
32541
32637
|
this.helpers.setUserCurrentJid('');
|
|
32542
32638
|
|
|
@@ -32930,6 +33026,9 @@ ChatProxy.prototype = {
|
|
|
32930
33026
|
this._checkConnectionTimer = undefined;
|
|
32931
33027
|
this._checkExpiredSessionTimer = undefined;
|
|
32932
33028
|
this.muc.joinedRooms = {};
|
|
33029
|
+
// [CROS-1061] Never carry rooms across a logout: re-joining the previous
|
|
33030
|
+
// user's rooms from a new JID is answered with 403/407 by the server.
|
|
33031
|
+
this.muc._roomsToRejoin = [];
|
|
32933
33032
|
// [QC-1550] Reset XMPP verification state on explicit disconnect so the
|
|
32934
33033
|
// next connect() starts from a clean slate. _isLogout guard below also
|
|
32935
33034
|
// prevents firing of deferred listeners if a pong arrives in flight,
|
|
@@ -32961,19 +33060,29 @@ ChatProxy.prototype = {
|
|
|
32961
33060
|
* Subscribe the current XMPP session to Notice Feature stanzas
|
|
32962
33061
|
* (urn:xmpp:notice:0). After a successful IQ result the server starts
|
|
32963
33062
|
* delivering NoticeUpdatedMessage / NoticeDeletedMessage /
|
|
32964
|
-
* NoticeUpdatedDialog / NoticeDeletedDialog
|
|
33063
|
+
* NoticeCreatedDialog / NoticeUpdatedDialog / NoticeDeletedDialog
|
|
33064
|
+
* headline stanzas.
|
|
32965
33065
|
*
|
|
32966
|
-
* The
|
|
32967
|
-
*
|
|
32968
|
-
*
|
|
33066
|
+
* The subscription belongs to the XMPP session, so it does not survive a
|
|
33067
|
+
* reconnect: the local enabled flag is reset to false whenever a new session
|
|
33068
|
+
* is established (initial connect and every reconnect alike) as well as on
|
|
33069
|
+
* disconnect. Consumers must call enableNotices() again after a reconnect —
|
|
33070
|
+
* an intentional divergence from the Android SDK, which auto-restores the
|
|
33071
|
+
* subscription. Reacting to onReconnectListener is the supported way to do
|
|
33072
|
+
* that.
|
|
32969
33073
|
*
|
|
32970
|
-
*
|
|
32971
|
-
*
|
|
32972
|
-
*
|
|
32973
|
-
*
|
|
33074
|
+
* Concurrent calls are safe: each IQ carries its own unique id, responses
|
|
33075
|
+
* are dispatched per id, and the flag is set independently for each result.
|
|
33076
|
+
* Calling enableNotices() again before the previous callback fires is
|
|
33077
|
+
* therefore allowed — for example when a second reconnect arrives while the
|
|
33078
|
+
* first enable is still in flight.
|
|
33079
|
+
*
|
|
33080
|
+
* If the server does not answer, the callback receives an error after a
|
|
33081
|
+
* timeout instead of never being called.
|
|
32974
33082
|
*
|
|
32975
|
-
*
|
|
32976
|
-
*
|
|
33083
|
+
* TODO(2.25.0): make auto-enable SDK-internal — fire on initial connect and
|
|
33084
|
+
* on every reconnect. Spec & three-state matrix are tracked in the internal
|
|
33085
|
+
* 2.25.0 backlog (auto-enable notices).
|
|
32977
33086
|
*
|
|
32978
33087
|
* @memberof QB.chat
|
|
32979
33088
|
* @param {enableNoticesCallback} callback - Called with (error, result) on IQ result.
|
|
@@ -33012,7 +33121,10 @@ ChatProxy.prototype = {
|
|
|
33012
33121
|
* Returns the local Notice Feature subscription flag.
|
|
33013
33122
|
* @memberof QB.chat
|
|
33014
33123
|
* @return {Boolean} true after a successful enableNotices(), false otherwise.
|
|
33015
|
-
* Reset to false on
|
|
33124
|
+
* Reset to false on disconnect and whenever a new XMPP session is
|
|
33125
|
+
* established, so after a reconnect it reports false until the consumer
|
|
33126
|
+
* enables notices again. Not synchronized with the server: it reflects
|
|
33127
|
+
* what this client last requested, not the server's own state.
|
|
33016
33128
|
* @since 2.24.0
|
|
33017
33129
|
*/
|
|
33018
33130
|
isNoticesEnabled: function () {
|
|
@@ -33065,10 +33177,34 @@ ChatProxy.prototype = {
|
|
|
33065
33177
|
}
|
|
33066
33178
|
|
|
33067
33179
|
if (Utils.getEnv().browser) {
|
|
33068
|
-
|
|
33180
|
+
// [CROS-1061] Without the 4th argument Strophe never times the IQ out,
|
|
33181
|
+
// so a server that stays silent leaves the caller without any callback
|
|
33182
|
+
// at all — the application spins forever. On timeout Strophe calls
|
|
33183
|
+
// _onError(null), which reports a 'cancel' error and leaves the flag
|
|
33184
|
+
// untouched.
|
|
33185
|
+
//
|
|
33186
|
+
// Note: this covers "server does not answer". It does NOT cover
|
|
33187
|
+
// "socket died", because the timeout is an addTimedHandler and
|
|
33188
|
+
// connection.reset() (called from the DISCONNECTED branch) clears
|
|
33189
|
+
// timedHandlers. That case is covered by the consumer-side timeout.
|
|
33190
|
+
self.connection.sendIQ(iq, _onSuccess, _onError, NOTICE_IQ_TIMEOUT_MS);
|
|
33069
33191
|
} else {
|
|
33070
33192
|
// Node/NativeScript path: register callback in nodeStanzasCallbacks map.
|
|
33193
|
+
// This path does not go through sendIQ, so the timeout is ours to run.
|
|
33194
|
+
var noticeIqTimer = setTimeout(function () {
|
|
33195
|
+
// Drop the pending entry first: _onIQ only dispatches while the
|
|
33196
|
+
// entry exists, so a late answer after this point is ignored
|
|
33197
|
+
// instead of invoking the callback a second time.
|
|
33198
|
+
delete self.nodeStanzasCallbacks[iqParams.id];
|
|
33199
|
+
_onError(null);
|
|
33200
|
+
}, NOTICE_IQ_TIMEOUT_MS);
|
|
33201
|
+
|
|
33071
33202
|
self.nodeStanzasCallbacks[iqParams.id] = function (stanza) {
|
|
33203
|
+
// Must be first: otherwise a timely answer still leaves the timer
|
|
33204
|
+
// armed, and it would fire later and call the callback a second
|
|
33205
|
+
// time with an error.
|
|
33206
|
+
clearTimeout(noticeIqTimer);
|
|
33207
|
+
|
|
33072
33208
|
// The map handler receives the result/error stanza. Inspect type to dispatch.
|
|
33073
33209
|
var iqType = chatUtils.getAttr(stanza, 'type');
|
|
33074
33210
|
if (iqType === 'result') {
|
|
@@ -33397,6 +33533,20 @@ function MucProxy(options) {
|
|
|
33397
33533
|
this.nodeStanzasCallbacks = options.nodeStanzasCallbacks;
|
|
33398
33534
|
//
|
|
33399
33535
|
this.joinedRooms = {};
|
|
33536
|
+
|
|
33537
|
+
/**
|
|
33538
|
+
* [CROS-1061] Rooms carried across an explicit QB.chat.reconnect().
|
|
33539
|
+
*
|
|
33540
|
+
* reconnect() has to clear joinedRooms — the new session holds no presence
|
|
33541
|
+
* yet — but until now it dropped the list without keeping a copy, so the
|
|
33542
|
+
* re-join loop in _postConnectActions found nothing to restore and group
|
|
33543
|
+
* dialogs silently stopped receiving message-level notices.
|
|
33544
|
+
*
|
|
33545
|
+
* Written only by reconnect(), read and cleared once by _postConnectActions,
|
|
33546
|
+
* and cleared by disconnect() so one user's rooms can never be re-joined
|
|
33547
|
+
* from another user's JID.
|
|
33548
|
+
*/
|
|
33549
|
+
this._roomsToRejoin = [];
|
|
33400
33550
|
}
|
|
33401
33551
|
|
|
33402
33552
|
MucProxy.prototype = {
|
|
@@ -35156,7 +35306,8 @@ var NOTICE_MODULE_IDENTIFIER = {
|
|
|
35156
35306
|
UPDATED_MESSAGE: 'NoticeUpdatedMessage',
|
|
35157
35307
|
DELETED_MESSAGE: 'NoticeDeletedMessage',
|
|
35158
35308
|
UPDATED_DIALOG: 'NoticeUpdatedDialog',
|
|
35159
|
-
DELETED_DIALOG: 'NoticeDeletedDialog'
|
|
35309
|
+
DELETED_DIALOG: 'NoticeDeletedDialog',
|
|
35310
|
+
CREATED_DIALOG: 'NoticeCreatedDialog'
|
|
35160
35311
|
};
|
|
35161
35312
|
|
|
35162
35313
|
module.exports = {
|
|
@@ -40569,8 +40720,8 @@ module.exports = StreamManagement;
|
|
|
40569
40720
|
*/
|
|
40570
40721
|
|
|
40571
40722
|
var config = {
|
|
40572
|
-
version: '2.24.
|
|
40573
|
-
buildNumber: '
|
|
40723
|
+
version: '2.24.1-alpha.1',
|
|
40724
|
+
buildNumber: '1181',
|
|
40574
40725
|
creds: {
|
|
40575
40726
|
'appId': 0,
|
|
40576
40727
|
'authKey': '',
|