Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading more items in mode: reverse #162

Closed
morajabi opened this issue Aug 16, 2023 · 9 comments
Closed

Loading more items in mode: reverse #162

morajabi opened this issue Aug 16, 2023 · 9 comments

Comments

@morajabi
Copy link

morajabi commented Aug 16, 2023

Is your feature request related to a problem? Please describe.
I use virtua in a chat message list and when scroll hits the top we load more messages. But we lose scroll state and either jump to offset: 0 at top or far bottom.

Describe the solution you'd like
It should have a way to pin scroll to top most item in the viewport so user doesn't feel any jumps.

Describe alternatives you've considered
Using a useLayoutEffect to scroll to that item manually works but is janky and not smooth.

Additional context
In general, mode: reverse scroll positioning can be improved, eg. to load at the bottom initially and not top, keep at bottom when item sizes change, etc. We can implement most of these given flexible APIs. What's important is user shouldn't feel any frames in a between state that preserves like a jump.

@inokawa
Copy link
Owner

inokawa commented Aug 17, 2023

Hi, I'm developing a prop in #147 for similar purpose, which will switch keeping position from bottom not top when items are shifted/unshifted.

It's almost working but the api isn't finalized yet. And it still cause jump in edge case.

As you pointed out, positioning can be improved in reverse scrolling but I'm bit wary to implement them because each people may have different use cases.

reverse-jump.mov

@morajabi
Copy link
Author

This is fantastic. My issues that I can't workaround are 2:

  1. bi-directional loading more (which this PR solves)
  2. jump when item size changes (imagine in Slack when you add a reaction to a message, it should still stay at bottom, but my scrollToBottom that uses scrollToOffset is one frame late for some reason)

@inokawa
Copy link
Owner

inokawa commented Aug 17, 2023

If you just want to stay at bottom when items added, scrollToIndex with end align may work:

const ref = useRef<VListHandle>(null).
useEffect(() => {
  ref?.current.scrollToIndex(elements.length - 1, "end");
}, [elements.length]

return <VList ref={ref}>{elements}</VList>

useEffect(() => {
if (!ref.current) return;
ref.current.scrollToIndex(items.length - 1, "end");
}, [items.length]);

Sticking to bottom automatically might be better, and it is actually implemented as jump handling for scrollToIndex , but it's not exposed as props yet.

@morajabi
Copy link
Author

morajabi commented Aug 17, 2023

@inokawa we are doing a release later today with virtua for our message list (for https://noor.to) is there anyway I can make a PR or for you to expose this as an option? we're loving virtua so far.
Going to try align: "end" right now. If it works, I'll let you know!

@inokawa
Copy link
Owner

inokawa commented Aug 17, 2023

That's sounds nice!

The stick to bottom during imperative scrolling logic is here. PRs are welcome but I doubt it would not work for other purpose as it is, because it's designed to work with imperative scrolling and the jump compensation in this lib is very timing dependent.

virtua/src/core/store.ts

Lines 213 to 227 in 691183a

if (scrollOffset === 0) {
// Do nothing to stick to the start
} else if (
scrollOffset >
getScrollOffsetMax() - SUBPIXEL_THRESHOLD
) {
// Keep end to stick to the end
diff = calculateJump(cache, updated);
} else {
// Keep start at mid
diff = calculateJump(
cache,
updated.filter(([index]) => index < startIndex)
);
}

@inokawa
Copy link
Owner

inokawa commented Aug 23, 2023

Finally, #147 is released as shift prop in 0.8.0.
A known issue will be tracked in #163 .

@Bessonov
Copy link

Hey @inokawa , great! Is there a way to track "Reverse scroll in iOS Safari"?

@inokawa
Copy link
Owner

inokawa commented Aug 23, 2023

Hi @Bessonov , the issue in iOS Safari will be processed in #43 .

@inokawa
Copy link
Owner

inokawa commented Oct 12, 2023

For a note, I changed the compensation logic described in #162 (comment) to work in more situations in 0.13.0.
I close this issue because of inactivity, but feel free to reopen it if you have any problems.

@inokawa inokawa closed this as completed Oct 12, 2023
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

No branches or pull requests

3 participants