React-native-gifted-chat: Need to auto-scroll to a particular message of a chat conversation

Created on 25 Jul 2018  路  27Comments  路  Source: FaridSafi/react-native-gifted-chat

Good afternoon,

I have a chat messages thread and I want to scroll to a particular message by it's Id. I have searched and haven't found anything so far.

e.g. : I have a 'message search' scene in my application. When you enter something in the search bar, every messages from every contacts are fetched and I display only some that corresponds with the entry.

When I click on a particular message of a particular contact, I navigate to this contact chat conversation.

The only thing I need is scrolling to that particular message. I know every message have an Id, that's why I wanted to know if there's a method to move directly to a specific message by providing the chat Id.

Hope you can help me with this 馃憤

Additional Information

  • Nodejs version: v8.9.4
  • React version: 16.2.0
  • React Native version: 0.55.4
  • react-native-gifted-chat version: 0.4.3
  • Platform(s) (IOS&Android): (IOS v11.2, Android v6.0)
wontfix

Most helpful comment

I finally did it by myself with v0.4.3.
The idea is:

  1. Get ref of the list view chatListView.
  2. Get position of the message views. Because in v0.4.3, gifted-chat using InvertibleScrollView. So I have to using a callback from onLayout of the View in InvertibleScrollView. Then I store them in a stored dictionary.

==> Scroll to message: Get position (messageViewY) of message view from the stored dictionary. Then:

let scrollY = messageViewY - this.chatListView.scrollProperties.visibleLength;
this.chatListView.scrollTo({ x: 0, y: scrollY, animated: true });

All 27 comments

I will also be looking forward to having this feature. I see that gifted chat uses RN's FlatList (https://github.com/FaridSafi/react-native-gifted-chat/blob/master/src/MessageContainer.js) so this could be used https://facebook.github.io/react-native/docs/virtualizedlist.html#scrolltooffset Which I see they have that function in Gifted chat also:

scrollTo(options) {
if (this.flatListRef) {
this.flatListRef.scrollToOffset(options);
}
}

I haven't been able to dig in more to see how to implement it though. I hope it helps in some way!

Also looking for it

@leron8 Thank you for your reply.

Your answer would work with a normal flatList usage, but I don't know if the behavior will still work even with the spacing for the dates displaying, and the variable height depending of the chat message content.

I will work on this issue and make up a pull request as soon as I can! :)

I'm looking for something similar...
Let me know if you guys figure out how to do that.

@leron8 : created this scrolling functionality ? Let me know if you have so that I need to implement at my end also

Hello @maulikdhameliya I haven't implemented it. Been busy. I believe @Thyix might have worked on a PR, but not sure though.

Didn't find anything yet, sadly :(

Technically, as alluded gifted chat uses Flatlist internally and it could be that you can use scrollToIndex but as documentation states it depends on getItemLayout and that depends on giving Flatlist heights to the items upfront.
@leron8 Your PR would be able to calculate variable item heights?

Hey @testshallpasswork I can't work on PR right now. @Thyix was but he says he hasn't found anything yet :'(

I'm waiting for this also. Hope.

I finally did it by myself with v0.4.3.
The idea is:

  1. Get ref of the list view chatListView.
  2. Get position of the message views. Because in v0.4.3, gifted-chat using InvertibleScrollView. So I have to using a callback from onLayout of the View in InvertibleScrollView. Then I store them in a stored dictionary.

==> Scroll to message: Get position (messageViewY) of message view from the stored dictionary. Then:

let scrollY = messageViewY - this.chatListView.scrollProperties.visibleLength;
this.chatListView.scrollTo({ x: 0, y: scrollY, animated: true });

@anhtukhtn can you please provide a little more detail on this? I have my reference to gifted chat but am a little confused after that.

@SrWildman
I did it with v0.4.3 ,when gifted-chat used InvertibleScrollView. It uses FlatList in v0.5 now.
So my solution maybe not work anymore.

If you still use v0.4.3. You can see more detail from forked repo
https://github.com/anhtukhtn/react-native-gifted-chat/commit/8408a24f41fd8f2c14902c9681094c375919821b
https://github.com/anhtukhtn/react-native-invertible-scroll-view/commit/fa7ee55ffcb08809b9a32e34510ab4ff56c5b419

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This was simpler than I thought. I have created a PR https://github.com/FaridSafi/react-native-gifted-chat/pull/1157

