Commit bc8eb82
authored
fix: flash list scroll to behaviour (#3602)
## 🎯 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
<!-- 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 Android1 parent daf6e29 commit bc8eb82
4 files changed
Lines changed: 60 additions & 31 deletions
File tree
- package/src
- components
- Channel
- hooks
- MessageList
- contexts/channelContext
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
567 | 567 | | |
568 | 568 | | |
569 | 569 | | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
570 | 582 | | |
571 | 583 | | |
572 | 584 | | |
| |||
693 | 705 | | |
694 | 706 | | |
695 | 707 | | |
| 708 | + | |
696 | 709 | | |
697 | 710 | | |
698 | 711 | | |
| |||
722 | 735 | | |
723 | 736 | | |
724 | 737 | | |
725 | | - | |
726 | | - | |
727 | | - | |
728 | | - | |
729 | | - | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
730 | 744 | | |
731 | | - | |
| 745 | + | |
732 | 746 | | |
733 | 747 | | |
734 | 748 | | |
| |||
1578 | 1592 | | |
1579 | 1593 | | |
1580 | 1594 | | |
| 1595 | + | |
1581 | 1596 | | |
1582 | 1597 | | |
1583 | 1598 | | |
| |||
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
69 | 70 | | |
70 | 71 | | |
71 | 72 | | |
| 73 | + | |
72 | 74 | | |
73 | 75 | | |
74 | 76 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
| 135 | + | |
135 | 136 | | |
136 | 137 | | |
137 | 138 | | |
| |||
289 | 290 | | |
290 | 291 | | |
291 | 292 | | |
| 293 | + | |
292 | 294 | | |
293 | 295 | | |
294 | 296 | | |
| |||
388 | 390 | | |
389 | 391 | | |
390 | 392 | | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
391 | 397 | | |
392 | 398 | | |
393 | 399 | | |
394 | 400 | | |
395 | | - | |
| 401 | + | |
396 | 402 | | |
397 | 403 | | |
398 | 404 | | |
| |||
408 | 414 | | |
409 | 415 | | |
410 | 416 | | |
411 | | - | |
412 | | - | |
413 | | - | |
414 | | - | |
415 | | - | |
416 | | - | |
417 | | - | |
418 | | - | |
419 | | - | |
420 | | - | |
421 | | - | |
422 | | - | |
423 | 417 | | |
424 | 418 | | |
425 | 419 | | |
| |||
440 | 434 | | |
441 | 435 | | |
442 | 436 | | |
443 | | - | |
444 | | - | |
445 | | - | |
446 | | - | |
447 | | - | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
448 | 459 | | |
449 | | - | |
450 | 460 | | |
451 | 461 | | |
452 | 462 | | |
| |||
456 | 466 | | |
457 | 467 | | |
458 | 468 | | |
459 | | - | |
460 | | - | |
461 | 469 | | |
462 | 470 | | |
463 | 471 | | |
| |||
529 | 537 | | |
530 | 538 | | |
531 | 539 | | |
532 | | - | |
533 | 540 | | |
534 | 541 | | |
535 | 542 | | |
| |||
1064 | 1071 | | |
1065 | 1072 | | |
1066 | 1073 | | |
1067 | | - | |
1068 | | - | |
1069 | | - | |
1070 | 1074 | | |
1071 | 1075 | | |
1072 | 1076 | | |
| |||
1203 | 1207 | | |
1204 | 1208 | | |
1205 | 1209 | | |
| 1210 | + | |
1206 | 1211 | | |
1207 | 1212 | | |
1208 | 1213 | | |
| |||
1246 | 1251 | | |
1247 | 1252 | | |
1248 | 1253 | | |
| 1254 | + | |
1249 | 1255 | | |
1250 | 1256 | | |
1251 | 1257 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
115 | 121 | | |
116 | 122 | | |
117 | 123 | | |
| |||
0 commit comments