Skip to content

fix: flash list scroll to behaviour#3602

Merged
isekovanic merged 8 commits into
developfrom
fix/flash-list-scroll-to-behaviour
May 19, 2026
Merged

fix: flash list scroll to behaviour#3602
isekovanic merged 8 commits into
developfrom
fix/flash-list-scroll-to-behaviour

Conversation

@isekovanic
Copy link
Copy Markdown
Contributor

🎯 Goal

This PR addresses 2 issues with MessageFlashList which have made scrollTo behaviour unreliable.

  1. It should fix (or at least make a lot better) the issue of being snapped back to the end of the list whenever we try to scroll to a quoted message for the very first time
  2. It should address not being able to scroll to the first unread message

Even though these 2 issues are seemingly similar, their underlying causes are completely different.

Quoted message scroll to

This particular issue happens specifically when we've loaded the messages into memory that we want to scroll to (so loading a completely different messageSet is working fine). The offender here is MVCP and scrolling to bottom in particular. I'm pretty certain that there's an upstream bug here, however I did not have a chance to debug it more thoroughly and find the actual root cause. Roughly what goes on is the following:

  • The list mounts, MVCP gets armed
  • We press on a quoted message and begin scrolling to it
  • Mid scroll, MVCP decides something's changed (because of the fact that recycling kicks in and layout gets revalidated) and triggers a pending scroll
  • The scroll is immediately consumed, snapping us back just after the quoted message scroll finishes

I actually had a patch in FlashList which allows us to clear all pending MVCP scrolls and also suspend MVCP from doing anything and it worked like a charm (like an imperative API).

However for now, this will have to do. At the very least, even when the issue happens it should reconcile shortly after and fix its positioning.

Initial scroll to first unread

This issue on the other hand is completely unrelated to MVCP. It's actually related to our automatic scrolling mechanism, which happens on mount and then also whenever autoscrollToRecent actually changes. Namely, if we look into FlashList's implementation we can see that scrollToEnd is actually ultimately wrapped within a setTimeout, likely to try to delay it natively on the JS runtime for timing purposes. However, this also means that if a state update happens really quickly (for example targetedMessage updating) we'll end up making the 2 scrolls race. scrollToEnd typically wins because it's invoked later and also because it invokes the underlying scroll view's ref rather than some abstraction.

We need this custom handling because initialScrollIndex for FlashList is very often not correct at all (and off by some number of offset). This is especially true whenever we scroll between 2 message sets and virtually load new data. I've yet to find why this is but maybe some day.

To prevent this, we expose a new API on the Channel level that allows us to anticipate when we're about to scroll to a targeted message, bypassing the scrollToEnd entirely in favor of having a pending scroll.

These fixes will be ported back to V8 as well.

πŸ›  Implementation details

🎨 UI Changes

iOS
Before After
Android
Before After

πŸ§ͺ Testing

β˜‘οΈ Checklist

  • I have signed the Stream CLA (required)
  • PR targets the develop branch
  • Documentation is updated
  • New code is tested in main example apps, including all possible scenarios
    • SampleApp iOS and Android
    • Expo iOS and Android

@isekovanic isekovanic requested review from oliverlaz and szuperaz May 19, 2026 11:17
Comment thread package/src/components/MessageList/MessageFlashList.tsx
@Stream-SDK-Bot
Copy link
Copy Markdown
Contributor

Stream-SDK-Bot commented May 19, 2026

SDK Size

title develop branch diff status
js_bundle_size 368 KB 368 KB 0 B 🟒

@isekovanic isekovanic merged commit bc8eb82 into develop May 19, 2026
5 checks passed
@isekovanic isekovanic deleted the fix/flash-list-scroll-to-behaviour branch May 19, 2026 12:40
@github-actions github-actions Bot mentioned this pull request May 19, 2026
6 tasks
isekovanic added a commit that referenced this pull request May 19, 2026
## 🎯 Goal

This is a backport of [this
PR](#3602)
towards V8. All details are in its description.

## πŸ›  Implementation details

<!-- Provide a description of the implementation -->

## 🎨 UI Changes

<!-- Add relevant screenshots -->

<details>
<summary>iOS</summary>


<table>
    <thead>
        <tr>
            <td>Before</td>
            <td>After</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <!--<img src="" /> -->
            </td>
            <td>
                <!--<img src="" /> -->
            </td>
        </tr>
    </tbody>
</table>
</details>


<details>
<summary>Android</summary>

<table>
    <thead>
        <tr>
            <td>Before</td>
            <td>After</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <!--<img src="" /> -->
            </td>
            <td>
                <!--<img src="" /> -->
            </td>
        </tr>
    </tbody>
</table>
</details>

## πŸ§ͺ Testing

<!-- Explain how this change can be tested (or why it can't be tested)
-->

## β˜‘οΈ Checklist

- [ ] I have signed the [Stream
CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform)
(required)
- [ ] PR targets the `develop` branch
- [ ] Documentation is updated
- [ ] New code is tested in main example apps, including all possible
scenarios
  - [ ] SampleApp iOS and Android
  - [ ] Expo iOS and Android
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants