quickblox 2.23.1-beta.5 → 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.
- package/package.json +1 -1
- package/quickblox.d.ts +216 -2
- package/quickblox.js +951 -124
- package/quickblox.min.js +1 -1
- package/src/modules/chat/qbChat.js +681 -2
- package/src/modules/chat/qbDialog.js +11 -2
- package/src/modules/chat/qbMessage.js +126 -0
- package/src/modules/chat/qbNoticeConsts.js +32 -0
- package/src/modules/webrtc/qbRTCPeerConnection.js +74 -95
- package/src/qbConfig.js +1 -1
- package/__getStats-mediaType-guard-fix-plan.md +0 -353
|
@@ -39,9 +39,11 @@ DialogProxy.prototype = {
|
|
|
39
39
|
},
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
* Create new dialog({@link https://docs.quickblox.com/
|
|
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/
|
|
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
|
-
|
|
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
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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
|
-
|
|
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;
|