stream-chat-angular 4.67.0 → 4.68.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/assets/version.d.ts +1 -1
- package/bundles/stream-chat-angular.umd.js +101 -9
- package/bundles/stream-chat-angular.umd.js.map +1 -1
- package/esm2015/assets/version.js +2 -2
- package/esm2015/lib/channel.service.js +29 -2
- package/esm2015/lib/message-list/message-list.component.js +75 -9
- package/fesm2015/stream-chat-angular.js +101 -10
- package/fesm2015/stream-chat-angular.js.map +1 -1
- package/lib/channel.service.d.ts +13 -1
- package/lib/message-list/message-list.component.d.ts +9 -1
- package/package.json +1 -1
- package/src/assets/version.ts +1 -1
|
@@ -3,7 +3,7 @@ import * as i0 from '@angular/core';
|
|
|
3
3
|
import { Injectable, Component, Input, EventEmitter, Output, ViewChild, InjectionToken, Directive, HostBinding, Inject, ChangeDetectionStrategy, NgModule } from '@angular/core';
|
|
4
4
|
import { BehaviorSubject, ReplaySubject, combineLatest, Subject, timer } from 'rxjs';
|
|
5
5
|
import { StreamChat } from 'stream-chat';
|
|
6
|
-
import { take, shareReplay, map, first, filter, tap, distinctUntilChanged, debounceTime } from 'rxjs/operators';
|
|
6
|
+
import { take, shareReplay, map, first, filter, tap, distinctUntilChanged, debounceTime, throttleTime } from 'rxjs/operators';
|
|
7
7
|
import { v4 } from 'uuid';
|
|
8
8
|
import * as i9 from '@ngx-translate/core';
|
|
9
9
|
import { TranslateModule } from '@ngx-translate/core';
|
|
@@ -20,7 +20,7 @@ import transliterate from '@stream-io/transliterate';
|
|
|
20
20
|
import * as i8$1 from 'angular-mentions';
|
|
21
21
|
import { MentionModule } from 'angular-mentions';
|
|
22
22
|
|
|
23
|
-
const version = '4.
|
|
23
|
+
const version = '4.68.0';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
|
|
@@ -436,6 +436,23 @@ class ChannelService {
|
|
|
436
436
|
.asObservable()
|
|
437
437
|
.pipe(shareReplay(1));
|
|
438
438
|
}
|
|
439
|
+
/**
|
|
440
|
+
* internal
|
|
441
|
+
*/
|
|
442
|
+
removeOldMessageFromMessageList() {
|
|
443
|
+
const channel = this.activeChannelSubject.getValue();
|
|
444
|
+
const channelMessages = channel === null || channel === void 0 ? void 0 : channel.state.latestMessages;
|
|
445
|
+
const targetLength = Math.ceil(ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST / 2);
|
|
446
|
+
if (!channel ||
|
|
447
|
+
!channelMessages ||
|
|
448
|
+
channelMessages !== (channel === null || channel === void 0 ? void 0 : channel.state.latestMessages) ||
|
|
449
|
+
channelMessages.length <= targetLength) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const messages = channelMessages;
|
|
453
|
+
messages.splice(0, messages.length - targetLength);
|
|
454
|
+
this.activeChannelMessagesSubject.next(messages);
|
|
455
|
+
}
|
|
439
456
|
/**
|
|
440
457
|
* 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.
|
|
441
458
|
*/
|
|
@@ -1005,6 +1022,12 @@ class ChannelService {
|
|
|
1005
1022
|
}
|
|
1006
1023
|
});
|
|
1007
1024
|
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Clears the currently selected message to jump
|
|
1027
|
+
*/
|
|
1028
|
+
clearMessageJump() {
|
|
1029
|
+
this.jumpToMessageSubject.next({ id: undefined, parentId: undefined });
|
|
1030
|
+
}
|
|
1008
1031
|
/**
|
|
1009
1032
|
* Pins the given message in the channel
|
|
1010
1033
|
* @param message
|
|
@@ -1798,7 +1821,11 @@ class ChannelService {
|
|
|
1798
1821
|
}
|
|
1799
1822
|
}
|
|
1800
1823
|
/**
|
|
1801
|
-
* internal
|
|
1824
|
+
* @internal
|
|
1825
|
+
*/
|
|
1826
|
+
ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST = 250;
|
|
1827
|
+
/**
|
|
1828
|
+
* @internal
|
|
1802
1829
|
*/
|
|
1803
1830
|
ChannelService.MAX_MESSAGE_REACTIONS_TO_FETCH = 1200;
|
|
1804
1831
|
ChannelService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: ChannelService, deps: [{ token: ChatClientService }, { token: i0.NgZone }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -6432,6 +6459,10 @@ class MessageListComponent {
|
|
|
6432
6459
|
* You can turn on and off the loading indicator that signals to users that more messages are being loaded to the message list
|
|
6433
6460
|
*/
|
|
6434
6461
|
this.displayLoadingIndicator = true;
|
|
6462
|
+
/**
|
|
6463
|
+
* @internal
|
|
6464
|
+
*/
|
|
6465
|
+
this.limitNumberOfMessagesInList = true;
|
|
6435
6466
|
this.emptyMainMessageListTemplate = null;
|
|
6436
6467
|
this.emptyThreadMessageListTemplate = null;
|
|
6437
6468
|
this.enabledMessageActions = [];
|
|
@@ -6447,6 +6478,8 @@ class MessageListComponent {
|
|
|
6447
6478
|
this.isLatestMessageInList = true;
|
|
6448
6479
|
this.parsedDates = new Map();
|
|
6449
6480
|
this.isViewInited = false;
|
|
6481
|
+
this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
6482
|
+
this.forceRepaintSubject = new Subject();
|
|
6450
6483
|
this.messageNotificationJumpClicked = () => {
|
|
6451
6484
|
this.jumpToFirstUnreadMessage();
|
|
6452
6485
|
this.isUnreadNotificationVisible = false;
|
|
@@ -6461,6 +6494,9 @@ class MessageListComponent {
|
|
|
6461
6494
|
return `str-chat-angular__main-panel-inner str-chat-angular__message-list-host str-chat__main-panel-inner ${this.isEmpty ? 'str-chat-angular__message-list-host--empty' : ''}`;
|
|
6462
6495
|
}
|
|
6463
6496
|
ngOnInit() {
|
|
6497
|
+
this.subscriptions.push(this.forceRepaintSubject.pipe(throttleTime(1000)).subscribe(() => {
|
|
6498
|
+
this.forceRepaint();
|
|
6499
|
+
}));
|
|
6464
6500
|
this.subscriptions.push(this.channelService.activeChannel$.subscribe((channel) => {
|
|
6465
6501
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
6466
6502
|
(_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}` });
|
|
@@ -6473,6 +6509,9 @@ class MessageListComponent {
|
|
|
6473
6509
|
this.isUnreadNotificationVisible = false;
|
|
6474
6510
|
(_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}` });
|
|
6475
6511
|
this.parsedDates = new Map();
|
|
6512
|
+
if (this.messageRemoveTimeout) {
|
|
6513
|
+
clearTimeout(this.messageRemoveTimeout);
|
|
6514
|
+
}
|
|
6476
6515
|
this.resetScrollState();
|
|
6477
6516
|
this.channelId = channel === null || channel === void 0 ? void 0 : channel.id;
|
|
6478
6517
|
if (this.isViewInited) {
|
|
@@ -6621,6 +6660,9 @@ class MessageListComponent {
|
|
|
6621
6660
|
.subscribe((config) => {
|
|
6622
6661
|
var _a, _b;
|
|
6623
6662
|
let messageId = undefined;
|
|
6663
|
+
if (this.messageRemoveTimeout) {
|
|
6664
|
+
clearTimeout(this.messageRemoveTimeout);
|
|
6665
|
+
}
|
|
6624
6666
|
if (this.mode === 'main') {
|
|
6625
6667
|
messageId = config.parentId || config.id;
|
|
6626
6668
|
}
|
|
@@ -6647,6 +6689,7 @@ class MessageListComponent {
|
|
|
6647
6689
|
}
|
|
6648
6690
|
}
|
|
6649
6691
|
}
|
|
6692
|
+
this.channelService.clearMessageJump();
|
|
6650
6693
|
}));
|
|
6651
6694
|
this.subscriptions.push(this.customTemplatesService.emptyMainMessageListPlaceholder$.subscribe((template) => {
|
|
6652
6695
|
const isChanged = this.emptyMainMessageListTemplate !== template;
|
|
@@ -6730,7 +6773,7 @@ class MessageListComponent {
|
|
|
6730
6773
|
}
|
|
6731
6774
|
}
|
|
6732
6775
|
ngOnDestroy() {
|
|
6733
|
-
var _a;
|
|
6776
|
+
var _a, _b;
|
|
6734
6777
|
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
6735
6778
|
(_a = this.newMessageSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
6736
6779
|
if (this.scrollEndTimeout) {
|
|
@@ -6742,6 +6785,10 @@ class MessageListComponent {
|
|
|
6742
6785
|
if (this.jumpToLatestButtonVisibilityTimeout) {
|
|
6743
6786
|
clearTimeout(this.jumpToLatestButtonVisibilityTimeout);
|
|
6744
6787
|
}
|
|
6788
|
+
if (this.messageRemoveTimeout) {
|
|
6789
|
+
clearTimeout(this.messageRemoveTimeout);
|
|
6790
|
+
}
|
|
6791
|
+
(_b = this.removeOldMessagesSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
|
|
6745
6792
|
}
|
|
6746
6793
|
trackByMessageId(index, item) {
|
|
6747
6794
|
return item.id;
|
|
@@ -6756,7 +6803,9 @@ class MessageListComponent {
|
|
|
6756
6803
|
scrollToBottom() {
|
|
6757
6804
|
this.scrollContainer.nativeElement.scrollTop =
|
|
6758
6805
|
this.scrollContainer.nativeElement.scrollHeight + 0.1;
|
|
6759
|
-
this.
|
|
6806
|
+
if (this.isSafari) {
|
|
6807
|
+
this.forceRepaintSubject.next();
|
|
6808
|
+
}
|
|
6760
6809
|
}
|
|
6761
6810
|
scrollToTop() {
|
|
6762
6811
|
this.scrollContainer.nativeElement.scrollTop = 0;
|
|
@@ -6799,7 +6848,7 @@ class MessageListComponent {
|
|
|
6799
6848
|
}
|
|
6800
6849
|
if (this.shouldLoadMoreMessages(scrollPosition)) {
|
|
6801
6850
|
this.ngZone.run(() => {
|
|
6802
|
-
var _a, _b;
|
|
6851
|
+
var _a, _b, _c;
|
|
6803
6852
|
this.containerHeight = this.scrollContainer.nativeElement.scrollHeight;
|
|
6804
6853
|
let direction;
|
|
6805
6854
|
if (this.direction === 'top-to-bottom') {
|
|
@@ -6814,6 +6863,9 @@ class MessageListComponent {
|
|
|
6814
6863
|
if (result) {
|
|
6815
6864
|
(_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}` });
|
|
6816
6865
|
this.isLoading = true;
|
|
6866
|
+
(_c = result.catch) === null || _c === void 0 ? void 0 : _c.call(result, () => {
|
|
6867
|
+
this.isLoading = false;
|
|
6868
|
+
});
|
|
6817
6869
|
}
|
|
6818
6870
|
this.cdRef.detectChanges();
|
|
6819
6871
|
});
|
|
@@ -6882,16 +6934,20 @@ class MessageListComponent {
|
|
|
6882
6934
|
position = 'top';
|
|
6883
6935
|
}
|
|
6884
6936
|
else if (Math.ceil(this.scrollContainer.nativeElement.scrollTop) +
|
|
6885
|
-
this.scrollContainer.nativeElement.clientHeight
|
|
6937
|
+
this.scrollContainer.nativeElement.clientHeight +
|
|
6938
|
+
1 >=
|
|
6886
6939
|
this.scrollContainer.nativeElement.scrollHeight) {
|
|
6887
6940
|
position = 'bottom';
|
|
6888
6941
|
}
|
|
6889
6942
|
return position;
|
|
6890
6943
|
}
|
|
6891
6944
|
shouldLoadMoreMessages(scrollPosition) {
|
|
6892
|
-
return scrollPosition !== 'middle' &&
|
|
6945
|
+
return (scrollPosition !== 'middle' &&
|
|
6946
|
+
!this.highlightedMessageId &&
|
|
6947
|
+
!this.isLoading);
|
|
6893
6948
|
}
|
|
6894
6949
|
setMessages$() {
|
|
6950
|
+
var _a;
|
|
6895
6951
|
this.messages$ = (this.mode === 'main'
|
|
6896
6952
|
? this.channelService.activeChannelMessages$
|
|
6897
6953
|
: this.channelService.activeThreadMessages$).pipe(tap((messages) => {
|
|
@@ -6955,7 +7011,40 @@ class MessageListComponent {
|
|
|
6955
7011
|
lastReadMessageId: this.lastReadMessageId,
|
|
6956
7012
|
}));
|
|
6957
7013
|
this.isNextMessageOnSeparateDate = messages.map((m, i) => this.checkIfOnSeparateDates(m, messages[i + 1]));
|
|
6958
|
-
}));
|
|
7014
|
+
}), shareReplay(1));
|
|
7015
|
+
(_a = this.removeOldMessagesSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
7016
|
+
this.removeOldMessagesSubscription = combineLatest([
|
|
7017
|
+
this.channelService.jumpToMessage$,
|
|
7018
|
+
this.messages$,
|
|
7019
|
+
]).subscribe(([jumpToMessage, messages]) => {
|
|
7020
|
+
if (this.limitNumberOfMessagesInList &&
|
|
7021
|
+
this.mode === 'main' &&
|
|
7022
|
+
messages.length >
|
|
7023
|
+
ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST * 0.5 &&
|
|
7024
|
+
!this.isUserScrolled &&
|
|
7025
|
+
!(jumpToMessage === null || jumpToMessage === void 0 ? void 0 : jumpToMessage.id) &&
|
|
7026
|
+
this.isLatestMessageInList) {
|
|
7027
|
+
if (this.messageRemoveTimeout) {
|
|
7028
|
+
clearTimeout(this.messageRemoveTimeout);
|
|
7029
|
+
}
|
|
7030
|
+
if (messages.length >= ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST) {
|
|
7031
|
+
this.channelService.removeOldMessageFromMessageList();
|
|
7032
|
+
}
|
|
7033
|
+
else {
|
|
7034
|
+
this.messageRemoveTimeout = setTimeout(() => {
|
|
7035
|
+
if (this.limitNumberOfMessagesInList &&
|
|
7036
|
+
this.mode === 'main' &&
|
|
7037
|
+
messages.length >
|
|
7038
|
+
ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST * 0.5 &&
|
|
7039
|
+
!this.isUserScrolled &&
|
|
7040
|
+
!this.highlightedMessageId &&
|
|
7041
|
+
this.isLatestMessageInList) {
|
|
7042
|
+
this.channelService.removeOldMessageFromMessageList();
|
|
7043
|
+
}
|
|
7044
|
+
}, 1500);
|
|
7045
|
+
}
|
|
7046
|
+
}
|
|
7047
|
+
});
|
|
6959
7048
|
}
|
|
6960
7049
|
resetScrollState() {
|
|
6961
7050
|
this.isEmpty = true;
|
|
@@ -7038,7 +7127,7 @@ class MessageListComponent {
|
|
|
7038
7127
|
}
|
|
7039
7128
|
}
|
|
7040
7129
|
MessageListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, deps: [{ token: ChannelService }, { token: ChatClientService }, { token: CustomTemplatesService }, { token: DateParserService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: MessageActionsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
7041
|
-
MessageListComponent.ɵcmp = i0.ɵɵ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, 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.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "translate": i9.TranslatePipe, "async": i8.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7130
|
+
MessageListComponent.ɵcmp = i0.ɵɵ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, 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.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "translate": i9.TranslatePipe, "async": i8.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7042
7131
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, decorators: [{
|
|
7043
7132
|
type: Component,
|
|
7044
7133
|
args: [{
|
|
@@ -7069,6 +7158,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
7069
7158
|
type: Input
|
|
7070
7159
|
}], displayLoadingIndicator: [{
|
|
7071
7160
|
type: Input
|
|
7161
|
+
}], limitNumberOfMessagesInList: [{
|
|
7162
|
+
type: Input
|
|
7072
7163
|
}], scrollContainer: [{
|
|
7073
7164
|
type: ViewChild,
|
|
7074
7165
|
args: ['scrollContainer']
|