diff --git a/projects/stream-chat-angular/src/lib/custom-templates.service.ts b/projects/stream-chat-angular/src/lib/custom-templates.service.ts index f0bfc639..f26645a3 100644 --- a/projects/stream-chat-angular/src/lib/custom-templates.service.ts +++ b/projects/stream-chat-angular/src/lib/custom-templates.service.ts @@ -292,8 +292,17 @@ export class CustomTemplatesService { newMessagesIndicatorTemplate$ = new BehaviorSubject< TemplateRef | undefined >(undefined); - emptyChannelPlaceholder$ = new BehaviorSubject< - TemplateRef<{ mode: 'main' | 'thread' }> | undefined + /** + * The template to show if the main message list is empty + */ + emptyMainMessageListPlaceholder$ = new BehaviorSubject< + TemplateRef | undefined + >(undefined); + /** + * The template to show if the thread message list is empty + */ + emptyThreadMessageListPlaceholder$ = new BehaviorSubject< + TemplateRef | undefined >(undefined); constructor() {} diff --git a/projects/stream-chat-angular/src/lib/message-list/message-list.component.html b/projects/stream-chat-angular/src/lib/message-list/message-list.component.html index fc256d8d..fa24f92b 100644 --- a/projects/stream-chat-angular/src/lib/message-list/message-list.component.html +++ b/projects/stream-chat-angular/src/lib/message-list/message-list.component.html @@ -4,6 +4,9 @@ class="str-chat__list" style="overscroll-behavior: none" > + + +
    + + + + + + +
  • + +
  • - - - -
  • - -
  • +
    + + - - - - - + >
    - - - -
    There are no messages
    -
    -
    | undefined; customDateSeparatorTemplate: TemplateRef | undefined; customnewMessagesIndicatorTemplate: TemplateRef | undefined; - emptyChannelPlaceholderTemplate: TemplateRef<{ - mode: 'main' | 'thread'; - }> | null = null; + emptyMainMessageListTemplate: TemplateRef | null = null; + emptyThreadMessageListTemplate: TemplateRef | null = null; messages$!: Observable; enabledMessageActions: string[] = []; - @HostBinding('class') private class = - 'str-chat-angular__main-panel-inner str-chat-angular__message-list-host str-chat__main-panel-inner'; + isEmpty = true; unreadMessageCount = 0; isUserScrolled: boolean | undefined; groupStyles: GroupStyle[] = []; @@ -128,12 +127,20 @@ export class MessageListComponent private channelId?: string; private parsedDates = new Map(); + @HostBinding('class') + private get class() { + 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' : '' + }`; + } + constructor( private channelService: ChannelService, private chatClientService: ChatClientService, private customTemplatesService: CustomTemplatesService, private dateParser: DateParserService, - private ngZone: NgZone + private ngZone: NgZone, + private cdRef: ChangeDetectorRef ) { this.subscriptions.push( this.channelService.activeChannel$.subscribe((channel) => { @@ -222,11 +229,6 @@ export class MessageListComponent (template) => (this.typingIndicatorTemplate = template) ) ); - this.subscriptions.push( - this.customTemplatesService.emptyChannelPlaceholder$.subscribe( - (template) => (this.emptyChannelPlaceholderTemplate = template || null) - ) - ); this.usersTypingInChannel$ = this.channelService.usersTypingInChannel$; this.usersTypingInThread$ = this.channelService.usersTypingInThread$; } @@ -277,6 +279,28 @@ export class MessageListComponent } }) ); + this.subscriptions.push( + this.customTemplatesService.emptyMainMessageListPlaceholder$.subscribe( + (template) => { + const isChanged = this.emptyMainMessageListTemplate !== template; + this.emptyMainMessageListTemplate = template || null; + if (isChanged) { + this.cdRef.detectChanges(); + } + } + ) + ); + this.subscriptions.push( + this.customTemplatesService.emptyThreadMessageListPlaceholder$.subscribe( + (template) => { + const isChanged = this.emptyThreadMessageListTemplate !== template; + this.emptyThreadMessageListTemplate = template || null; + if (isChanged) { + this.cdRef.detectChanges(); + } + } + ) + ); } ngAfterViewChecked() { @@ -459,6 +483,12 @@ export class MessageListComponent return { replyCount: this.parentMessage?.reply_count }; } + get emptyListTemplate() { + return this.mode === 'main' + ? this.emptyMainMessageListTemplate + : this.emptyThreadMessageListTemplate; + } + private preserveScrollbarPosition() { this.scrollContainer.nativeElement.scrollTop = (this.prevScrollTop || 0) + @@ -516,6 +546,10 @@ export class MessageListComponent this.resetScrollState(); return; } + if (this.isEmpty) { + // cdRef.detectChanges() isn't enough here, test will fail + setTimeout(() => (this.isEmpty = false), 0); + } this.chatClientService.chatClient?.logger?.( 'info', `Received one or more messages`, @@ -582,6 +616,7 @@ export class MessageListComponent } private resetScrollState() { + this.isEmpty = true; this.latestMessage = undefined; this.hasNewMessages = true; this.isUserScrolled = false;