stream-chat-angular 4.67.0 → 4.68.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.
@@ -1 +1 @@
1
- export declare const version = "4.67.0";
1
+ export declare const version = "4.68.1";
@@ -356,7 +356,7 @@
356
356
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
357
357
  }
358
358
 
359
- var version = '4.67.0';
359
+ var version = '4.68.1';
360
360
 
361
361
  /**
362
362
  * The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
@@ -453,6 +453,7 @@
453
453
  this.pendingInvitesSubject = new rxjs.BehaviorSubject([]);
454
454
  this.userSubject = new rxjs.ReplaySubject(1);
455
455
  this.subscriptions = [];
456
+ this.trackPendingChannelInvites = true;
456
457
  this.events$ = this.notificationSubject.asObservable();
457
458
  this.connectionState$ = this.connectionStateSubject.asObservable();
458
459
  this.appSettings$ = this.appSettingsSubject.asObservable();
@@ -472,18 +473,20 @@
472
473
  * @param clientOptions Setting to provide to the Stream client instance
473
474
  */
474
475
  ChatClientService.prototype.init = function (apiKey, userOrId, userTokenOrProvider, clientOptions) {
475
- var _a;
476
+ var _a, _b;
476
477
  return __awaiter(this, void 0, void 0, function () {
477
478
  var result, channels, removeNotification;
478
479
  var _this = this;
479
480
  return __generator(this, function (_d) {
480
481
  switch (_d.label) {
481
482
  case 0:
483
+ this.trackPendingChannelInvites =
484
+ (clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.trackPendingChannelInvites) !== false;
482
485
  this.chatClient = streamChat.StreamChat.getInstance(apiKey, clientOptions);
483
486
  this.chatClient.recoverStateOnReconnect = false;
484
487
  this.chatClient.devToken;
485
488
  return [4 /*yield*/, this.ngZone.runOutsideAngular(function () { return __awaiter(_this, void 0, void 0, function () {
486
- var _b, user, error_1, sdkPrefix;
489
+ var _c, user, error_1, sdkPrefix;
487
490
  var _this = this;
488
491
  return __generator(this, function (_d) {
489
492
  switch (_d.label) {
@@ -492,11 +495,11 @@
492
495
  _d.label = 1;
493
496
  case 1:
494
497
  _d.trys.push([1, 3, , 4]);
495
- return [4 /*yield*/, ((_b = {
498
+ return [4 /*yield*/, ((_c = {
496
499
  guest: function () { return _this.chatClient.setGuestUser(user); },
497
500
  anonymous: function () { return _this.chatClient.connectAnonymousUser(); },
498
501
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
499
- }["" + userTokenOrProvider]) !== null && _b !== void 0 ? _b : (function () { return _this.chatClient.connectUser(user, userTokenOrProvider); }))()];
502
+ }["" + userTokenOrProvider]) !== null && _c !== void 0 ? _c : (function () { return _this.chatClient.connectUser(user, userTokenOrProvider); }))()];
500
503
  case 2:
501
504
  result = _d.sent();
502
505
  return [3 /*break*/, 4];
@@ -516,11 +519,17 @@
516
519
  }); })];
517
520
  case 1:
518
521
  _d.sent();
519
- return [4 /*yield*/, this.chatClient.queryChannels({ invite: 'pending' }, // TODO: find out why we need this typecast
520
- {}, { user_id: (_a = this.chatClient.user) === null || _a === void 0 ? void 0 : _a.id })];
522
+ if (!(((_a = this.chatClient.user) === null || _a === void 0 ? void 0 : _a.id) && this.trackPendingChannelInvites)) return [3 /*break*/, 3];
523
+ return [4 /*yield*/, this.chatClient.queryChannels({
524
+ invite: 'pending',
525
+ members: { $in: [(_b = this.chatClient.user) === null || _b === void 0 ? void 0 : _b.id] },
526
+ } // TODO: find out why we need this typecast
527
+ )];
521
528
  case 2:
522
529
  channels = _d.sent();
523
530
  this.pendingInvitesSubject.next(channels);
531
+ _d.label = 3;
532
+ case 3:
524
533
  this.appSettingsSubject.next(undefined);
525
534
  this.subscriptions.push(this.chatClient.on(function (e) {
526
535
  _this.updateUser(e);
@@ -636,6 +645,9 @@
636
645
  };
637
646
  ChatClientService.prototype.updatePendingInvites = function (e) {
638
647
  var _a, _b, _c;
648
+ if (!this.trackPendingChannelInvites) {
649
+ return;
650
+ }
639
651
  if (((_b = (_a = e.member) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.id) === ((_c = this.chatClient.user) === null || _c === void 0 ? void 0 : _c.id) && e.channel) {
640
652
  var pendingInvites = this.pendingInvitesSubject.getValue();
641
653
  if (e.type === 'notification.invited') {
@@ -838,6 +850,23 @@
838
850
  .asObservable()
839
851
  .pipe(operators.shareReplay(1));
840
852
  }
853
+ /**
854
+ * internal
855
+ */
856
+ ChannelService.prototype.removeOldMessageFromMessageList = function () {
857
+ var channel = this.activeChannelSubject.getValue();
858
+ var channelMessages = channel === null || channel === void 0 ? void 0 : channel.state.latestMessages;
859
+ var targetLength = Math.ceil(ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST / 2);
860
+ if (!channel ||
861
+ !channelMessages ||
862
+ channelMessages !== (channel === null || channel === void 0 ? void 0 : channel.state.latestMessages) ||
863
+ channelMessages.length <= targetLength) {
864
+ return;
865
+ }
866
+ var messages = channelMessages;
867
+ messages.splice(0, messages.length - targetLength);
868
+ this.activeChannelMessagesSubject.next(messages);
869
+ };
841
870
  Object.defineProperty(ChannelService.prototype, "shouldMarkActiveChannelAsRead", {
842
871
  /**
843
872
  * If set to false, read events won't be sent as new messages are received. If set to true active channel (if any) will immediately be marked as read.
@@ -1557,6 +1586,12 @@
1557
1586
  });
1558
1587
  });
1559
1588
  };
1589
+ /**
1590
+ * Clears the currently selected message to jump
1591
+ */
1592
+ ChannelService.prototype.clearMessageJump = function () {
1593
+ this.jumpToMessageSubject.next({ id: undefined, parentId: undefined });
1594
+ };
1560
1595
  /**
1561
1596
  * Pins the given message in the channel
1562
1597
  * @param message
@@ -2458,7 +2493,11 @@
2458
2493
  return ChannelService;
2459
2494
  }());
2460
2495
  /**
2461
- * internal
2496
+ * @internal
2497
+ */
2498
+ ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST = 250;
2499
+ /**
2500
+ * @internal
2462
2501
  */
2463
2502
  ChannelService.MAX_MESSAGE_REACTIONS_TO_FETCH = 1200;
2464
2503
  ChannelService.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: ChannelService, deps: [{ token: ChatClientService }, { token: i0__namespace.NgZone }, { token: NotificationService }], target: i0__namespace.ɵɵFactoryTarget.Injectable });
@@ -7426,6 +7465,10 @@
7426
7465
  * You can turn on and off the loading indicator that signals to users that more messages are being loaded to the message list
7427
7466
  */
7428
7467
  this.displayLoadingIndicator = true;
7468
+ /**
7469
+ * @internal
7470
+ */
7471
+ this.limitNumberOfMessagesInList = true;
7429
7472
  this.emptyMainMessageListTemplate = null;
7430
7473
  this.emptyThreadMessageListTemplate = null;
7431
7474
  this.enabledMessageActions = [];
@@ -7441,6 +7484,8 @@
7441
7484
  this.isLatestMessageInList = true;
7442
7485
  this.parsedDates = new Map();
7443
7486
  this.isViewInited = false;
7487
+ this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
7488
+ this.forceRepaintSubject = new rxjs.Subject();
7444
7489
  this.messageNotificationJumpClicked = function () {
7445
7490
  _this.jumpToFirstUnreadMessage();
7446
7491
  _this.isUnreadNotificationVisible = false;
@@ -7460,6 +7505,9 @@
7460
7505
  });
7461
7506
  MessageListComponent.prototype.ngOnInit = function () {
7462
7507
  var _this = this;
7508
+ this.subscriptions.push(this.forceRepaintSubject.pipe(operators.throttleTime(1000)).subscribe(function () {
7509
+ _this.forceRepaint();
7510
+ }));
7463
7511
  this.subscriptions.push(this.channelService.activeChannel$.subscribe(function (channel) {
7464
7512
  var _a, _b, _c, _d, _e, _f, _g;
7465
7513
  (_b = (_a = _this.chatClientService.chatClient) === null || _a === void 0 ? void 0 : _a.logger) === null || _b === void 0 ? void 0 : _b.call(_a, 'info', ((channel === null || channel === void 0 ? void 0 : channel.cid) || 'undefined') + " selected", { tags: "message list " + _this.mode });
@@ -7472,6 +7520,9 @@
7472
7520
  _this.isUnreadNotificationVisible = false;
7473
7521
  (_e = (_d = (_c = _this.chatClientService) === null || _c === void 0 ? void 0 : _c.chatClient) === null || _d === void 0 ? void 0 : _d.logger) === null || _e === void 0 ? void 0 : _e.call(_d, 'info', "new channel is different from prev channel, reseting scroll state", { tags: "message list " + _this.mode });
7474
7522
  _this.parsedDates = new Map();
7523
+ if (_this.messageRemoveTimeout) {
7524
+ clearTimeout(_this.messageRemoveTimeout);
7525
+ }
7475
7526
  _this.resetScrollState();
7476
7527
  _this.channelId = channel === null || channel === void 0 ? void 0 : channel.id;
7477
7528
  if (_this.isViewInited) {
@@ -7619,6 +7670,9 @@
7619
7670
  .subscribe(function (config) {
7620
7671
  var _a, _b;
7621
7672
  var messageId = undefined;
7673
+ if (_this.messageRemoveTimeout) {
7674
+ clearTimeout(_this.messageRemoveTimeout);
7675
+ }
7622
7676
  if (_this.mode === 'main') {
7623
7677
  messageId = config.parentId || config.id;
7624
7678
  }
@@ -7645,6 +7699,7 @@
7645
7699
  }
7646
7700
  }
7647
7701
  }
7702
+ _this.channelService.clearMessageJump();
7648
7703
  }));
7649
7704
  this.subscriptions.push(this.customTemplatesService.emptyMainMessageListPlaceholder$.subscribe(function (template) {
7650
7705
  var isChanged = _this.emptyMainMessageListTemplate !== template;
@@ -7729,7 +7784,7 @@
7729
7784
  }
7730
7785
  };
7731
7786
  MessageListComponent.prototype.ngOnDestroy = function () {
7732
- var _a;
7787
+ var _a, _b;
7733
7788
  this.subscriptions.forEach(function (s) { return s.unsubscribe(); });
7734
7789
  (_a = this.newMessageSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
7735
7790
  if (this.scrollEndTimeout) {
@@ -7741,6 +7796,10 @@
7741
7796
  if (this.jumpToLatestButtonVisibilityTimeout) {
7742
7797
  clearTimeout(this.jumpToLatestButtonVisibilityTimeout);
7743
7798
  }
7799
+ if (this.messageRemoveTimeout) {
7800
+ clearTimeout(this.messageRemoveTimeout);
7801
+ }
7802
+ (_b = this.removeOldMessagesSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
7744
7803
  };
7745
7804
  MessageListComponent.prototype.trackByMessageId = function (index, item) {
7746
7805
  return item.id;
@@ -7755,7 +7814,9 @@
7755
7814
  MessageListComponent.prototype.scrollToBottom = function () {
7756
7815
  this.scrollContainer.nativeElement.scrollTop =
7757
7816
  this.scrollContainer.nativeElement.scrollHeight + 0.1;
7758
- this.forceRepaint();
7817
+ if (this.isSafari) {
7818
+ this.forceRepaintSubject.next();
7819
+ }
7759
7820
  };
7760
7821
  MessageListComponent.prototype.scrollToTop = function () {
7761
7822
  this.scrollContainer.nativeElement.scrollTop = 0;
@@ -7799,7 +7860,7 @@
7799
7860
  }
7800
7861
  if (this.shouldLoadMoreMessages(scrollPosition)) {
7801
7862
  this.ngZone.run(function () {
7802
- var _a, _b;
7863
+ var _a, _b, _c;
7803
7864
  _this.containerHeight = _this.scrollContainer.nativeElement.scrollHeight;
7804
7865
  var direction;
7805
7866
  if (_this.direction === 'top-to-bottom') {
@@ -7814,6 +7875,9 @@
7814
7875
  if (result) {
7815
7876
  (_b = (_a = _this.chatClientService.chatClient) === null || _a === void 0 ? void 0 : _a.logger) === null || _b === void 0 ? void 0 : _b.call(_a, 'info', "Displaying loading indicator", { tags: "message list " + _this.mode });
7816
7877
  _this.isLoading = true;
7878
+ (_c = result.catch) === null || _c === void 0 ? void 0 : _c.call(result, function () {
7879
+ _this.isLoading = false;
7880
+ });
7817
7881
  }
7818
7882
  _this.cdRef.detectChanges();
7819
7883
  });
@@ -7890,17 +7954,21 @@
7890
7954
  position = 'top';
7891
7955
  }
7892
7956
  else if (Math.ceil(this.scrollContainer.nativeElement.scrollTop) +
7893
- this.scrollContainer.nativeElement.clientHeight >=
7957
+ this.scrollContainer.nativeElement.clientHeight +
7958
+ 1 >=
7894
7959
  this.scrollContainer.nativeElement.scrollHeight) {
7895
7960
  position = 'bottom';
7896
7961
  }
7897
7962
  return position;
7898
7963
  };
7899
7964
  MessageListComponent.prototype.shouldLoadMoreMessages = function (scrollPosition) {
7900
- return scrollPosition !== 'middle' && !this.highlightedMessageId;
7965
+ return (scrollPosition !== 'middle' &&
7966
+ !this.highlightedMessageId &&
7967
+ !this.isLoading);
7901
7968
  };
7902
7969
  MessageListComponent.prototype.setMessages$ = function () {
7903
7970
  var _this = this;
7971
+ var _a;
7904
7972
  this.messages$ = (this.mode === 'main'
7905
7973
  ? this.channelService.activeChannelMessages$
7906
7974
  : this.channelService.activeThreadMessages$).pipe(operators.tap(function (messages) {
@@ -7963,7 +8031,41 @@
7963
8031
  lastReadMessageId: _this.lastReadMessageId,
7964
8032
  }); });
7965
8033
  _this.isNextMessageOnSeparateDate = messages.map(function (m, i) { return _this.checkIfOnSeparateDates(m, messages[i + 1]); });
7966
- }));
8034
+ }), operators.shareReplay(1));
8035
+ (_a = this.removeOldMessagesSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
8036
+ this.removeOldMessagesSubscription = rxjs.combineLatest([
8037
+ this.channelService.jumpToMessage$,
8038
+ this.messages$,
8039
+ ]).subscribe(function (_k) {
8040
+ var _l = __read(_k, 2), jumpToMessage = _l[0], messages = _l[1];
8041
+ if (_this.limitNumberOfMessagesInList &&
8042
+ _this.mode === 'main' &&
8043
+ messages.length >
8044
+ ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST * 0.5 &&
8045
+ !_this.isUserScrolled &&
8046
+ !(jumpToMessage === null || jumpToMessage === void 0 ? void 0 : jumpToMessage.id) &&
8047
+ _this.isLatestMessageInList) {
8048
+ if (_this.messageRemoveTimeout) {
8049
+ clearTimeout(_this.messageRemoveTimeout);
8050
+ }
8051
+ if (messages.length >= ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST) {
8052
+ _this.channelService.removeOldMessageFromMessageList();
8053
+ }
8054
+ else {
8055
+ _this.messageRemoveTimeout = setTimeout(function () {
8056
+ if (_this.limitNumberOfMessagesInList &&
8057
+ _this.mode === 'main' &&
8058
+ messages.length >
8059
+ ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST * 0.5 &&
8060
+ !_this.isUserScrolled &&
8061
+ !_this.highlightedMessageId &&
8062
+ _this.isLatestMessageInList) {
8063
+ _this.channelService.removeOldMessageFromMessageList();
8064
+ }
8065
+ }, 1500);
8066
+ }
8067
+ }
8068
+ });
7967
8069
  };
7968
8070
  MessageListComponent.prototype.resetScrollState = function () {
7969
8071
  this.isEmpty = true;
@@ -8055,7 +8157,7 @@
8055
8157
  return MessageListComponent;
8056
8158
  }());
8057
8159
  MessageListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageListComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: CustomTemplatesService }, { token: DateParserService }, { token: i0__namespace.NgZone }, { token: i0__namespace.ChangeDetectorRef }, { token: MessageActionsService }], target: i0__namespace.ɵɵFactoryTarget.Component });
8058
- MessageListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageListComponent, selector: "stream-message-list", inputs: { mode: "mode", direction: "direction", messageOptionsTrigger: "messageOptionsTrigger", hideJumpToLatestButtonDuringScroll: "hideJumpToLatestButtonDuringScroll", customMessageActions: "customMessageActions", displayDateSeparator: "displayDateSeparator", displayUnreadSeparator: "displayUnreadSeparator", dateSeparatorTextPos: "dateSeparatorTextPos", openMessageListAt: "openMessageListAt", hideUnreadCountForNotificationAndIndicator: "hideUnreadCountForNotificationAndIndicator", displayLoadingIndicator: "displayLoadingIndicator" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "parentMessageElement", first: true, predicate: ["parentMessageElement"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<ng-container\n *ngIf=\"\n lastReadMessageId &&\n isUnreadNotificationVisible &&\n openMessageListAt === 'last-message' &&\n displayUnreadSeparator\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesNotificationTemplate ||\n defaultUnreadMessagesNotification;\n context: {\n unreadCount: unreadCount,\n onDismiss: messageNotificationDismissClicked,\n onJump: messageNotificationJumpClicked\n }\n \"\n ></ng-container>\n</ng-container>\n<ng-template\n #defaultUnreadMessagesNotification\n let-unreadCount=\"unreadCount\"\n let-onDismiss=\"onDismiss\"\n let-onJump=\"onJump\"\n>\n <div\n class=\"str-chat__unread-messages-notification\"\n data-testid=\"unread-messages-notification\"\n >\n <button\n data-testid=\"unread-messages-notification-jump-to-message\"\n (click)=\"onJump()\"\n >\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate: { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </button>\n <button\n data-testid=\"unread-messages-notification-dismiss\"\n (click)=\"onDismiss()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n<div #scrollContainer data-testid=\"scroll-container\" class=\"str-chat__list\">\n <ng-container *ngIf=\"mode === 'main' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <div class=\"str-chat__reverse-infinite-scroll str-chat__message-list-scroll\">\n <ul\n class=\"str-chat__ul\"\n [class.str-chat__message-options-in-bubble]=\"\n messageOptionsTrigger === 'message-bubble'\n \"\n >\n <li\n #parentMessageElement\n *ngIf=\"mode === 'thread' && parentMessage\"\n data-testid=\"parent-message\"\n class=\"str-chat__parent-message-li\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage, index: 'parent' }\n \"\n ></ng-container>\n <div data-testid=\"reply-count\" class=\"str-chat__thread-start\">\n {{parentMessage?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </div>\n </li>\n <ng-container *ngIf=\"mode === 'thread' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <stream-loading-indicator\n data-testid=\"top-loading-indicator\"\n *ngIf=\"\n isLoading && direction === 'bottom-to-top' && displayLoadingIndicator\n \"\n ></stream-loading-indicator>\n <ng-container *ngIf=\"messages$ | async as messages\">\n <ng-container\n *ngFor=\"\n let message of messages;\n let i = index;\n let isFirst = first;\n let isLast = last;\n trackBy: trackByMessageId\n \"\n >\n <ng-container *ngIf=\"isFirst\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: message.created_at,\n parsedDate: parseDate(message.created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n <li\n tabindex=\"0\"\n data-testclass=\"message\"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n id=\"{{ message.id }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message, index: i }\n \"\n ></ng-container>\n </li>\n <ng-container\n *ngIf=\"\n (lastReadMessageId === message?.id &&\n direction === 'bottom-to-top') ||\n (direction === 'top-to-bottom' &&\n lastReadMessageId === messages[i + 1]?.id)\n \"\n >\n <li\n *ngIf=\"displayUnreadSeparator\"\n id=\"stream-chat-new-message-indicator\"\n data-testid=\"new-messages-indicator\"\n class=\"str-chat__li str-chat__unread-messages-separator-wrapper\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesIndicatorTemplate ||\n defaultNewMessagesIndicator;\n context: { unreadCount: unreadCount }\n \"\n ></ng-container>\n </li>\n </ng-container>\n <ng-container *ngIf=\"isNextMessageOnSeparateDate[i]\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: messages[i + 1].created_at,\n parsedDate: parseDate(messages[i + 1].created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n <stream-loading-indicator\n data-testid=\"bottom-loading-indicator\"\n *ngIf=\"\n isLoading && direction === 'top-to-bottom' && displayLoadingIndicator\n \"\n ></stream-loading-indicator>\n </ul>\n <ng-template #defaultTypingIndicator let-usersTyping$=\"usersTyping$\">\n <!-- eslint-disable-next-line @angular-eslint/template/no-any -->\n <ng-container *ngIf=\"$any(usersTyping$ | async) as users\">\n <div\n *ngIf=\"users.length > 0\"\n data-testid=\"typing-indicator\"\n class=\"str-chat__typing-indicator str-chat__typing-indicator--typing\"\n >\n <div class=\"str-chat__typing-indicator__dots\">\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n </div>\n <div\n data-testid=\"typing-users\"\n class=\"str-chat__typing-indicator__users\"\n >\n {{\n users.length === 1\n ? (\"streamChat.user is typing\"\n | translate: { user: getTypingIndicatorText(users) })\n : (\"streamChat.users are typing\"\n | translate: { users: getTypingIndicatorText(users) })\n }}\n </div>\n </div>\n </ng-container>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n typingIndicatorTemplate || defaultTypingIndicator;\n context: getTypingIndicatorContext()\n \"\n ></ng-container>\n </div>\n</div>\n<div class=\"str-chat__jump-to-latest-message\">\n <button\n data-testid=\"scroll-to-latest\"\n *ngIf=\"isUserScrolled && isJumpToLatestButtonVisible\"\n class=\"\n str-chat__message-notification-scroll-to-latest\n str-chat__message-notification-scroll-to-latest-right\n str-chat__circle-fab\n \"\n (keyup.enter)=\"jumpToLatestMessage()\"\n (click)=\"jumpToLatestMessage()\"\n >\n <stream-icon\n class=\"str-chat__jump-to-latest-icon str-chat__circle-fab-icon\"\n [icon]=\"direction === 'bottom-to-top' ? 'arrow-down' : 'arrow-up'\"\n ></stream-icon>\n <div\n *ngIf=\"newMessageCountWhileBeingScrolled > 0\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-scroll-to-latest-unread-count\n str-chat__jump-to-latest-unread-count\n \"\n >\n {{ newMessageCountWhileBeingScrolled }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\" let-index=\"index\">\n <ng-template\n #defaultMessageTemplate\n let-messageInput=\"message\"\n let-isLastSentMessage=\"isLastSentMessage\"\n let-enabledMessageActions=\"enabledMessageActions\"\n let-mode=\"mode\"\n let-isHighlighted=\"isHighlighted\"\n let-customActions=\"customActions\"\n >\n <stream-message\n [message]=\"messageInput\"\n [isLastSentMessage]=\"isLastSentMessage\"\n [enabledMessageActions]=\"enabledMessageActions\"\n [mode]=\"mode\"\n [isHighlighted]=\"isHighlighted\"\n [customActions]=\"customActions\"\n ></stream-message>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate || defaultMessageTemplate;\n context: {\n message: message,\n isLastSentMessage: !!(\n lastSentMessageId && message?.id === lastSentMessageId\n ),\n enabledMessageActions: enabledMessageActions,\n mode: mode,\n isHighlighted: message?.id === highlightedMessageId,\n customActions: customMessageActions\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template #dateSeparator let-date=\"date\" let-parsedDate=\"parsedDate\">\n <ng-container *ngIf=\"displayDateSeparator\">\n <ng-container\n *ngTemplateOutlet=\"\n customDateSeparatorTemplate || defaultDateSeparator;\n context: {\n date: date,\n parsedDate: parsedDate\n }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template\n #defaultDateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n >\n <div data-testid=\"date-separator\" class=\"str-chat__date-separator\">\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'right' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n <div class=\"str-chat__date-separator-date\">\n {{ parsedDate }}\n </div>\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'left' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #defaultNewMessagesIndicator let-unreadCount=\"unreadCount\">\n <div class=\"str-chat__unread-messages-separator\">\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate: { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </div>\n</ng-template>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: MessageComponent, selector: "stream-message", inputs: ["message", "enabledMessageActions", "isLastSentMessage", "mode", "isHighlighted", "customActions"] }], directives: [{ type: i8__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i8__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "translate": i9__namespace.TranslatePipe, "async": i8__namespace.AsyncPipe }, changeDetection: i0__namespace.ChangeDetectionStrategy.OnPush });
8160
+ MessageListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: MessageListComponent, selector: "stream-message-list", inputs: { mode: "mode", direction: "direction", messageOptionsTrigger: "messageOptionsTrigger", hideJumpToLatestButtonDuringScroll: "hideJumpToLatestButtonDuringScroll", customMessageActions: "customMessageActions", displayDateSeparator: "displayDateSeparator", displayUnreadSeparator: "displayUnreadSeparator", dateSeparatorTextPos: "dateSeparatorTextPos", openMessageListAt: "openMessageListAt", hideUnreadCountForNotificationAndIndicator: "hideUnreadCountForNotificationAndIndicator", displayLoadingIndicator: "displayLoadingIndicator", limitNumberOfMessagesInList: "limitNumberOfMessagesInList" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "parentMessageElement", first: true, predicate: ["parentMessageElement"], descendants: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<ng-container\n *ngIf=\"\n lastReadMessageId &&\n isUnreadNotificationVisible &&\n openMessageListAt === 'last-message' &&\n displayUnreadSeparator\n \"\n>\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesNotificationTemplate ||\n defaultUnreadMessagesNotification;\n context: {\n unreadCount: unreadCount,\n onDismiss: messageNotificationDismissClicked,\n onJump: messageNotificationJumpClicked\n }\n \"\n ></ng-container>\n</ng-container>\n<ng-template\n #defaultUnreadMessagesNotification\n let-unreadCount=\"unreadCount\"\n let-onDismiss=\"onDismiss\"\n let-onJump=\"onJump\"\n>\n <div\n class=\"str-chat__unread-messages-notification\"\n data-testid=\"unread-messages-notification\"\n >\n <button\n data-testid=\"unread-messages-notification-jump-to-message\"\n (click)=\"onJump()\"\n >\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate: { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </button>\n <button\n data-testid=\"unread-messages-notification-dismiss\"\n (click)=\"onDismiss()\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n<div #scrollContainer data-testid=\"scroll-container\" class=\"str-chat__list\">\n <ng-container *ngIf=\"mode === 'main' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <div class=\"str-chat__reverse-infinite-scroll str-chat__message-list-scroll\">\n <ul\n class=\"str-chat__ul\"\n [class.str-chat__message-options-in-bubble]=\"\n messageOptionsTrigger === 'message-bubble'\n \"\n >\n <li\n #parentMessageElement\n *ngIf=\"mode === 'thread' && parentMessage\"\n data-testid=\"parent-message\"\n class=\"str-chat__parent-message-li\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: parentMessage, index: 'parent' }\n \"\n ></ng-container>\n <div data-testid=\"reply-count\" class=\"str-chat__thread-start\">\n {{parentMessage?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </div>\n </li>\n <ng-container *ngIf=\"mode === 'thread' && isEmpty && emptyListTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyListTemplate\"></ng-container>\n </ng-container>\n <stream-loading-indicator\n data-testid=\"top-loading-indicator\"\n *ngIf=\"\n isLoading && direction === 'bottom-to-top' && displayLoadingIndicator\n \"\n ></stream-loading-indicator>\n <ng-container *ngIf=\"messages$ | async as messages\">\n <ng-container\n *ngFor=\"\n let message of messages;\n let i = index;\n let isFirst = first;\n let isLast = last;\n trackBy: trackByMessageId\n \"\n >\n <ng-container *ngIf=\"isFirst\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: message.created_at,\n parsedDate: parseDate(message.created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n <li\n tabindex=\"0\"\n data-testclass=\"message\"\n class=\"str-chat__li str-chat__li--{{ groupStyles[i] }}\"\n id=\"{{ message.id }}\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplateContainer;\n context: { message: message, index: i }\n \"\n ></ng-container>\n </li>\n <ng-container\n *ngIf=\"\n (lastReadMessageId === message?.id &&\n direction === 'bottom-to-top') ||\n (direction === 'top-to-bottom' &&\n lastReadMessageId === messages[i + 1]?.id)\n \"\n >\n <li\n *ngIf=\"displayUnreadSeparator\"\n id=\"stream-chat-new-message-indicator\"\n data-testid=\"new-messages-indicator\"\n class=\"str-chat__li str-chat__unread-messages-separator-wrapper\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesIndicatorTemplate ||\n defaultNewMessagesIndicator;\n context: { unreadCount: unreadCount }\n \"\n ></ng-container>\n </li>\n </ng-container>\n <ng-container *ngIf=\"isNextMessageOnSeparateDate[i]\">\n <ng-container\n *ngTemplateOutlet=\"\n dateSeparator;\n context: {\n date: messages[i + 1].created_at,\n parsedDate: parseDate(messages[i + 1].created_at)\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n <stream-loading-indicator\n data-testid=\"bottom-loading-indicator\"\n *ngIf=\"\n isLoading && direction === 'top-to-bottom' && displayLoadingIndicator\n \"\n ></stream-loading-indicator>\n </ul>\n <ng-template #defaultTypingIndicator let-usersTyping$=\"usersTyping$\">\n <!-- eslint-disable-next-line @angular-eslint/template/no-any -->\n <ng-container *ngIf=\"$any(usersTyping$ | async) as users\">\n <div\n *ngIf=\"users.length > 0\"\n data-testid=\"typing-indicator\"\n class=\"str-chat__typing-indicator str-chat__typing-indicator--typing\"\n >\n <div class=\"str-chat__typing-indicator__dots\">\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n <span class=\"str-chat__typing-indicator__dot\"></span>\n </div>\n <div\n data-testid=\"typing-users\"\n class=\"str-chat__typing-indicator__users\"\n >\n {{\n users.length === 1\n ? (\"streamChat.user is typing\"\n | translate: { user: getTypingIndicatorText(users) })\n : (\"streamChat.users are typing\"\n | translate: { users: getTypingIndicatorText(users) })\n }}\n </div>\n </div>\n </ng-container>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n typingIndicatorTemplate || defaultTypingIndicator;\n context: getTypingIndicatorContext()\n \"\n ></ng-container>\n </div>\n</div>\n<div class=\"str-chat__jump-to-latest-message\">\n <button\n data-testid=\"scroll-to-latest\"\n *ngIf=\"isUserScrolled && isJumpToLatestButtonVisible\"\n class=\"\n str-chat__message-notification-scroll-to-latest\n str-chat__message-notification-scroll-to-latest-right\n str-chat__circle-fab\n \"\n (keyup.enter)=\"jumpToLatestMessage()\"\n (click)=\"jumpToLatestMessage()\"\n >\n <stream-icon\n class=\"str-chat__jump-to-latest-icon str-chat__circle-fab-icon\"\n [icon]=\"direction === 'bottom-to-top' ? 'arrow-down' : 'arrow-up'\"\n ></stream-icon>\n <div\n *ngIf=\"newMessageCountWhileBeingScrolled > 0\"\n class=\"\n str-chat__message-notification\n str-chat__message-notification-scroll-to-latest-unread-count\n str-chat__jump-to-latest-unread-count\n \"\n >\n {{ newMessageCountWhileBeingScrolled }}\n </div>\n </button>\n</div>\n\n<ng-template #messageTemplateContainer let-message=\"message\" let-index=\"index\">\n <ng-template\n #defaultMessageTemplate\n let-messageInput=\"message\"\n let-isLastSentMessage=\"isLastSentMessage\"\n let-enabledMessageActions=\"enabledMessageActions\"\n let-mode=\"mode\"\n let-isHighlighted=\"isHighlighted\"\n let-customActions=\"customActions\"\n >\n <stream-message\n [message]=\"messageInput\"\n [isLastSentMessage]=\"isLastSentMessage\"\n [enabledMessageActions]=\"enabledMessageActions\"\n [mode]=\"mode\"\n [isHighlighted]=\"isHighlighted\"\n [customActions]=\"customActions\"\n ></stream-message>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n messageTemplate || defaultMessageTemplate;\n context: {\n message: message,\n isLastSentMessage: !!(\n lastSentMessageId && message?.id === lastSentMessageId\n ),\n enabledMessageActions: enabledMessageActions,\n mode: mode,\n isHighlighted: message?.id === highlightedMessageId,\n customActions: customMessageActions\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template #dateSeparator let-date=\"date\" let-parsedDate=\"parsedDate\">\n <ng-container *ngIf=\"displayDateSeparator\">\n <ng-container\n *ngTemplateOutlet=\"\n customDateSeparatorTemplate || defaultDateSeparator;\n context: {\n date: date,\n parsedDate: parsedDate\n }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template\n #defaultDateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n >\n <div data-testid=\"date-separator\" class=\"str-chat__date-separator\">\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'right' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n <div class=\"str-chat__date-separator-date\">\n {{ parsedDate }}\n </div>\n <hr\n *ngIf=\"\n dateSeparatorTextPos === 'left' || dateSeparatorTextPos === 'center'\n \"\n class=\"str-chat__date-separator-line\"\n />\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #defaultNewMessagesIndicator let-unreadCount=\"unreadCount\">\n <div class=\"str-chat__unread-messages-separator\">\n <ng-container\n *ngIf=\"\n unreadCount > 0 && !hideUnreadCountForNotificationAndIndicator;\n else noUnreadCount\n \"\n >\n {{\n (unreadCount === 1\n ? \"streamChat.\\{\\{count\\}\\} unread message\"\n : \"streamChat.\\{\\{count\\}\\} unread messages\"\n ) | translate: { count: unreadCount }\n }}\n </ng-container>\n <ng-template #noUnreadCount>\n {{ \"streamChat.Unread messages\" | translate }}\n </ng-template>\n </div>\n</ng-template>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: LoadingIndicatorComponent, selector: "stream-loading-indicator", inputs: ["size", "color"] }, { type: IconComponent, selector: "stream-icon", inputs: ["icon", "size"] }, { type: MessageComponent, selector: "stream-message", inputs: ["message", "enabledMessageActions", "isLastSentMessage", "mode", "isHighlighted", "customActions"] }], directives: [{ type: i8__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i8__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "translate": i9__namespace.TranslatePipe, "async": i8__namespace.AsyncPipe }, changeDetection: i0__namespace.ChangeDetectionStrategy.OnPush });
8059
8161
  i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: MessageListComponent, decorators: [{
8060
8162
  type: i0.Component,
8061
8163
  args: [{
@@ -8086,6 +8188,8 @@
8086
8188
  type: i0.Input
8087
8189
  }], displayLoadingIndicator: [{
8088
8190
  type: i0.Input
8191
+ }], limitNumberOfMessagesInList: [{
8192
+ type: i0.Input
8089
8193
  }], scrollContainer: [{
8090
8194
  type: i0.ViewChild,
8091
8195
  args: ['scrollContainer']