Topic: Scroll Bottom Of Chat

ewgiddings free asked 2 years ago


Expected behavior When adding a new message to the chat component for the chat be aligned to the bottom as happens with most every chat application. Actual behavior Adding a new message does not scroll the overflow to the bottom of the message area. It should auto scroll to the bottom most (newest) message. This is how most chat applications act. Resources (screenshots, code snippets etc.) WhatsApp, Messenger, SMS, all align to the bottom of the overflow when a new message is added.

Question How do we get the MDB Small Chat component of class .my-custom-scrollbar to scroll to the bottom so the newly added messages are in view and push out of view older messages?


Konrad Stępień staff answered 2 years ago


Hi @ewgiddings,

You can use this code for scroll to bottom message:

element.nativeElement.scrollTop = element.nativeElement.scrollHeight;

For example, I get div with @ViewChild method like this:

HTML:

<div class="my-custom-scrollbar" #scroll>

TS:

@ViewChild('scroll', { static: true }) scroll: any;

and then when I get new message ( ngOnChange or another event) i use this code

this.scroll.nativeElement.scrollTop = this.scroll.nativeElement.scrollHeight;

Can you try this in your project?

Best, Konrad.


ewgiddings free commented 2 years ago

Yea this is what I ended up using. I was wondering if this was the way you all recommend since there's nothing in the docs about it.

The biggest problem with this is that pushing a message to the message array and then calling this it only scrolls to the bottom of the message before the newest one. I have to set a timeout on that call of 1 millisecond to actually scroll to the bottom.

this.chatMessages.push({ userName: this.user.userName, userId: this.user.id.toString(), message: this.newMessage }); setTimeout(() => { const messageArea = document.getElementsByClassName('my-custom-scrollbar')[0] as HTMLElement; messageArea.scrollTop = messageArea.scrollHeight - messageArea.clientHeight; }, 1);

If I don't use that setTimeout then the method you described only scrolls to the previously sent message not the newest.


Konrad Stępień staff commented 2 years ago

There are probably other ways to achieve a similar effect, it all depends on how the project is created.

Have you tried maybe to use asynchronous data?


ewgiddings free commented 2 years ago

The project is simply pushing a message model into the array of messages using array.push(messageModel). Do you suggest I turn that array push into some sort of promise or async function? Is that what you mean by using async data?


Konrad Stępień staff commented 2 years ago

Do you suggest I turn that array push into some sort of promise or async function?

Yes, but I didn't saw your push function.

I did your example with this function and I didn't find any other solution besides:

import { Component, ViewChild, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements AfterViewInit {
  @ViewChild('scroll', { static: true }) scroll: any;

  messages: string[] = [];

  addMess = (text: string) => {
    this.messages.push(text);
    setTimeout(() => {
      this.scroll.nativeElement.scrollTo(0, this.scroll.nativeElement.scrollHeight);
    }, 0);
  };

  ngAfterViewInit() {
    this.scroll.nativeElement.scrollTo(0, this.scroll.nativeElement.scrollHeight);
  }
}

I'm afraid that setTimeout must be used



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • User: Free
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: 8.6.0
  • Device: Surface
  • Browser: Chrome
  • OS: Windows
  • Provided sample code: No
  • Provided link: No