Description
Matthew's summary of the problems:
https://matrix.to/#/!maVEfftuKxhnPMcckU:matrix.org/$15500048623049743lQqLW:matrix.org?via=matrix.org&via=t2l.io&via=lant.uk
Related bugs:
- Scroll jumping when back paginating #6265
- Scrolling jumps #2646
- Timeline scroll jumps in e2e due to download link appearing #6755
Update 19/3/2019
Going with a new algorithm, dubbed BACAT (Bottom-Aligned, Clipped-At-Top) scrolling, prototyped here: https://gist.github.com/bwindels/b3a3ba3fa3792f23962d894866fa7b0f
The motivation for the changes is having noticed that setting scrollTop while scrolling tends not work well on at least Chrome on macOs. Also see #528. The approach taken instead manually sets the height of the timeline in 200px increments, with the timeline being aligned to the bottom of the container element. The relatively tiny 200px height comes from the fact that we don't want the user to ever scroll off into pages of whitespace and we have no way of preventing overscroll, so by keeping it to 200px and putting a spinner 100px up from the top of the page, we avoid death by whitespace.
By changing the height of the container, we can compensate for anything that grew below the viewport to maintain what's currently visible in the viewport without jumping. For anything above the viewport growing or shrinking, we don't need to do anything as the timeline is bottom-aligned. We do need to update the height manually. To maintain scroll position after the portion above the viewport changes height, we need to set the scrollTop, as we cannot balance it out with more height changes. We do this 100ms after the user has stopped scrolling, so setting scrollTop has not nasty side-effects.
- prototype of new algo.
- initial impl. in riot
- fix height not updating after unfilling
- fix jump to bottom exception
- fix shrink blocking for typing notifs
- make sure permalinks still work
- fix jump while filling backwards from cached messages on Chrome/macOS
- fix negative margin of right panel resize handle overlapping with scrollbar
- resizing right panel doesn't maintain scroll position
- timeline stops filling in certain conditions
- fix tests
- fix the search UX, which now is also aligned to the bottom which looks weird
- write e2e tests for the scroll panel, as we've removed the app tests for it as they completely broke.
- Matthew might have found another jump on macOs/Chrome.
- update some obsolete comments in ScrollPanel
Obsolete now: Update 5/3/2019:
The resize observer approach doesn't work reliably as it can race with the scroll event, so looks like manually restoring the scroll position from event tile when it can cause a jump is the better option. These things can cause jumps:
- flair (fixed in Prevent flair pushing timeline downwards matrix-org/matrix-react-sdk#2746)
- image thumbnails loading (checked, seems ok. Was already not causing jumps AFAICT, MImageBody gets height based on timeline width and image A/R, also before image is loaded).
- bugs calculating the new scrolloffset when backpaginating (checked, seems ok)
- bugs when thumbnails haven't specified an explicit width & height when sent, so we don't know how much room to leave for them. (check code, seems ok, also most clients send this, so it wouldn't explain why jumps are so common, but I guess we could still artificially send an event like this and test what happens).
- bugs when calculating the size that should be left for images (or videos or other variable-sized table cells)
- when URL previews pop into the timeline (checked, seems ok)
- when encrypted events are decrypted (or are added to the TL)
- when the 'decrypt link' turns into the 'download link' on encrypted attachments (fixed in Scroll investigation changes matrix-org/matrix-react-sdk#2766)
- when encrypted attachment thumbnails are added into the room (the presizing doesn't take the download link, which is actually an iframe, into account, iirc - or it assumes that it doesn't linewrap, which it might)
- when replies pop into the timeline (checked, seems ok)~~