|
1 | 1 | import { |
2 | 2 | AfterViewChecked, |
3 | 3 | AfterViewInit, |
| 4 | + ChangeDetectorRef, |
4 | 5 | Component, |
5 | 6 | ElementRef, |
6 | 7 | HostBinding, |
@@ -87,10 +88,11 @@ export class MessageListComponent |
87 | 88 | messageTemplate: TemplateRef<MessageContext> | undefined; |
88 | 89 | customDateSeparatorTemplate: TemplateRef<DateSeparatorContext> | undefined; |
89 | 90 | customnewMessagesIndicatorTemplate: TemplateRef<void> | undefined; |
| 91 | + emptyMainMessageListTemplate: TemplateRef<void> | null = null; |
| 92 | + emptyThreadMessageListTemplate: TemplateRef<void> | null = null; |
90 | 93 | messages$!: Observable<StreamMessage[]>; |
91 | 94 | enabledMessageActions: string[] = []; |
92 | | - @HostBinding('class') private class = |
93 | | - 'str-chat-angular__main-panel-inner str-chat-angular__message-list-host str-chat__main-panel-inner'; |
| 95 | + isEmpty = true; |
94 | 96 | unreadMessageCount = 0; |
95 | 97 | isUserScrolled: boolean | undefined; |
96 | 98 | groupStyles: GroupStyle[] = []; |
@@ -125,12 +127,20 @@ export class MessageListComponent |
125 | 127 | private channelId?: string; |
126 | 128 | private parsedDates = new Map<Date, string>(); |
127 | 129 |
|
| 130 | + @HostBinding('class') |
| 131 | + private get class() { |
| 132 | + return `str-chat-angular__main-panel-inner str-chat-angular__message-list-host str-chat__main-panel-inner ${ |
| 133 | + this.isEmpty ? 'str-chat-angular__message-list-host--empty' : '' |
| 134 | + }`; |
| 135 | + } |
| 136 | + |
128 | 137 | constructor( |
129 | 138 | private channelService: ChannelService, |
130 | 139 | private chatClientService: ChatClientService, |
131 | 140 | private customTemplatesService: CustomTemplatesService, |
132 | 141 | private dateParser: DateParserService, |
133 | | - private ngZone: NgZone |
| 142 | + private ngZone: NgZone, |
| 143 | + private cdRef: ChangeDetectorRef |
134 | 144 | ) { |
135 | 145 | this.subscriptions.push( |
136 | 146 | this.channelService.activeChannel$.subscribe((channel) => { |
@@ -269,6 +279,28 @@ export class MessageListComponent |
269 | 279 | } |
270 | 280 | }) |
271 | 281 | ); |
| 282 | + this.subscriptions.push( |
| 283 | + this.customTemplatesService.emptyMainMessageListPlaceholder$.subscribe( |
| 284 | + (template) => { |
| 285 | + const isChanged = this.emptyMainMessageListTemplate !== template; |
| 286 | + this.emptyMainMessageListTemplate = template || null; |
| 287 | + if (isChanged) { |
| 288 | + this.cdRef.detectChanges(); |
| 289 | + } |
| 290 | + } |
| 291 | + ) |
| 292 | + ); |
| 293 | + this.subscriptions.push( |
| 294 | + this.customTemplatesService.emptyThreadMessageListPlaceholder$.subscribe( |
| 295 | + (template) => { |
| 296 | + const isChanged = this.emptyThreadMessageListTemplate !== template; |
| 297 | + this.emptyThreadMessageListTemplate = template || null; |
| 298 | + if (isChanged) { |
| 299 | + this.cdRef.detectChanges(); |
| 300 | + } |
| 301 | + } |
| 302 | + ) |
| 303 | + ); |
272 | 304 | } |
273 | 305 |
|
274 | 306 | ngAfterViewChecked() { |
@@ -451,6 +483,12 @@ export class MessageListComponent |
451 | 483 | return { replyCount: this.parentMessage?.reply_count }; |
452 | 484 | } |
453 | 485 |
|
| 486 | + get emptyListTemplate() { |
| 487 | + return this.mode === 'main' |
| 488 | + ? this.emptyMainMessageListTemplate |
| 489 | + : this.emptyThreadMessageListTemplate; |
| 490 | + } |
| 491 | + |
454 | 492 | private preserveScrollbarPosition() { |
455 | 493 | this.scrollContainer.nativeElement.scrollTop = |
456 | 494 | (this.prevScrollTop || 0) + |
@@ -508,6 +546,10 @@ export class MessageListComponent |
508 | 546 | this.resetScrollState(); |
509 | 547 | return; |
510 | 548 | } |
| 549 | + if (this.isEmpty) { |
| 550 | + // cdRef.detectChanges() isn't enough here, test will fail |
| 551 | + setTimeout(() => (this.isEmpty = false), 0); |
| 552 | + } |
511 | 553 | this.chatClientService.chatClient?.logger?.( |
512 | 554 | 'info', |
513 | 555 | `Received one or more messages`, |
@@ -574,6 +616,7 @@ export class MessageListComponent |
574 | 616 | } |
575 | 617 |
|
576 | 618 | private resetScrollState() { |
| 619 | + this.isEmpty = true; |
577 | 620 | this.latestMessage = undefined; |
578 | 621 | this.hasNewMessages = true; |
579 | 622 | this.isUserScrolled = false; |
|
0 commit comments