@Thyix Can you check if it works for you, if you haven't found a solution already.

I finally did it by myself with v0.4.3.
The idea is:

  1. Get ref of the list view chatListView.
  2. Get position of the message views. Because in v0.4.3, gifted-chat using InvertibleScrollView. So I have to using a callback from onLayout of the View in InvertibleScrollView. Then I store them in a stored dictionary.

==> Scroll to message: Get position (messageViewY) of message view from the stored dictionary. Then:

let scrollY = messageViewY - this.chatListView.scrollProperties.visibleLength;
this.chatListView.scrollTo({ x: 0, y: scrollY, animated: true });

It says scrollTo in not a function. Any idea what might the reason?

@infaz Did you link it with ListView ref? I did it with v0.4.3.
At the current version >v0.6, GiftedChat changed the container to FlatList.

I want a scenario that on particular condition the chat should not scroll to the bottom(latest message), unless user manually scroll it.
can we achieve it with updated gifted-chat version?

My strategy:

  • Store in redux or in a state the message that you would like to focus
  • Pass each message row a field focusedMessage={}
  • do a check in the component, if props.focusedMessage === this.props.message then ref.measure, then props.shouldScrollTo

  • In the GiftedChat component, in the renderMessage section:

shouldScrollTo={(offset: number) => {
    ref.current._messageContainerRef.current.scrollToOffset({
        offset: scrollViewHeight - offset // for inverted
    });
}}

@JonnyBurger
As I understood you do it this way:
<GiftedChat ......... renderMessage={this.renderMessage} ref={this.chatListRef} shouldScrollTo={(offset) => { this.chatListRef.current._messageContainerRef.current.scrollToOffset({ offset: scrollViewHeight - offset }); }} focusedMessage={focusedMessage} />
Could you please explain how to calculate offset and scrollViewHeight?
And my renderMessage:
renderMessage(props) { if (props.focusedMessage && props.currentMessage._id === props.focusedMessage.id) { props.shouldScrollTo(.....) } return <Message text={props.currentMessage.text}/>; }

@romanmashkovskiy By scrollViewHeight I meant scroll view position, sorry. It can be calculated by listening to onScroll event of the ScrollView. The offset is already given in the callback, it doesn't need to be calculated.

@JonnyBurger As I understood I should call shouldScrollTo in my renderMessage if current message is equal to focused. Correct?

Yes, in my chat message view I have the following:

    componentDidUpdate(prevProps) {
        if (
            this.props.currentMessage?._id === this.props.scrollToMessage &&
            !prevProps.scrollToMessage
        ) {
            this.ref.current?.measure((fx, fy, width, height, px, py) => {
                this.props.shouldScrollTo(py);
                Animated.timing(this.animatedValue, {
                    toValue: 100,
                    duration: 200
                }).start();
            });
        }
        if (
            prevProps.currentMessage._id === prevProps.scrollToMessage &&
            !this.props.scrollToMessage
        ) {
            Animated.timing(this.animatedValue, {
                toValue: 0,
                duration: 1000
            }).start();
        }
    }

@JonnyBurger I added ref to my GiftedChat component <GiftedChat ref={this.chatListRef} />. But this.chatListRef.measure is not a function

Add the ref to each message. Also it might be ref.current.measure.

Add the ref to each message. Also it might be ref.current.measure.

I couldn't find measure inside ref._messageContainerRef.current or ref.current.measure. Did any one get the exact location of this.

@4RGUS
I solved it by calling FlatList's scrollToIndex

      giftedChatRef.current?._messageContainerRef?.current?.scrollToIndex({
        animated: true,
        index: 5,
      });
Was this page helpful?
0 / 5 - 0 ratings

Related issues

cassioseffrin picture cassioseffrin  路  3Comments

iamdurui picture iamdurui  路  3Comments

radvc picture radvc  路  3Comments

luisfuertes picture luisfuertes  路  3Comments

pentarex picture pentarex  路  3Comments