stream-chat 6.2.0 → 6.3.0

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/dist/index.es.js CHANGED
@@ -103,6 +103,13 @@ var ChannelState = /*#__PURE__*/function () {
103
103
  * When false, any new message (received by websocket event - message.new) will not
104
104
  * be pushed on to message list.
105
105
  */
106
+
107
+ /**
108
+ * Disjoint lists of messages
109
+ * Users can jump in the message list (with searching) and this can result in disjoint lists of messages
110
+ * The state manages these lists and merges them when lists overlap
111
+ * The messages array contains the currently active set
112
+ */
106
113
  function ChannelState(channel) {
107
114
  var _this = this,
108
115
  _channel$state;
@@ -117,8 +124,6 @@ var ChannelState = /*#__PURE__*/function () {
117
124
 
118
125
  _defineProperty(this, "read", void 0);
119
126
 
120
- _defineProperty(this, "messages", void 0);
121
-
122
127
  _defineProperty(this, "pinnedMessages", void 0);
123
128
 
124
129
  _defineProperty(this, "threads", void 0);
@@ -137,6 +142,8 @@ var ChannelState = /*#__PURE__*/function () {
137
142
 
138
143
  _defineProperty(this, "isUpToDate", void 0);
139
144
 
145
+ _defineProperty(this, "messageSets", []);
146
+
140
147
  _defineProperty(this, "setIsUpToDate", function (isUpToDate) {
141
148
  _this.isUpToDate = isUpToDate;
142
149
  });
@@ -166,7 +173,9 @@ var ChannelState = /*#__PURE__*/function () {
166
173
  }
167
174
  };
168
175
 
169
- _updateUserMessages(_this.messages, user);
176
+ _this.messageSets.forEach(function (set) {
177
+ return _updateUserMessages(set.messages, user);
178
+ });
170
179
 
171
180
  for (var parentId in _this.threads) {
172
181
  _updateUserMessages(_this.threads[parentId], user);
@@ -220,7 +229,9 @@ var ChannelState = /*#__PURE__*/function () {
220
229
  }
221
230
  };
222
231
 
223
- _deleteUserMessages(_this.messages, user, hardDelete);
232
+ _this.messageSets.forEach(function (set) {
233
+ return _deleteUserMessages(set.messages, user, hardDelete);
234
+ });
224
235
 
225
236
  for (var parentId in _this.threads) {
226
237
  _deleteUserMessages(_this.threads[parentId], user, hardDelete);
@@ -233,7 +244,7 @@ var ChannelState = /*#__PURE__*/function () {
233
244
  this.watcher_count = 0;
234
245
  this.typing = {};
235
246
  this.read = {};
236
- this.messages = [];
247
+ this.initMessages();
237
248
  this.pinnedMessages = [];
238
249
  this.threads = {}; // a list of users to hide messages from
239
250
 
@@ -252,22 +263,58 @@ var ChannelState = /*#__PURE__*/function () {
252
263
  this.isUpToDate = true;
253
264
  this.last_message_at = (channel === null || channel === void 0 ? void 0 : (_channel$state = channel.state) === null || _channel$state === void 0 ? void 0 : _channel$state.last_message_at) != null ? new Date(channel.state.last_message_at) : null;
254
265
  }
255
- /**
256
- * addMessageSorted - Add a message to the state
257
- *
258
- * @param {MessageResponse<StreamChatGenerics>} newMessage A new message
259
- * @param {boolean} timestampChanged Whether updating a message with changed created_at value.
260
- * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.
261
- *
262
- */
263
-
264
266
 
265
267
  _createClass(ChannelState, [{
268
+ key: "messages",
269
+ get: function get() {
270
+ var _this$messageSets$fin;
271
+
272
+ return ((_this$messageSets$fin = this.messageSets.find(function (s) {
273
+ return s.isCurrent;
274
+ })) === null || _this$messageSets$fin === void 0 ? void 0 : _this$messageSets$fin.messages) || [];
275
+ },
276
+ set: function set(messages) {
277
+ var index = this.messageSets.findIndex(function (s) {
278
+ return s.isCurrent;
279
+ });
280
+ this.messageSets[index].messages = messages;
281
+ }
282
+ /**
283
+ * The list of latest messages
284
+ * The messages array not always contains the latest messages (for example if a user searched for an earlier message, that is in a different message set)
285
+ */
286
+
287
+ }, {
288
+ key: "latestMessages",
289
+ get: function get() {
290
+ var _this$messageSets$fin2;
291
+
292
+ return ((_this$messageSets$fin2 = this.messageSets.find(function (s) {
293
+ return s.isLatest;
294
+ })) === null || _this$messageSets$fin2 === void 0 ? void 0 : _this$messageSets$fin2.messages) || [];
295
+ },
296
+ set: function set(messages) {
297
+ var index = this.messageSets.findIndex(function (s) {
298
+ return s.isLatest;
299
+ });
300
+ this.messageSets[index].messages = messages;
301
+ }
302
+ /**
303
+ * addMessageSorted - Add a message to the state
304
+ *
305
+ * @param {MessageResponse<StreamChatGenerics>} newMessage A new message
306
+ * @param {boolean} timestampChanged Whether updating a message with changed created_at value.
307
+ * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.
308
+ * @param {MessageSetType} messageSetToAddToIfDoesNotExist Which message set to add to if message is not in the list (only used if addIfDoesNotExist is true)
309
+ */
310
+
311
+ }, {
266
312
  key: "addMessageSorted",
267
313
  value: function addMessageSorted(newMessage) {
268
314
  var timestampChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
269
315
  var addIfDoesNotExist = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
270
- return this.addMessagesSorted([newMessage], timestampChanged, false, addIfDoesNotExist);
316
+ var messageSetToAddToIfDoesNotExist = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'latest';
317
+ return this.addMessagesSorted([newMessage], timestampChanged, false, addIfDoesNotExist, messageSetToAddToIfDoesNotExist);
271
318
  }
272
319
  /**
273
320
  * formatMessage - Takes the message object. Parses the dates, sets __html
@@ -299,6 +346,7 @@ var ChannelState = /*#__PURE__*/function () {
299
346
  * @param {boolean} timestampChanged Whether updating messages with changed created_at value.
300
347
  * @param {boolean} initializing Whether channel is being initialized.
301
348
  * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.
349
+ * @param {MessageSetType} messageSetToAddToIfDoesNotExist Which message set to add to if messages are not in the list (only used if addIfDoesNotExist is true)
302
350
  *
303
351
  */
304
352
 
@@ -308,48 +356,60 @@ var ChannelState = /*#__PURE__*/function () {
308
356
  var timestampChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
309
357
  var initializing = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
310
358
  var addIfDoesNotExist = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
359
+ var messageSetToAddToIfDoesNotExist = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'current';
311
360
 
312
- for (var i = 0; i < newMessages.length; i += 1) {
313
- var _this$_channel;
361
+ var _this$findTargetMessa = this.findTargetMessageSet(newMessages, addIfDoesNotExist, messageSetToAddToIfDoesNotExist),
362
+ messagesToAdd = _this$findTargetMessa.messagesToAdd,
363
+ targetMessageSetIndex = _this$findTargetMessa.targetMessageSetIndex;
314
364
 
315
- var isFromShadowBannedUser = newMessages[i].shadowed;
365
+ for (var i = 0; i < messagesToAdd.length; i += 1) {
366
+ var isFromShadowBannedUser = messagesToAdd[i].shadowed;
316
367
 
317
368
  if (isFromShadowBannedUser) {
318
369
  continue;
319
370
  }
320
371
 
321
- var message = this.formatMessage(newMessages[i]);
372
+ var isMerging = messagesToAdd[i].created_at instanceof Date;
373
+ var message = void 0;
322
374
 
323
- if (message.user && (_this$_channel = this._channel) !== null && _this$_channel !== void 0 && _this$_channel.cid) {
324
- /**
325
- * Store the reference to user for this channel, so that when we have to
326
- * handle updates to user, we can use the reference map, to determine which
327
- * channels need to be updated with updated user object.
328
- */
329
- this._channel.getClient().state.updateUserReference(message.user, this._channel.cid);
330
- }
375
+ if (isMerging) {
376
+ message = messagesToAdd[i];
377
+ } else {
378
+ var _this$_channel;
331
379
 
332
- if (initializing && message.id && this.threads[message.id]) {
333
- // If we are initializing the state of channel (e.g., in case of connection recovery),
334
- // then in that case we remove thread related to this message from threads object.
335
- // This way we can ensure that we don't have any stale data in thread object
336
- // and consumer can refetch the replies.
337
- delete this.threads[message.id];
338
- }
380
+ message = this.formatMessage(messagesToAdd[i]);
339
381
 
340
- if (!this.last_message_at) {
341
- this.last_message_at = new Date(message.created_at.getTime());
342
- }
382
+ if (message.user && (_this$_channel = this._channel) !== null && _this$_channel !== void 0 && _this$_channel.cid) {
383
+ /**
384
+ * Store the reference to user for this channel, so that when we have to
385
+ * handle updates to user, we can use the reference map, to determine which
386
+ * channels need to be updated with updated user object.
387
+ */
388
+ this._channel.getClient().state.updateUserReference(message.user, this._channel.cid);
389
+ }
390
+
391
+ if (initializing && message.id && this.threads[message.id]) {
392
+ // If we are initializing the state of channel (e.g., in case of connection recovery),
393
+ // then in that case we remove thread related to this message from threads object.
394
+ // This way we can ensure that we don't have any stale data in thread object
395
+ // and consumer can refetch the replies.
396
+ delete this.threads[message.id];
397
+ }
343
398
 
344
- if (message.created_at.getTime() > this.last_message_at.getTime()) {
345
- this.last_message_at = new Date(message.created_at.getTime());
399
+ if (!this.last_message_at) {
400
+ this.last_message_at = new Date(message.created_at.getTime());
401
+ }
402
+
403
+ if (message.created_at.getTime() > this.last_message_at.getTime()) {
404
+ this.last_message_at = new Date(message.created_at.getTime());
405
+ }
346
406
  } // update or append the messages...
347
407
 
348
408
 
349
- var parentID = message.parent_id; // add to the main message list
409
+ var parentID = message.parent_id; // add to the given message set
350
410
 
351
- if (!parentID || message.show_in_channel) {
352
- this.messages = this._addToMessageList(this.messages, message, timestampChanged, 'created_at', addIfDoesNotExist);
411
+ if ((!parentID || message.show_in_channel) && targetMessageSetIndex !== -1) {
412
+ this.messageSets[targetMessageSetIndex].messages = this._addToMessageList(this.messageSets[targetMessageSetIndex].messages, message, timestampChanged, 'created_at', addIfDoesNotExist);
353
413
  }
354
414
  /**
355
415
  * Add message to thread if applicable and the message
@@ -362,7 +422,7 @@ var ChannelState = /*#__PURE__*/function () {
362
422
  */
363
423
 
364
424
 
365
- if (parentID && !initializing) {
425
+ if (parentID && !initializing && !isMerging) {
366
426
  var thread = this.threads[parentID] || [];
367
427
 
368
428
  var threadMessages = this._addToMessageList(thread, message, timestampChanged, 'created_at', addIfDoesNotExist);
@@ -473,6 +533,8 @@ var ChannelState = /*#__PURE__*/function () {
473
533
  }, {
474
534
  key: "removeQuotedMessageReferences",
475
535
  value: function removeQuotedMessageReferences(message) {
536
+ var _this4 = this;
537
+
476
538
  var parseMessage = function parseMessage(m) {
477
539
  var _m$pinned_at, _m$updated_at;
478
540
 
@@ -483,16 +545,19 @@ var ChannelState = /*#__PURE__*/function () {
483
545
  });
484
546
  };
485
547
 
486
- var updatedMessages = this.messages.filter(function (msg) {
487
- return msg.quoted_message_id === message.id;
488
- }).map(parseMessage).map(function (msg) {
489
- return _objectSpread$7(_objectSpread$7({}, msg), {}, {
490
- quoted_message: _objectSpread$7(_objectSpread$7({}, message), {}, {
491
- attachments: []
492
- })
548
+ this.messageSets.forEach(function (set) {
549
+ var updatedMessages = set.messages.filter(function (msg) {
550
+ return msg.quoted_message_id === message.id;
551
+ }).map(parseMessage).map(function (msg) {
552
+ return _objectSpread$7(_objectSpread$7({}, msg), {}, {
553
+ quoted_message: _objectSpread$7(_objectSpread$7({}, message), {}, {
554
+ attachments: []
555
+ })
556
+ });
493
557
  });
558
+
559
+ _this4.addMessagesSorted(updatedMessages, true);
494
560
  });
495
- this.addMessagesSorted(updatedMessages, true);
496
561
  }
497
562
  /**
498
563
  * Updates all instances of given message in channel state
@@ -520,12 +585,16 @@ var ChannelState = /*#__PURE__*/function () {
520
585
  }
521
586
 
522
587
  if (!show_in_channel && !parent_id || show_in_channel) {
523
- var _msgIndex = this.messages.findIndex(function (msg) {
524
- return msg.id === message.id;
525
- });
588
+ var messageSetIndex = this.findMessageSetIndex(message);
589
+
590
+ if (messageSetIndex !== -1) {
591
+ var _msgIndex = this.messageSets[messageSetIndex].messages.findIndex(function (msg) {
592
+ return msg.id === message.id;
593
+ });
526
594
 
527
- if (_msgIndex !== -1) {
528
- this.messages[_msgIndex] = updateFunc(this.messages[_msgIndex]);
595
+ if (_msgIndex !== -1) {
596
+ this.messageSets[messageSetIndex].messages[_msgIndex] = updateFunc(this.messageSets[messageSetIndex].messages[_msgIndex]);
597
+ }
529
598
  }
530
599
  }
531
600
 
@@ -644,12 +713,16 @@ var ChannelState = /*#__PURE__*/function () {
644
713
  this.threads[messageToRemove.parent_id] = threadMessages;
645
714
  isRemoved = removed;
646
715
  } else {
647
- var _this$removeMessageFr3 = this.removeMessageFromArray(this.messages, messageToRemove),
648
- _removed = _this$removeMessageFr3.removed,
649
- messages = _this$removeMessageFr3.result;
716
+ var messageSetIndex = this.findMessageSetIndex(messageToRemove);
650
717
 
651
- this.messages = messages;
652
- isRemoved = _removed;
718
+ if (messageSetIndex !== -1) {
719
+ var _this$removeMessageFr3 = this.removeMessageFromArray(this.messageSets[messageSetIndex].messages, messageToRemove),
720
+ _removed = _this$removeMessageFr3.removed,
721
+ messages = _this$removeMessageFr3.result;
722
+
723
+ this.messageSets[messageSetIndex].messages = messages;
724
+ isRemoved = _removed;
725
+ }
653
726
  }
654
727
 
655
728
  return isRemoved;
@@ -662,10 +735,10 @@ var ChannelState = /*#__PURE__*/function () {
662
735
  *
663
736
  */
664
737
  function filterErrorMessages() {
665
- var filteredMessages = this.messages.filter(function (message) {
738
+ var filteredMessages = this.latestMessages.filter(function (message) {
666
739
  return message.type !== 'error';
667
740
  });
668
- this.messages = filteredMessages;
741
+ this.latestMessages = filteredMessages;
669
742
  }
670
743
  /**
671
744
  * clean - Remove stale data such as users that stayed in typing state for more than 5 seconds
@@ -699,9 +772,250 @@ var ChannelState = /*#__PURE__*/function () {
699
772
  }, {
700
773
  key: "clearMessages",
701
774
  value: function clearMessages() {
702
- this.messages = [];
775
+ this.initMessages();
703
776
  this.pinnedMessages = [];
704
777
  }
778
+ }, {
779
+ key: "initMessages",
780
+ value: function initMessages() {
781
+ this.messageSets = [{
782
+ messages: [],
783
+ isLatest: true,
784
+ isCurrent: true
785
+ }];
786
+ }
787
+ /**
788
+ * loadMessageIntoState - Loads a given message (and messages around it) into the state
789
+ *
790
+ * @param {string} messageId The id of the message, or 'latest' to indicate switching to the latest messages
791
+ * @param {string} parentMessageId The id of the parent message, if we want load a thread reply
792
+ */
793
+
794
+ }, {
795
+ key: "loadMessageIntoState",
796
+ value: function () {
797
+ var _loadMessageIntoState = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(messageId, parentMessageId) {
798
+ var _this$threads$parentM;
799
+
800
+ var messageSetIndex, switchedToMessageSet, loadedMessageThread, messageIdToFind;
801
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
802
+ while (1) {
803
+ switch (_context.prev = _context.next) {
804
+ case 0:
805
+ switchedToMessageSet = false;
806
+ loadedMessageThread = false;
807
+ messageIdToFind = parentMessageId || messageId;
808
+
809
+ if (!(messageId === 'latest')) {
810
+ _context.next = 9;
811
+ break;
812
+ }
813
+
814
+ if (!(this.messages === this.latestMessages)) {
815
+ _context.next = 6;
816
+ break;
817
+ }
818
+
819
+ return _context.abrupt("return");
820
+
821
+ case 6:
822
+ messageSetIndex = this.messageSets.findIndex(function (s) {
823
+ return s.isLatest;
824
+ });
825
+ _context.next = 10;
826
+ break;
827
+
828
+ case 9:
829
+ messageSetIndex = this.findMessageSetIndex({
830
+ id: messageIdToFind
831
+ });
832
+
833
+ case 10:
834
+ if (messageSetIndex !== -1) {
835
+ this.switchToMessageSet(messageSetIndex);
836
+ switchedToMessageSet = true;
837
+ }
838
+
839
+ loadedMessageThread = !parentMessageId || !!((_this$threads$parentM = this.threads[parentMessageId]) !== null && _this$threads$parentM !== void 0 && _this$threads$parentM.find(function (m) {
840
+ return m.id === messageId;
841
+ }));
842
+
843
+ if (!(switchedToMessageSet && loadedMessageThread)) {
844
+ _context.next = 14;
845
+ break;
846
+ }
847
+
848
+ return _context.abrupt("return");
849
+
850
+ case 14:
851
+ if (switchedToMessageSet) {
852
+ _context.next = 17;
853
+ break;
854
+ }
855
+
856
+ _context.next = 17;
857
+ return this._channel.query({
858
+ messages: {
859
+ id_around: messageIdToFind,
860
+ limit: 25
861
+ }
862
+ }, 'new');
863
+
864
+ case 17:
865
+ if (!(!loadedMessageThread && parentMessageId)) {
866
+ _context.next = 20;
867
+ break;
868
+ }
869
+
870
+ _context.next = 20;
871
+ return this._channel.getReplies(parentMessageId, {
872
+ id_around: messageId,
873
+ limit: 25
874
+ });
875
+
876
+ case 20:
877
+ messageSetIndex = this.findMessageSetIndex({
878
+ id: messageIdToFind
879
+ });
880
+
881
+ if (messageSetIndex !== -1) {
882
+ this.switchToMessageSet(messageSetIndex);
883
+ }
884
+
885
+ case 22:
886
+ case "end":
887
+ return _context.stop();
888
+ }
889
+ }
890
+ }, _callee, this);
891
+ }));
892
+
893
+ function loadMessageIntoState(_x, _x2) {
894
+ return _loadMessageIntoState.apply(this, arguments);
895
+ }
896
+
897
+ return loadMessageIntoState;
898
+ }()
899
+ }, {
900
+ key: "switchToMessageSet",
901
+ value: function switchToMessageSet(index) {
902
+ var currentMessages = this.messageSets.find(function (s) {
903
+ return s.isCurrent;
904
+ });
905
+
906
+ if (!currentMessages) {
907
+ return;
908
+ }
909
+
910
+ currentMessages.isCurrent = false;
911
+ this.messageSets[index].isCurrent = true;
912
+ }
913
+ }, {
914
+ key: "areMessageSetsOverlap",
915
+ value: function areMessageSetsOverlap(messages1, messages2) {
916
+ return messages1.some(function (m1) {
917
+ return messages2.find(function (m2) {
918
+ return m1.id === m2.id;
919
+ });
920
+ });
921
+ }
922
+ }, {
923
+ key: "findMessageSetIndex",
924
+ value: function findMessageSetIndex(message) {
925
+ return this.messageSets.findIndex(function (set) {
926
+ return !!set.messages.find(function (m) {
927
+ return m.id === message.id;
928
+ });
929
+ });
930
+ }
931
+ }, {
932
+ key: "findTargetMessageSet",
933
+ value: function findTargetMessageSet(newMessages) {
934
+ var _this5 = this;
935
+
936
+ var addIfDoesNotExist = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
937
+ var messageSetToAddToIfDoesNotExist = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'current';
938
+ var messagesToAdd = newMessages;
939
+ var targetMessageSetIndex;
940
+
941
+ if (addIfDoesNotExist) {
942
+ var overlappingMessageSetIndices = this.messageSets.map(function (_, i) {
943
+ return i;
944
+ }).filter(function (i) {
945
+ return _this5.areMessageSetsOverlap(_this5.messageSets[i].messages, newMessages);
946
+ });
947
+
948
+ switch (messageSetToAddToIfDoesNotExist) {
949
+ case 'new':
950
+ if (overlappingMessageSetIndices.length > 0) {
951
+ targetMessageSetIndex = overlappingMessageSetIndices[0]; // No new message set is created if newMessages only contains thread replies
952
+ } else if (newMessages.some(function (m) {
953
+ return !m.parent_id;
954
+ })) {
955
+ this.messageSets.push({
956
+ messages: [],
957
+ isCurrent: false,
958
+ isLatest: false
959
+ });
960
+ targetMessageSetIndex = this.messageSets.length - 1;
961
+ }
962
+
963
+ break;
964
+
965
+ case 'current':
966
+ targetMessageSetIndex = this.messageSets.findIndex(function (s) {
967
+ return s.isCurrent;
968
+ });
969
+ break;
970
+
971
+ case 'latest':
972
+ targetMessageSetIndex = this.messageSets.findIndex(function (s) {
973
+ return s.isLatest;
974
+ });
975
+ break;
976
+
977
+ default:
978
+ targetMessageSetIndex = -1;
979
+ } // when merging the target set will be the first one from the overlapping message sets
980
+
981
+
982
+ var mergeTargetMessageSetIndex = overlappingMessageSetIndices.splice(0, 1)[0];
983
+
984
+ var mergeSourceMessageSetIndices = _toConsumableArray(overlappingMessageSetIndices);
985
+
986
+ if (mergeTargetMessageSetIndex !== undefined && mergeTargetMessageSetIndex !== targetMessageSetIndex) {
987
+ mergeSourceMessageSetIndices.push(targetMessageSetIndex);
988
+ } // merge message sets
989
+
990
+
991
+ if (mergeSourceMessageSetIndices.length > 0) {
992
+ var target = this.messageSets[mergeTargetMessageSetIndex];
993
+ var sources = this.messageSets.filter(function (_, i) {
994
+ return mergeSourceMessageSetIndices.indexOf(i) !== -1;
995
+ });
996
+ sources.forEach(function (messageSet) {
997
+ target.isLatest = target.isLatest || messageSet.isLatest;
998
+ target.isCurrent = target.isCurrent || messageSet.isCurrent;
999
+ messagesToAdd = [].concat(_toConsumableArray(messagesToAdd), _toConsumableArray(messageSet.messages));
1000
+ });
1001
+ sources.forEach(function (s) {
1002
+ return _this5.messageSets.splice(_this5.messageSets.indexOf(s), 1);
1003
+ });
1004
+ var overlappingMessageSetIndex = this.messageSets.findIndex(function (s) {
1005
+ return _this5.areMessageSetsOverlap(s.messages, newMessages);
1006
+ });
1007
+ targetMessageSetIndex = overlappingMessageSetIndex;
1008
+ }
1009
+ } else {
1010
+ // assumes that all new messages belong to the same set
1011
+ targetMessageSetIndex = this.findMessageSetIndex(newMessages[0]);
1012
+ }
1013
+
1014
+ return {
1015
+ targetMessageSetIndex: targetMessageSetIndex,
1016
+ messagesToAdd: messagesToAdd
1017
+ };
1018
+ }
705
1019
  }]);
706
1020
 
707
1021
  return ChannelState;
@@ -1064,7 +1378,7 @@ var Channel = /*#__PURE__*/function () {
1064
1378
  presence: false
1065
1379
  };
1066
1380
  _context.next = 3;
1067
- return _this.query(options);
1381
+ return _this.query(options, 'latest');
1068
1382
 
1069
1383
  case 3:
1070
1384
  return _context.abrupt("return", _context.sent);
@@ -2362,14 +2676,14 @@ var Channel = /*#__PURE__*/function () {
2362
2676
  value: function lastMessage() {
2363
2677
  // get last 5 messages, sort, return the latest
2364
2678
  // get a slice of the last 5
2365
- var min = this.state.messages.length - 5;
2679
+ var min = this.state.latestMessages.length - 5;
2366
2680
 
2367
2681
  if (min < 0) {
2368
2682
  min = 0;
2369
2683
  }
2370
2684
 
2371
- var max = this.state.messages.length + 1;
2372
- var messageSlice = this.state.messages.slice(min, max); // sort by pk desc
2685
+ var max = this.state.latestMessages.length + 1;
2686
+ var messageSlice = this.state.latestMessages.slice(min, max); // sort by pk desc
2373
2687
 
2374
2688
  messageSlice.sort(function (a, b) {
2375
2689
  return b.created_at.getTime() - a.created_at.getTime();
@@ -2478,7 +2792,7 @@ var Channel = /*#__PURE__*/function () {
2478
2792
 
2479
2793
  combined = _objectSpread$5(_objectSpread$5({}, defaultOptions), options);
2480
2794
  _context27.next = 7;
2481
- return this.query(combined);
2795
+ return this.query(combined, 'latest');
2482
2796
 
2483
2797
  case 7:
2484
2798
  state = _context27.sent;
@@ -2552,7 +2866,7 @@ var Channel = /*#__PURE__*/function () {
2552
2866
  * getReplies - List the message replies for a parent message
2553
2867
  *
2554
2868
  * @param {string} parent_id The message parent id, ie the top of the thread
2555
- * @param {PaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}
2869
+ * @param {MessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}
2556
2870
  *
2557
2871
  * @return {Promise<GetRepliesAPIResponse<StreamChatGenerics>>} A response with a list of messages
2558
2872
  */
@@ -2713,8 +3027,8 @@ var Channel = /*#__PURE__*/function () {
2713
3027
  if (!lastRead) return this.state.unreadCount;
2714
3028
  var count = 0;
2715
3029
 
2716
- for (var i = 0; i < this.state.messages.length; i += 1) {
2717
- var message = this.state.messages[i];
3030
+ for (var i = 0; i < this.state.latestMessages.length; i += 1) {
3031
+ var message = this.state.latestMessages[i];
2718
3032
 
2719
3033
  if (message.created_at > lastRead && this._countMessageAsUnread(message)) {
2720
3034
  count++;
@@ -2724,7 +3038,7 @@ var Channel = /*#__PURE__*/function () {
2724
3038
  return count;
2725
3039
  }
2726
3040
  /**
2727
- * countUnread - Count the number of unread messages mentioning the current user
3041
+ * countUnreadMentions - Count the number of unread messages mentioning the current user
2728
3042
  *
2729
3043
  * @return {number} Unread mentions count
2730
3044
  */
@@ -2736,10 +3050,10 @@ var Channel = /*#__PURE__*/function () {
2736
3050
  var userID = this.getClient().userID;
2737
3051
  var count = 0;
2738
3052
 
2739
- for (var i = 0; i < this.state.messages.length; i += 1) {
3053
+ for (var i = 0; i < this.state.latestMessages.length; i += 1) {
2740
3054
  var _message$mentioned_us;
2741
3055
 
2742
- var message = this.state.messages[i];
3056
+ var message = this.state.latestMessages[i];
2743
3057
 
2744
3058
  if (this._countMessageAsUnread(message) && (!lastRead || message.created_at > lastRead) && (_message$mentioned_us = message.mentioned_users) !== null && _message$mentioned_us !== void 0 && _message$mentioned_us.some(function (user) {
2745
3059
  return user.id === userID;
@@ -2763,33 +3077,40 @@ var Channel = /*#__PURE__*/function () {
2763
3077
  * query - Query the API, get messages, members or other channel fields
2764
3078
  *
2765
3079
  * @param {ChannelQueryOptions<StreamChatGenerics>} options The query options
3080
+ * @param {MessageSetType} messageSetToAddToIfDoesNotExist It's possible to load disjunct sets of a channel's messages into state, use `current` to load the initial channel state or if you want to extend the currently displayed messages, use `latest` if you want to load/extend the latest messages, `new` is used for loading a specific message and it's surroundings
2766
3081
  *
2767
3082
  * @return {Promise<ChannelAPIResponse<StreamChatGenerics>>} Returns a query response
2768
3083
  */
2769
3084
  function () {
2770
3085
  var _query = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee31(options) {
2771
- var queryURL, state, membersStr, tempChannelCid;
3086
+ var messageSetToAddToIfDoesNotExist,
3087
+ queryURL,
3088
+ state,
3089
+ membersStr,
3090
+ tempChannelCid,
3091
+ _args31 = arguments;
2772
3092
  return _regeneratorRuntime.wrap(function _callee31$(_context31) {
2773
3093
  while (1) {
2774
3094
  switch (_context31.prev = _context31.next) {
2775
3095
  case 0:
2776
- _context31.next = 2;
3096
+ messageSetToAddToIfDoesNotExist = _args31.length > 1 && _args31[1] !== undefined ? _args31[1] : 'current';
3097
+ _context31.next = 3;
2777
3098
  return this.getClient().wsPromise;
2778
3099
 
2779
- case 2:
3100
+ case 3:
2780
3101
  queryURL = "".concat(this.getClient().baseURL, "/channels/").concat(this.type);
2781
3102
 
2782
3103
  if (this.id) {
2783
3104
  queryURL += "/".concat(this.id);
2784
3105
  }
2785
3106
 
2786
- _context31.next = 6;
3107
+ _context31.next = 7;
2787
3108
  return this.getClient().post(queryURL + '/query', _objectSpread$5({
2788
3109
  data: this._data,
2789
3110
  state: true
2790
3111
  }, options));
2791
3112
 
2792
- case 6:
3113
+ case 7:
2793
3114
  state = _context31.sent;
2794
3115
 
2795
3116
  // update the channel id if it was missing
@@ -2818,11 +3139,11 @@ var Channel = /*#__PURE__*/function () {
2818
3139
  this.getClient()._addChannelConfig(state); // add any messages to our channel state
2819
3140
 
2820
3141
 
2821
- this._initializeState(state);
3142
+ this._initializeState(state, messageSetToAddToIfDoesNotExist);
2822
3143
 
2823
3144
  return _context31.abrupt("return", state);
2824
3145
 
2825
- case 11:
3146
+ case 12:
2826
3147
  case "end":
2827
3148
  return _context31.stop();
2828
3149
  }
@@ -3372,6 +3693,8 @@ var Channel = /*#__PURE__*/function () {
3372
3693
  }, {
3373
3694
  key: "_initializeState",
3374
3695
  value: function _initializeState(state) {
3696
+ var messageSetToAddToIfDoesNotExist = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'latest';
3697
+
3375
3698
  var _this$getClient2 = this.getClient(),
3376
3699
  clientState = _this$getClient2.state,
3377
3700
  user = _this$getClient2.user,
@@ -3401,10 +3724,10 @@ var Channel = /*#__PURE__*/function () {
3401
3724
  var messages = state.messages || [];
3402
3725
 
3403
3726
  if (!this.state.messages) {
3404
- this.state.messages = [];
3727
+ this.state.initMessages();
3405
3728
  }
3406
3729
 
3407
- this.state.addMessagesSorted(messages, false, true);
3730
+ this.state.addMessagesSorted(messages, false, true, true, messageSetToAddToIfDoesNotExist);
3408
3731
 
3409
3732
  if (!this.state.pinnedMessages) {
3410
3733
  this.state.pinnedMessages = [];
@@ -7444,11 +7767,11 @@ var StreamChat = /*#__PURE__*/function () {
7444
7767
  c.initialized = true;
7445
7768
 
7446
7769
  if (skipInitialization === undefined) {
7447
- c._initializeState(_channelState);
7770
+ c._initializeState(_channelState, 'latest');
7448
7771
  } else if (!skipInitialization.includes(_channelState.channel.id)) {
7449
7772
  c.state.clearMessages();
7450
7773
 
7451
- c._initializeState(_channelState);
7774
+ c._initializeState(_channelState, 'latest');
7452
7775
  }
7453
7776
 
7454
7777
  channels.push(c);
@@ -9183,7 +9506,7 @@ var StreamChat = /*#__PURE__*/function () {
9183
9506
  }, {
9184
9507
  key: "getUserAgent",
9185
9508
  value: function getUserAgent() {
9186
- return this.userAgent || "stream-chat-javascript-client-".concat(this.node ? 'node' : 'browser', "-", "6.2.0");
9509
+ return this.userAgent || "stream-chat-javascript-client-".concat(this.node ? 'node' : 'browser', "-", "6.3.0");
9187
9510
  }
9188
9511
  }, {
9189
9512
  key: "setUserAgent",
@@ -10353,6 +10676,122 @@ var StreamChat = /*#__PURE__*/function () {
10353
10676
 
10354
10677
  return _listImports;
10355
10678
  }()
10679
+ /**
10680
+ * upsertPushProvider - Create or Update a push provider
10681
+ *
10682
+ * Note: Works only for v2 push version is enabled on app settings.
10683
+ *
10684
+ * @param {PushProviderConfig} configuration of the provider you want to create or update
10685
+ *
10686
+ * @return {APIResponse & PushProviderUpsertResponse} A push provider
10687
+ */
10688
+
10689
+ }, {
10690
+ key: "upsertPushProvider",
10691
+ value: function () {
10692
+ var _upsertPushProvider = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee75(pushProvider) {
10693
+ return _regeneratorRuntime.wrap(function _callee75$(_context75) {
10694
+ while (1) {
10695
+ switch (_context75.prev = _context75.next) {
10696
+ case 0:
10697
+ _context75.next = 2;
10698
+ return this.post(this.baseURL + "/push_providers", {
10699
+ push_provider: pushProvider
10700
+ });
10701
+
10702
+ case 2:
10703
+ return _context75.abrupt("return", _context75.sent);
10704
+
10705
+ case 3:
10706
+ case "end":
10707
+ return _context75.stop();
10708
+ }
10709
+ }
10710
+ }, _callee75, this);
10711
+ }));
10712
+
10713
+ function upsertPushProvider(_x98) {
10714
+ return _upsertPushProvider.apply(this, arguments);
10715
+ }
10716
+
10717
+ return upsertPushProvider;
10718
+ }()
10719
+ /**
10720
+ * deletePushProvider - Delete a push provider
10721
+ *
10722
+ * Note: Works only for v2 push version is enabled on app settings.
10723
+ *
10724
+ * @param {PushProviderID} type and foreign id of the push provider to be deleted
10725
+ *
10726
+ * @return {APIResponse} An API response
10727
+ */
10728
+
10729
+ }, {
10730
+ key: "deletePushProvider",
10731
+ value: function () {
10732
+ var _deletePushProvider = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee76(_ref8) {
10733
+ var type, name;
10734
+ return _regeneratorRuntime.wrap(function _callee76$(_context76) {
10735
+ while (1) {
10736
+ switch (_context76.prev = _context76.next) {
10737
+ case 0:
10738
+ type = _ref8.type, name = _ref8.name;
10739
+ _context76.next = 3;
10740
+ return this.delete(this.baseURL + "/push_providers/".concat(type, "/").concat(name));
10741
+
10742
+ case 3:
10743
+ return _context76.abrupt("return", _context76.sent);
10744
+
10745
+ case 4:
10746
+ case "end":
10747
+ return _context76.stop();
10748
+ }
10749
+ }
10750
+ }, _callee76, this);
10751
+ }));
10752
+
10753
+ function deletePushProvider(_x99) {
10754
+ return _deletePushProvider.apply(this, arguments);
10755
+ }
10756
+
10757
+ return deletePushProvider;
10758
+ }()
10759
+ /**
10760
+ * listPushProviders - Get all push providers in the app
10761
+ *
10762
+ * Note: Works only for v2 push version is enabled on app settings.
10763
+ *
10764
+ * @return {APIResponse & PushProviderListResponse} A push provider
10765
+ */
10766
+
10767
+ }, {
10768
+ key: "listPushProviders",
10769
+ value: function () {
10770
+ var _listPushProviders = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee77() {
10771
+ return _regeneratorRuntime.wrap(function _callee77$(_context77) {
10772
+ while (1) {
10773
+ switch (_context77.prev = _context77.next) {
10774
+ case 0:
10775
+ _context77.next = 2;
10776
+ return this.get(this.baseURL + "/push_providers");
10777
+
10778
+ case 2:
10779
+ return _context77.abrupt("return", _context77.sent);
10780
+
10781
+ case 3:
10782
+ case "end":
10783
+ return _context77.stop();
10784
+ }
10785
+ }
10786
+ }, _callee77, this);
10787
+ }));
10788
+
10789
+ function listPushProviders() {
10790
+ return _listPushProviders.apply(this, arguments);
10791
+ }
10792
+
10793
+ return listPushProviders;
10794
+ }()
10356
10795
  }], [{
10357
10796
  key: "getInstance",
10358
10797
  value: function getInstance(key, secretOrOptions, options) {