quickblox 2.23.1-beta.6 → 2.24.0-beta.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.
@@ -39,9 +39,11 @@ DialogProxy.prototype = {
39
39
  },
40
40
 
41
41
  /**
42
- * Create new dialog({@link https://docs.quickblox.com/docs/js-chat-dialogs#create-dialog read more}).
42
+ * Create new dialog({@link https://docs.quickblox.com/reference/create-dialog read more}).
43
43
  * @memberof QB.chat.dialog
44
44
  * @param {Object} params - Object of parameters.
45
+ * @param {Number[]|String} [params.admin_ids] - IDs of dialog admins for public/group dialogs.
46
+ * Ignored by the backend for private dialogs.
45
47
  * @param {createDialogCallback} callback - The callback function.
46
48
  * */
47
49
  create: function(params, callback) {
@@ -56,6 +58,10 @@ DialogProxy.prototype = {
56
58
  params.occupants_ids = params.occupants_ids.join(', ');
57
59
  }
58
60
 
61
+ if (params && params.admin_ids && Utils.isArray(params.admin_ids)) {
62
+ params.admin_ids = params.admin_ids.join(', ');
63
+ }
64
+
59
65
  if (params && params.is_join_required !== undefined && params.is_join_required !== null) {
60
66
  if (params.is_join_required !== 0 && params.is_join_required !== 1) {
61
67
  Utils.QBLog('[QBChat]', 'Warning: is_join_required must be 0 or 1, got: ' +
@@ -72,10 +78,13 @@ DialogProxy.prototype = {
72
78
  },
73
79
 
74
80
  /**
75
- * Update group dialog({@link https://docs.quickblox.com/docs/js-chat-dialogs#update-dialog read more}).
81
+ * Update group dialog({@link https://docs.quickblox.com/reference/update-dialog read more}).
76
82
  * @memberof QB.chat.dialog
77
83
  * @param {String} id - The dialog ID.
78
84
  * @param {Object} params - Object of parameters.
85
+ * @param {Number[]|String} [params.admin_ids] - Full replacement list of dialog admins.
86
+ * @param {Object} [params.push_all] - Incremental fields to append, including admin_ids.
87
+ * @param {Object} [params.pull_all] - Incremental fields to remove, including admin_ids.
79
88
  * @param {updateDialogCallback} callback - The callback function.
80
89
  * */
81
90
  update: function(id, params, callback) {
@@ -17,6 +17,9 @@ MessageProxy.prototype = {
17
17
  * Get a chat history({@link https://docs.quickblox.com/docs/js-chat-messaging#retrieve-chat-history read more}).
18
18
  * @memberof QB.chat.message
19
19
  * @param {Object} params - Object of parameters.
20
+ * @param {Number} [params.include_reactions] - Include message reactions in the response.
21
+ * Allowed values: 0 (default, no reactions data) or 1 (include reactions[] per message).
22
+ * Reactions array shape: [{ name, count, user_ids: number[] }].
20
23
  * @param {listMessageCallback} callback - The callback function.
21
24
  * */
22
25
  list: function(params, callback) {
@@ -114,6 +117,129 @@ MessageProxy.prototype = {
114
117
  }
115
118
  },
116
119
 
120
+ /**
121
+ * Get a chat message by ID
122
+ * ({@link https://docs.quickblox.com/reference/get-message-by-id read more}).
123
+ * @memberof QB.chat.message
124
+ * @param {String} id - The message id.
125
+ * @param {Object} [params] - Optional query parameters.
126
+ * @param {Number} [params.include_reactions] - Include message reactions in the response (0 or 1).
127
+ * @param {getByIdMessageCallback} callback - The callback function.
128
+ * @since 2.24.0
129
+ * */
130
+ getById: function(id, params_or_callback, callback) {
131
+ /**
132
+ * Callback for QB.chat.message.getById().
133
+ * @param {Object} error - The error object.
134
+ * @param {Object} message - The message object.
135
+ * @callback getByIdMessageCallback
136
+ * */
137
+
138
+ var ajaxParams = {
139
+ url: Utils.getUrl(MESSAGES_API_URL, id)
140
+ };
141
+
142
+ if (arguments.length === 2) {
143
+ this.service.ajax(ajaxParams, params_or_callback);
144
+ } else if (arguments.length === 3) {
145
+ ajaxParams.data = params_or_callback;
146
+
147
+ this.service.ajax(ajaxParams, callback);
148
+ }
149
+ },
150
+
151
+ /**
152
+ * Add reaction to a message.
153
+ * @memberof QB.chat.message
154
+ * @param {String} id - The message id.
155
+ * @param {String} name - The reaction name.
156
+ * @param {addReactionCallback} callback - The callback function.
157
+ *
158
+ * Server contract:
159
+ * POST /chat/Message/{id}/reactions
160
+ * Success: 201 Created with empty body.
161
+ * Errors: 400 (invalid id/name or reaction limits), 404 (message not found), 422 (public dialog).
162
+ *
163
+ * Idempotency note: Re-adding the same reaction by the same user returns 201 without creating a duplicate reaction.
164
+ * */
165
+ addReaction: function(id, name, callback) {
166
+ /**
167
+ * Callback for QB.chat.message.addReaction().
168
+ * @param {Object} error - The error object.
169
+ * @param {Object|undefined} reaction - Empty response body on success.
170
+ * @callback addReactionCallback
171
+ * */
172
+
173
+ // Server returns 201 with empty body. Use dataType:'text' so qbProxy does
174
+ // not try to JSON.parse the empty response (which throws in node-fetch).
175
+ this.service.ajax({
176
+ url: Utils.getUrl(MESSAGES_API_URL + '/' + id + '/reactions'),
177
+ type: 'POST',
178
+ contentType: 'application/json; charset=utf-8',
179
+ isNeedStringify: true,
180
+ dataType: 'text',
181
+ data: {
182
+ name: name
183
+ }
184
+ }, callback);
185
+ },
186
+
187
+ /**
188
+ * Remove reaction from a message.
189
+ * @memberof QB.chat.message
190
+ * @param {String} id - The message id.
191
+ * @param {String} name - The reaction name.
192
+ * @param {removeReactionCallback} callback - The callback function.
193
+ *
194
+ * Server contract:
195
+ * DELETE /chat/Message/{id}/reactions
196
+ * Success: 200 OK with empty body.
197
+ * Errors: 400 (invalid id/name), 404 (message not found or reaction not found).
198
+ * */
199
+ removeReaction: function(id, name, callback) {
200
+ /**
201
+ * Callback for QB.chat.message.removeReaction().
202
+ * @param {Object} error - The error object.
203
+ * @param {String} response - Empty body.
204
+ * @callback removeReactionCallback
205
+ * */
206
+
207
+ this.service.ajax({
208
+ url: Utils.getUrl(MESSAGES_API_URL + '/' + id + '/reactions'),
209
+ type: 'DELETE',
210
+ contentType: 'application/json; charset=utf-8',
211
+ isNeedStringify: true,
212
+ dataType: 'text',
213
+ data: {
214
+ name: name
215
+ }
216
+ }, callback);
217
+ },
218
+
219
+ /**
220
+ * Get reactions list for a message.
221
+ * @memberof QB.chat.message
222
+ * @param {String} id - The message id.
223
+ * @param {listReactionsCallback} callback - The callback function.
224
+ *
225
+ * Server contract:
226
+ * GET /chat/Message/{id}/reactions
227
+ * Success: 200 OK, body { total_entries: Number, items: Array<{ name, count, user_ids[] }> }.
228
+ * Errors: 400 (invalid id), 404 (message not found).
229
+ * */
230
+ listReactions: function(id, callback) {
231
+ /**
232
+ * Callback for QB.chat.message.listReactions().
233
+ * @param {Object} error - The error object.
234
+ * @param {Object} reactions - The reactions aggregate object.
235
+ * @callback listReactionsCallback
236
+ * */
237
+
238
+ this.service.ajax({
239
+ url: Utils.getUrl(MESSAGES_API_URL + '/' + id + '/reactions')
240
+ }, callback);
241
+ },
242
+
117
243
  /**
118
244
  * Get unread messages counter for one or group of dialogs({@link https://docs.quickblox.com/docs/js-chat-dialogs#get-number-of-unread-messages read more}).
119
245
  * @memberof QB.chat.message
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Shared constants for the Notice Feature (XMPP `urn:xmpp:notice:0`).
5
+ *
6
+ * Foundation module for SDK 2.24.0 — imported by Notice / Reaction / Admin Role
7
+ * runtime modules in their respective feature branches. No runtime behavior here.
8
+ *
9
+ * Mirror of Android `com.quickblox.chat.notice.QBNoticeConsts`.
10
+ */
11
+
12
+ /**
13
+ * XMPP namespace for Notice IQ stanzas (`<enable>`, `<disable>`) and for the
14
+ * `<moduleIdentifier>` element on inbound notice messages.
15
+ */
16
+ var NOTICE_NAMESPACE = 'urn:xmpp:notice:0';
17
+
18
+ /**
19
+ * Discriminator strings carried in the `<moduleIdentifier>` element of
20
+ * inbound notice stanzas. Used for routing in the headline-message handler.
21
+ */
22
+ var NOTICE_MODULE_IDENTIFIER = {
23
+ UPDATED_MESSAGE: 'NoticeUpdatedMessage',
24
+ DELETED_MESSAGE: 'NoticeDeletedMessage',
25
+ UPDATED_DIALOG: 'NoticeUpdatedDialog',
26
+ DELETED_DIALOG: 'NoticeDeletedDialog'
27
+ };
28
+
29
+ module.exports = {
30
+ NOTICE_NAMESPACE: NOTICE_NAMESPACE,
31
+ NOTICE_MODULE_IDENTIFIER: NOTICE_MODULE_IDENTIFIER
32
+ };
@@ -542,110 +542,92 @@ function _getStats(peer, lastResults, successCallback, errorCallback) {
542
542
 
543
543
  peer.getStats(null).then(function (results) {
544
544
  results.forEach(function (result) {
545
- _applyStatReport(statistic, result, lastResults);
545
+ var item;
546
+
547
+ if (result.bytesReceived && result.type === 'inbound-rtp') {
548
+ item = statistic.remote[result.mediaType];
549
+ item.bitrate = _getBitratePerSecond(result, lastResults, false);
550
+ item.bytesReceived = result.bytesReceived;
551
+ item.packetsReceived = result.packetsReceived;
552
+ item.timestamp = result.timestamp;
553
+ if (result.mediaType === 'video' && result.framerateMean) {
554
+ item.framesPerSecond = Math.round(result.framerateMean * 10) / 10;
555
+ }
556
+ } else if (result.bytesSent && result.type === 'outbound-rtp') {
557
+ item = statistic.local[result.mediaType];
558
+ item.bitrate = _getBitratePerSecond(result, lastResults, true);
559
+ item.bytesSent = result.bytesSent;
560
+ item.packetsSent = result.packetsSent;
561
+ item.timestamp = result.timestamp;
562
+ if (result.mediaType === 'video' && result.framerateMean) {
563
+ item.framesPerSecond = Math.round(result.framerateMean * 10) / 10;
564
+ }
565
+ } else if (result.type === 'local-candidate') {
566
+ item = statistic.local.candidate;
567
+ if (result.candidateType === 'host' && result.mozLocalTransport === 'udp' && result.transport === 'udp') {
568
+ item.protocol = result.transport;
569
+ item.ip = result.ipAddress;
570
+ item.port = result.portNumber;
571
+ } else if (!Helpers.getVersionFirefox()) {
572
+ item.protocol = result.protocol;
573
+ item.ip = result.ip;
574
+ item.port = result.port;
575
+ }
576
+ } else if (result.type === 'remote-candidate') {
577
+ item = statistic.remote.candidate;
578
+ item.protocol = result.protocol || result.transport;
579
+ item.ip = result.ip || result.ipAddress;
580
+ item.port = result.port || result.portNumber;
581
+ } else if (result.type === 'track' && result.kind === 'video' && !Helpers.getVersionFirefox()) {
582
+ if (result.remoteSource) {
583
+ item = statistic.remote.video;
584
+ item.frameHeight = result.frameHeight;
585
+ item.frameWidth = result.frameWidth;
586
+ item.framesPerSecond = _getFramesPerSecond(result, lastResults, false);
587
+ } else {
588
+ item = statistic.local.video;
589
+ item.frameHeight = result.frameHeight;
590
+ item.frameWidth = result.frameWidth;
591
+ item.framesPerSecond = _getFramesPerSecond(result, lastResults, true);
592
+ }
593
+ }
546
594
  });
547
595
  successCallback(statistic, results);
548
596
  }, errorCallback);
549
- }
550
597
 
551
- function _applyStatReport(statistic, result, lastResults) {
552
- var item;
553
- // mediaType is deprecated in the W3C webrtc-stats spec and replaced by kind.
554
- // Safari/WebKit omits mediaType on some reports and provides only kind, so we
555
- // normalize once and use it for both the statistic lookup and the 'video' check.
556
- var mediaType = result.mediaType || result.kind;
557
-
558
- if (result.bytesReceived && result.type === 'inbound-rtp') {
559
- item = statistic.remote[mediaType];
560
-
561
- if (item) {
562
- item.bitrate = _getBitratePerSecond(result, lastResults, false);
563
- item.bytesReceived = result.bytesReceived;
564
- item.packetsReceived = result.packetsReceived;
565
- item.timestamp = result.timestamp;
566
- if (mediaType === 'video' && result.framerateMean) {
567
- item.framesPerSecond = Math.round(result.framerateMean * 10) / 10;
568
- }
569
- } else {
570
- Helpers.traceWarning('_getStats: skipping inbound-rtp report with unknown mediaType/kind: ' + mediaType);
571
- }
572
- } else if (result.bytesSent && result.type === 'outbound-rtp') {
573
- item = statistic.local[mediaType];
574
-
575
- if (item) {
576
- item.bitrate = _getBitratePerSecond(result, lastResults, true);
577
- item.bytesSent = result.bytesSent;
578
- item.packetsSent = result.packetsSent;
579
- item.timestamp = result.timestamp;
580
- if (mediaType === 'video' && result.framerateMean) {
581
- item.framesPerSecond = Math.round(result.framerateMean * 10) / 10;
582
- }
583
- } else {
584
- Helpers.traceWarning('_getStats: skipping outbound-rtp report with unknown mediaType/kind: ' + mediaType);
585
- }
586
- } else if (result.type === 'local-candidate') {
587
- item = statistic.local.candidate;
588
- if (result.candidateType === 'host' && result.mozLocalTransport === 'udp' && result.transport === 'udp') {
589
- item.protocol = result.transport;
590
- item.ip = result.ipAddress;
591
- item.port = result.portNumber;
592
- } else if (!Helpers.getVersionFirefox()) {
593
- item.protocol = result.protocol;
594
- item.ip = result.ip;
595
- item.port = result.port;
596
- }
597
- } else if (result.type === 'remote-candidate') {
598
- item = statistic.remote.candidate;
599
- item.protocol = result.protocol || result.transport;
600
- item.ip = result.ip || result.ipAddress;
601
- item.port = result.port || result.portNumber;
602
- } else if (result.type === 'track' && result.kind === 'video' && !Helpers.getVersionFirefox()) {
603
- if (result.remoteSource) {
604
- item = statistic.remote.video;
605
- item.frameHeight = result.frameHeight;
606
- item.frameWidth = result.frameWidth;
607
- item.framesPerSecond = _getFramesPerSecond(result, lastResults, false);
598
+ function _getBitratePerSecond(result, lastResults, isLocal) {
599
+ var lastResult = lastResults && lastResults.get(result.id),
600
+ seconds = lastResult ? ((result.timestamp - lastResult.timestamp) / 1000) : 5,
601
+ kilo = 1024,
602
+ bit = 8,
603
+ bitrate;
604
+
605
+ if (!lastResult) {
606
+ bitrate = 0;
607
+ } else if (isLocal) {
608
+ bitrate = bit * (result.bytesSent - lastResult.bytesSent) / (kilo * seconds);
608
609
  } else {
609
- item = statistic.local.video;
610
- item.frameHeight = result.frameHeight;
611
- item.frameWidth = result.frameWidth;
612
- item.framesPerSecond = _getFramesPerSecond(result, lastResults, true);
610
+ bitrate = bit * (result.bytesReceived - lastResult.bytesReceived) / (kilo * seconds);
613
611
  }
614
- }
615
- }
616
612
 
617
- function _getBitratePerSecond(result, lastResults, isLocal) {
618
- var lastResult = lastResults && lastResults.get(result.id),
619
- seconds = lastResult ? ((result.timestamp - lastResult.timestamp) / 1000) : 5,
620
- kilo = 1024,
621
- bit = 8,
622
- bitrate;
623
-
624
- if (!lastResult) {
625
- bitrate = 0;
626
- } else if (isLocal) {
627
- bitrate = bit * (result.bytesSent - lastResult.bytesSent) / (kilo * seconds);
628
- } else {
629
- bitrate = bit * (result.bytesReceived - lastResult.bytesReceived) / (kilo * seconds);
613
+ return Math.round(bitrate);
630
614
  }
631
615
 
632
- return Math.round(bitrate);
633
- }
616
+ function _getFramesPerSecond(result, lastResults, isLocal) {
617
+ var lastResult = lastResults && lastResults.get(result.id),
618
+ seconds = lastResult ? ((result.timestamp - lastResult.timestamp) / 1000) : 5,
619
+ framesPerSecond;
634
620
 
635
- function _getFramesPerSecond(result, lastResults, isLocal) {
636
- var lastResult = lastResults && lastResults.get(result.id),
637
- seconds = lastResult ? ((result.timestamp - lastResult.timestamp) / 1000) : 5,
638
- framesPerSecond;
621
+ if (!lastResult) {
622
+ framesPerSecond = 0;
623
+ } else if (isLocal) {
624
+ framesPerSecond = (result.framesSent - lastResult.framesSent) / seconds;
625
+ } else {
626
+ framesPerSecond = (result.framesReceived - lastResult.framesReceived) / seconds;
627
+ }
639
628
 
640
- if (!lastResult) {
641
- framesPerSecond = 0;
642
- } else if (isLocal) {
643
- framesPerSecond = (result.framesSent - lastResult.framesSent) / seconds;
644
- } else {
645
- framesPerSecond = (result.framesReceived - lastResult.framesReceived) / seconds;
629
+ return Math.round(framesPerSecond * 10) / 10;
646
630
  }
647
-
648
- return Math.round(framesPerSecond * 10) / 10;
649
631
  }
650
632
 
651
633
  // Find the line in sdpLines[startLine...endLine - 1] that starts with |prefix|
@@ -832,7 +814,4 @@ function setMediaBitrate(sdp, media, bitrate) {
832
814
  return newLines.join('\n');
833
815
  }
834
816
 
835
- // PRIVATE - exposed for unit tests only, not part of the public SDK contract.
836
- qbRTCPeerConnection._applyStatReport = _applyStatReport;
837
-
838
817
  module.exports = qbRTCPeerConnection;
package/src/qbConfig.js CHANGED
@@ -12,7 +12,7 @@
12
12
  */
13
13
 
14
14
  var config = {
15
- version: '2.23.1-beta.6',
15
+ version: '2.24.0-beta.1',
16
16
  buildNumber: '1179',
17
17
  creds: {
18
18
  'appId': 0,
@@ -1,235 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * QuickBlox JavaScript SDK
5
- * Chat Stream Management plugin
6
- * doc: http://xmpp.org/extensions/xep-0198.html
7
- *
8
- * To enable this features add to config
9
- * ```javascript
10
- * streamManagement: {
11
- - enable: true
12
- - }
13
- * ```
14
- *
15
- * Uses listener by QB.chat.onSentMessageCallback
16
- *
17
- * ```javascript
18
- * QB.chat.onSentMessageCallback = function (messageLost, messageSent) {
19
- * if (messageLost) {
20
- * console.error('sendErrorCallback', messageLost);
21
- * } else {
22
- * console.info('sendMessageSuccessCallback', messageSent);
23
- * }
24
- * };
25
- * ```
26
- */
27
-
28
- /** JSHint inline rules */
29
- /* globals $build */
30
-
31
- var Utils = require('../qbUtils'),
32
- chatUtils = require('../modules/chat/qbChatHelpers');
33
-
34
- function StreamManagement(options) {
35
-
36
- this._NS = 'urn:xmpp:sm:3';
37
-
38
- this._isStreamManagementEnabled = false;
39
-
40
- // Counter of the incoming stanzas
41
- this._clientProcessedStanzasCounter = null;
42
-
43
- // The client send stanza counter.
44
- this._clientSentStanzasCounter = null;
45
-
46
- this._intervalId = null;
47
-
48
- this._timeInterval = Utils.getTimeIntervalForCallBackMessage();
49
-
50
- this.sentMessageCallback = null;
51
-
52
- if(Utils.getEnv().browser){
53
- this._parser = new DOMParser();
54
- }
55
-
56
- // connection
57
- this._c = null;
58
-
59
- this._nodeBuilder = null;
60
- // Original connection.send method
61
- this._originalSend = null;
62
-
63
- // In progress stanzas queue
64
- this._stanzasQueue = [];
65
- }
66
-
67
-
68
- StreamManagement.prototype.enable = function (connection, client) {
69
- var self = this,
70
- stanza,
71
- enableParams = {
72
- xmlns: self._NS
73
- };
74
-
75
- if(!self._isStreamManagementEnabled){
76
- self._c = connection;
77
- self._originalSend = this._c.send;
78
- self._c.send = this.send.bind(self);
79
- }
80
-
81
- if(Utils.getEnv().browser){
82
- this._clientProcessedStanzasCounter = null;
83
- this._clientSentStanzasCounter = null;
84
- self._addEnableHandlers();
85
- stanza = $build('enable', enableParams);
86
- } else {
87
- self._nodeBuilder = client.Stanza;
88
- self._addEnableHandlers();
89
- stanza = chatUtils.createStanza(self._nodeBuilder, enableParams, 'enable');
90
- }
91
-
92
- self._c.send(stanza);
93
- };
94
-
95
- StreamManagement.prototype._timeoutCallback = function () {
96
- var self = this,
97
- now = Date.now(),
98
- updatedStanzasQueue = [];
99
-
100
- if(self._stanzasQueue.length){
101
- for(var i = 0; i < self._stanzasQueue.length; i++){
102
- if(self._stanzasQueue[i] && self._stanzasQueue[i].time < now){
103
- self.sentMessageCallback(self._stanzasQueue[i].message);
104
- } else {
105
- updatedStanzasQueue.push(self._stanzasQueue[i]);
106
- }
107
- }
108
-
109
- self._stanzasQueue = updatedStanzasQueue;
110
- }
111
- };
112
-
113
- StreamManagement.prototype._addEnableHandlers = function () {
114
- var self = this;
115
-
116
- if (Utils.getEnv().browser) {
117
- self._c.XAddTrackedHandler(_incomingStanzaHandler.bind(self));
118
- } else {
119
- self._c.on('stanza', _incomingStanzaHandler.bind(self));
120
- }
121
-
122
- function _incomingStanzaHandler (stanza){
123
- /*
124
- * Getting incoming stanza tagName
125
- * */
126
-
127
- var tagName = stanza.name || stanza.tagName || stanza.nodeTree.tagName;
128
-
129
- if(tagName === 'enabled'){
130
- self._isStreamManagementEnabled = true;
131
-
132
- return true;
133
- }
134
-
135
- if (self._isStreamManagementEnabled && tagName === 'message') {
136
- clearInterval(self._intervalId);
137
- self._intervalId = setInterval(self._timeoutCallback.bind(self), self._timeInterval);
138
-
139
- return true;
140
- }
141
-
142
- if(chatUtils.getAttr(stanza, 'xmlns') !== self._NS){
143
- self._increaseReceivedStanzasCounter();
144
- }
145
-
146
- if(tagName === 'r'){
147
- var params = {
148
- xmlns: self._NS,
149
- h: self._clientProcessedStanzasCounter
150
- },
151
- answerStanza = Utils.getEnv().browser ? $build('a', params) :
152
- chatUtils.createStanza(self._nodeBuilder, params, 'a');
153
-
154
- self._originalSend.call(self._c, answerStanza);
155
-
156
- return true;
157
- }
158
-
159
- if(tagName === 'a'){
160
- var h = parseInt(chatUtils.getAttr(stanza, 'h'));
161
-
162
- self._checkCounterOnIncomeStanza(h);
163
- }
164
-
165
- return true;
166
- }
167
- };
168
-
169
- StreamManagement.prototype.send = function (stanza, message) {
170
- var self = this,
171
- stanzaXML = stanza.nodeTree ? this._parser.parseFromString(stanza.nodeTree.outerHTML, "application/xml").childNodes[0] : stanza,
172
- tagName = stanzaXML.name || stanzaXML.tagName || stanzaXML.nodeTree.tagName,
173
- type = chatUtils.getAttr(stanzaXML, 'type'),
174
- bodyContent = chatUtils.getElementText(stanzaXML, 'body') || '',
175
- attachments = chatUtils.getAllElements(stanzaXML, 'attachment') || '';
176
-
177
- try {
178
- self._originalSend.call(self._c, stanza);
179
- } catch (e) {
180
- Utils.QBLog('[QBChat]', e.message);
181
- } finally {
182
- if (tagName === 'message' && (type === 'chat' || type === 'groupchat') && (bodyContent || attachments.length)) {
183
- self._sendStanzasRequest({
184
- message: message,
185
- time: Date.now() + self._timeInterval,
186
- expect: self._clientSentStanzasCounter
187
- });
188
- }
189
-
190
- self._clientSentStanzasCounter++;
191
- }
192
-
193
- };
194
-
195
- StreamManagement.prototype._sendStanzasRequest = function (data) {
196
- var self = this;
197
-
198
- if(self._isStreamManagementEnabled){
199
- self._stanzasQueue.push(data);
200
-
201
- var stanza = Utils.getEnv().browser ? $build('r', { xmlns: self._NS }) :
202
- chatUtils.createStanza(self._nodeBuilder, { xmlns: self._NS }, 'r');
203
-
204
- if (self._c.connected) {
205
- self._originalSend.call(self._c, stanza);
206
- } else {
207
- self._checkCounterOnIncomeStanza();
208
- }
209
- }
210
- };
211
-
212
- StreamManagement.prototype.getClientSentStanzasCounter = function(){
213
- return this._clientSentStanzasCounter;
214
- };
215
-
216
- StreamManagement.prototype._checkCounterOnIncomeStanza = function (count){
217
- var updatedStanzasQueue = [];
218
-
219
- if(this._stanzasQueue.length){
220
- for(var i = 0; i < this._stanzasQueue.length; i++){
221
- if(this._stanzasQueue[i].expect == count){
222
- this.sentMessageCallback(null, this._stanzasQueue[i].message);
223
- } else {
224
- updatedStanzasQueue.push(this._stanzasQueue[i]);
225
- }
226
- }
227
- this._stanzasQueue = updatedStanzasQueue;
228
- }
229
- };
230
-
231
- StreamManagement.prototype._increaseReceivedStanzasCounter = function(){
232
- this._clientProcessedStanzasCounter++;
233
- };
234
-
235
- module.exports = StreamManagement;