html-next/smoke-and-mirrors

Shifted scrolling with `renderFromLast` when adding items to `content`

christophersansone opened this issue · 4 comments

Say you are building a chat room using vertical-collection and renderFromLast, where the initial render should scroll to the bottom where the most recent message is displayed. Scrolling up will display older messages, retrieving batches of 100 from the server and appending them to the collection's content. The server requests are triggered when firstReached is triggered.

The expected behavior is that when you scroll to the top, the next batch of records is loaded, and the scroll position has not changed: the newly loaded messages are available above. Currently, however, all 100 messages will appear below the current scroll position.

I suspect that the following is occurring: the scroll position reaches zero, triggering firstReached. When the new records are loaded, the scroll position remains at zero, so the messages are populated downward instead of upward. I think the logic should change so that, when renderFromLast is true, the scroll position should be calculated from the bottom (scrollHeight - scrollTop) instead of from the top.

The problem is exacerbated when the server has several pages to retrieve. Scrolling to the top will trigger firstReached, which fetches the next batch... but because the scroll position is still zero, firstReached will be triggered immediately after rendering the previous batch. So basically, by scrolling to the top once, you eventually wind up at the very beginning of the feed.

This may be an implementation error, could you show me how you've configured it?

@runspired Ahh, you're right! The vertical-collection was configured properly, but I had an issue with sorting and appending vs. prepending. For renderFromLast, the array needs to be prepended, which makes perfect sense. Thanks for the tip!

Hey @christophersansone running into the same issue, how exactly did you solve it?

@AndrewAskins My issue was this. Say you are building a chat room, and you have server-side pagination that returns the messages in batches of 100 records. When you request page 1, it returns the 100 newest messages, sorted by the timestamp in descending order (the first record is the newest message). In the UI, you want the newest messages to appear at the bottom, and scrolling up will show the previous messages in order. When firstReached is triggered, it will request the next page from the server and add the results to the message array.

As far as the vertical-collection is concerned, the array of messages must be sorted in the order in which they should appear in the collection. In this example with renderFromLast, the array needs to be sorted so that the oldest message is first and the newest message is last. Since the server returned the list with the newest message at the top, the list needs to be reversed before sending it to the vertical-collection. Then, when page 2 is received, its data must be added to the array so that the order is still correct: oldest must be first and newest must be last. Therefore, the new items must be prepended to the beginning of the array instead of appended to the end. Once I got the sort order correct across page requests, the scrolling behavior was great.

Hope this helps!