stream-chat-angular 4.45.2 → 4.47.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 +73 -9
- package/bundles/stream-chat-angular.umd.js.map +1 -1
- package/esm2015/assets/version.js +2 -2
- package/esm2015/lib/chat-client.service.js +19 -1
- package/esm2015/lib/custom-templates.service.js +9 -1
- package/esm2015/lib/message-list/message-list.component.js +39 -9
- package/fesm2015/stream-chat-angular.js +65 -9
- package/fesm2015/stream-chat-angular.js.map +1 -1
- package/lib/custom-templates.service.d.ts +8 -0
- package/lib/message-list/message-list.component.d.ts +8 -3
- package/package.json +1 -1
- package/src/assets/version.ts +1 -1
|
@@ -20,7 +20,7 @@ import transliterate from '@stream-io/transliterate';
|
|
|
20
20
|
import * as i8 from 'angular-mentions';
|
|
21
21
|
import { MentionModule } from 'angular-mentions';
|
|
22
22
|
|
|
23
|
-
const version = '4.
|
|
23
|
+
const version = '4.47.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.
|
|
@@ -265,6 +265,24 @@ class ChatClientService {
|
|
|
265
265
|
this.userSubject.next(Object.assign(Object.assign({}, user), { total_unread_count: e.total_unread_count }));
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
|
+
if (typeof e.unread_channels !== 'undefined') {
|
|
269
|
+
let user;
|
|
270
|
+
this.userSubject.pipe(take(1)).subscribe((u) => {
|
|
271
|
+
user = u;
|
|
272
|
+
});
|
|
273
|
+
if (user && user.unread_channels !== e.unread_channels) {
|
|
274
|
+
this.userSubject.next(Object.assign(Object.assign({}, user), { unread_channels: e.unread_channels }));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (typeof e.unread_count !== 'undefined') {
|
|
278
|
+
let user;
|
|
279
|
+
this.userSubject.pipe(take(1)).subscribe((u) => {
|
|
280
|
+
user = u;
|
|
281
|
+
});
|
|
282
|
+
if (user && user.unread_count !== e.unread_count) {
|
|
283
|
+
this.userSubject.next(Object.assign(Object.assign({}, user), { unread_count: e.unread_count }));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
268
286
|
if (e.type === 'user.updated' &&
|
|
269
287
|
this.chatClient.user &&
|
|
270
288
|
((_a = e.user) === null || _a === void 0 ? void 0 : _a.id) === this.chatClient.user.id) {
|
|
@@ -2556,6 +2574,14 @@ class CustomTemplatesService {
|
|
|
2556
2574
|
* The template used to display the new messages indicator inside the [message list](../components/MessageListComponent.mdx)
|
|
2557
2575
|
*/
|
|
2558
2576
|
this.newMessagesIndicatorTemplate$ = new BehaviorSubject(undefined);
|
|
2577
|
+
/**
|
|
2578
|
+
* The template to show if the main message list is empty
|
|
2579
|
+
*/
|
|
2580
|
+
this.emptyMainMessageListPlaceholder$ = new BehaviorSubject(undefined);
|
|
2581
|
+
/**
|
|
2582
|
+
* The template to show if the thread message list is empty
|
|
2583
|
+
*/
|
|
2584
|
+
this.emptyThreadMessageListPlaceholder$ = new BehaviorSubject(undefined);
|
|
2559
2585
|
}
|
|
2560
2586
|
}
|
|
2561
2587
|
CustomTemplatesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: CustomTemplatesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -5253,12 +5279,13 @@ const isOnSameDay = (date1, date2) => {
|
|
|
5253
5279
|
* The `MessageList` component renders a scrollable list of messages.
|
|
5254
5280
|
*/
|
|
5255
5281
|
class MessageListComponent {
|
|
5256
|
-
constructor(channelService, chatClientService, customTemplatesService, dateParser, ngZone) {
|
|
5282
|
+
constructor(channelService, chatClientService, customTemplatesService, dateParser, ngZone, cdRef) {
|
|
5257
5283
|
this.channelService = channelService;
|
|
5258
5284
|
this.chatClientService = chatClientService;
|
|
5259
5285
|
this.customTemplatesService = customTemplatesService;
|
|
5260
5286
|
this.dateParser = dateParser;
|
|
5261
5287
|
this.ngZone = ngZone;
|
|
5288
|
+
this.cdRef = cdRef;
|
|
5262
5289
|
/**
|
|
5263
5290
|
* Determines if the message list should display channel messages or [thread messages](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
|
|
5264
5291
|
*/
|
|
@@ -5298,8 +5325,10 @@ class MessageListComponent {
|
|
|
5298
5325
|
* You can turn on and off the loading indicator that signals to users that more messages are being loaded to the message list
|
|
5299
5326
|
*/
|
|
5300
5327
|
this.displayLoadingIndicator = true;
|
|
5328
|
+
this.emptyMainMessageListTemplate = null;
|
|
5329
|
+
this.emptyThreadMessageListTemplate = null;
|
|
5301
5330
|
this.enabledMessageActions = [];
|
|
5302
|
-
this.
|
|
5331
|
+
this.isEmpty = true;
|
|
5303
5332
|
this.unreadMessageCount = 0;
|
|
5304
5333
|
this.groupStyles = [];
|
|
5305
5334
|
this.isNextMessageOnSeparateDate = [];
|
|
@@ -5366,6 +5395,9 @@ class MessageListComponent {
|
|
|
5366
5395
|
this.usersTypingInChannel$ = this.channelService.usersTypingInChannel$;
|
|
5367
5396
|
this.usersTypingInThread$ = this.channelService.usersTypingInThread$;
|
|
5368
5397
|
}
|
|
5398
|
+
get class() {
|
|
5399
|
+
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' : ''}`;
|
|
5400
|
+
}
|
|
5369
5401
|
ngOnInit() {
|
|
5370
5402
|
this.setMessages$();
|
|
5371
5403
|
}
|
|
@@ -5406,6 +5438,20 @@ class MessageListComponent {
|
|
|
5406
5438
|
}
|
|
5407
5439
|
}
|
|
5408
5440
|
}));
|
|
5441
|
+
this.subscriptions.push(this.customTemplatesService.emptyMainMessageListPlaceholder$.subscribe((template) => {
|
|
5442
|
+
const isChanged = this.emptyMainMessageListTemplate !== template;
|
|
5443
|
+
this.emptyMainMessageListTemplate = template || null;
|
|
5444
|
+
if (isChanged) {
|
|
5445
|
+
this.cdRef.detectChanges();
|
|
5446
|
+
}
|
|
5447
|
+
}));
|
|
5448
|
+
this.subscriptions.push(this.customTemplatesService.emptyThreadMessageListPlaceholder$.subscribe((template) => {
|
|
5449
|
+
const isChanged = this.emptyThreadMessageListTemplate !== template;
|
|
5450
|
+
this.emptyThreadMessageListTemplate = template || null;
|
|
5451
|
+
if (isChanged) {
|
|
5452
|
+
this.cdRef.detectChanges();
|
|
5453
|
+
}
|
|
5454
|
+
}));
|
|
5409
5455
|
}
|
|
5410
5456
|
ngAfterViewChecked() {
|
|
5411
5457
|
var _a, _b, _c, _d, _e, _f;
|
|
@@ -5547,6 +5593,11 @@ class MessageListComponent {
|
|
|
5547
5593
|
var _a;
|
|
5548
5594
|
return { replyCount: (_a = this.parentMessage) === null || _a === void 0 ? void 0 : _a.reply_count };
|
|
5549
5595
|
}
|
|
5596
|
+
get emptyListTemplate() {
|
|
5597
|
+
return this.mode === 'main'
|
|
5598
|
+
? this.emptyMainMessageListTemplate
|
|
5599
|
+
: this.emptyThreadMessageListTemplate;
|
|
5600
|
+
}
|
|
5550
5601
|
preserveScrollbarPosition() {
|
|
5551
5602
|
this.scrollContainer.nativeElement.scrollTop =
|
|
5552
5603
|
(this.prevScrollTop || 0) +
|
|
@@ -5591,6 +5642,10 @@ class MessageListComponent {
|
|
|
5591
5642
|
this.resetScrollState();
|
|
5592
5643
|
return;
|
|
5593
5644
|
}
|
|
5645
|
+
if (this.isEmpty) {
|
|
5646
|
+
// cdRef.detectChanges() isn't enough here, test will fail
|
|
5647
|
+
setTimeout(() => (this.isEmpty = false), 0);
|
|
5648
|
+
}
|
|
5594
5649
|
(_d = (_c = this.chatClientService.chatClient) === null || _c === void 0 ? void 0 : _c.logger) === null || _d === void 0 ? void 0 : _d.call(_c, 'info', `Received one or more messages`, {
|
|
5595
5650
|
tags: `message list ${this.mode}`,
|
|
5596
5651
|
});
|
|
@@ -5636,6 +5691,7 @@ class MessageListComponent {
|
|
|
5636
5691
|
}));
|
|
5637
5692
|
}
|
|
5638
5693
|
resetScrollState() {
|
|
5694
|
+
this.isEmpty = true;
|
|
5639
5695
|
this.latestMessage = undefined;
|
|
5640
5696
|
this.hasNewMessages = true;
|
|
5641
5697
|
this.isUserScrolled = false;
|
|
@@ -5708,8 +5764,8 @@ class MessageListComponent {
|
|
|
5708
5764
|
return false;
|
|
5709
5765
|
}
|
|
5710
5766
|
}
|
|
5711
|
-
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 }], target: i0.ɵɵFactoryTarget.Component });
|
|
5712
|
-
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", dateSeparatorTextPos: "dateSeparatorTextPos", openMessageListAt: "openMessageListAt", 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: "<div\n #scrollContainer\n data-testid=\"scroll-container\"\n class=\"str-chat__list\"\n style=\"overscroll-behavior: none\"\n>\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 <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 isNewMessage: false\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 !isLast &&\n direction === 'bottom-to-top' &&\n !isSentByCurrentUser(messages[i + 1]) &&\n (!displayDateSeparator || !isNextMessageOnSeparateDate[i])) ||\n (direction === 'top-to-bottom' &&\n !isLast &&\n !isSentByCurrentUser(message) &&\n lastReadMessageId === messages[i + 1].id)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesIndicatorTemplate ||\n defaultNewMessagesIndicator\n \"\n ></ng-container>\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 isNewMessage:\n (direction === 'bottom-to-top' &&\n message.id === lastReadMessageId &&\n !isSentByCurrentUser(messages[i + 1])) ||\n (direction === 'top-to-bottom' && false)\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\"\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=\"unreadMessageCount > 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 {{ unreadMessageCount }}\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:\n message?.id === highlightedMessageId &&\n !isJumpingToLatestUnreadMessage,\n customActions: customMessageActions\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template\n #dateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n let-isNewMessage=\"isNewMessage\"\n>\n <ng-container *ngIf=\"displayDateSeparator\">\n <ng-container\n *ngTemplateOutlet=\"\n customDateSeparatorTemplate || defaultDateSeparator;\n context: {\n date: date,\n parsedDate: parsedDate,\n isNewMessage: isNewMessage\n }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template\n #defaultDateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n let-isNewMessage=\"isNewMessage\"\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 <span\n *ngIf=\"isNewMessage\"\n data-testid=\"new-messages-indicator-date-separator\"\n >\u2022 {{ \"streamChat.New\" | translate }}</span\n >\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>\n <div data-testid=\"new-messages-indicator\" 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\" translate>streamChat.New</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", components: [{ 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: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i9.TranslatePipe, "async": i5.AsyncPipe } });
|
|
5767
|
+
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 }], target: i0.ɵɵFactoryTarget.Component });
|
|
5768
|
+
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", dateSeparatorTextPos: "dateSeparatorTextPos", openMessageListAt: "openMessageListAt", 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: "<div\n #scrollContainer\n data-testid=\"scroll-container\"\n class=\"str-chat__list\"\n style=\"overscroll-behavior: none\"\n>\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 isNewMessage: false\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 !isLast &&\n direction === 'bottom-to-top' &&\n !isSentByCurrentUser(messages[i + 1]) &&\n (!displayDateSeparator || !isNextMessageOnSeparateDate[i])) ||\n (direction === 'top-to-bottom' &&\n !isLast &&\n !isSentByCurrentUser(message) &&\n lastReadMessageId === messages[i + 1].id)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n customnewMessagesIndicatorTemplate ||\n defaultNewMessagesIndicator\n \"\n ></ng-container>\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 isNewMessage:\n (direction === 'bottom-to-top' &&\n message.id === lastReadMessageId &&\n !isSentByCurrentUser(messages[i + 1])) ||\n (direction === 'top-to-bottom' && false)\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\"\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=\"unreadMessageCount > 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 {{ unreadMessageCount }}\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:\n message?.id === highlightedMessageId &&\n !isJumpingToLatestUnreadMessage,\n customActions: customMessageActions\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template\n #dateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n let-isNewMessage=\"isNewMessage\"\n>\n <ng-container *ngIf=\"displayDateSeparator\">\n <ng-container\n *ngTemplateOutlet=\"\n customDateSeparatorTemplate || defaultDateSeparator;\n context: {\n date: date,\n parsedDate: parsedDate,\n isNewMessage: isNewMessage\n }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template\n #defaultDateSeparator\n let-date=\"date\"\n let-parsedDate=\"parsedDate\"\n let-isNewMessage=\"isNewMessage\"\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 <span\n *ngIf=\"isNewMessage\"\n data-testid=\"new-messages-indicator-date-separator\"\n >\u2022 {{ \"streamChat.New\" | translate }}</span\n >\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>\n <div data-testid=\"new-messages-indicator\" 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\" translate>streamChat.New</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", components: [{ 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: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "translate": i9.TranslatePipe, "async": i5.AsyncPipe } });
|
|
5713
5769
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0, type: MessageListComponent, decorators: [{
|
|
5714
5770
|
type: Component,
|
|
5715
5771
|
args: [{
|
|
@@ -5717,7 +5773,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
5717
5773
|
templateUrl: './message-list.component.html',
|
|
5718
5774
|
styles: [],
|
|
5719
5775
|
}]
|
|
5720
|
-
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: CustomTemplatesService }, { type: DateParserService }, { type: i0.NgZone }]; }, propDecorators: { mode: [{
|
|
5776
|
+
}], ctorParameters: function () { return [{ type: ChannelService }, { type: ChatClientService }, { type: CustomTemplatesService }, { type: DateParserService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { mode: [{
|
|
5721
5777
|
type: Input
|
|
5722
5778
|
}], direction: [{
|
|
5723
5779
|
type: Input
|
|
@@ -5735,15 +5791,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImpor
|
|
|
5735
5791
|
type: Input
|
|
5736
5792
|
}], displayLoadingIndicator: [{
|
|
5737
5793
|
type: Input
|
|
5738
|
-
}], class: [{
|
|
5739
|
-
type: HostBinding,
|
|
5740
|
-
args: ['class']
|
|
5741
5794
|
}], scrollContainer: [{
|
|
5742
5795
|
type: ViewChild,
|
|
5743
5796
|
args: ['scrollContainer']
|
|
5744
5797
|
}], parentMessageElement: [{
|
|
5745
5798
|
type: ViewChild,
|
|
5746
5799
|
args: ['parentMessageElement']
|
|
5800
|
+
}], class: [{
|
|
5801
|
+
type: HostBinding,
|
|
5802
|
+
args: ['class']
|
|
5747
5803
|
}] } });
|
|
5748
5804
|
|
|
5749
5805
|
/**
|