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

Use CSS scroll anchoring for most chat scroll pinning #704

Merged
merged 2 commits into from
Aug 18, 2023

Conversation

dominiccooney
Copy link
Contributor

@dominiccooney dominiccooney commented Aug 16, 2023

Chat scroll pinning was broken for /search because that adds messages in quick succession and the React effect was only looking at the change in message author.

The general approach was also iffy because we were basically polling the scroll position on updates, but in practice scrolling works best when it is managed asynchronously by the browser.

This takes a different approach:

  • Use CSS scroll anchoring. This takes care of 90% of what we want with pinning the scroll position to the bottom: If you scroll away from the anchor, the scroll position doesn't change, the browser manages all of this for us. We also get better behavior when you resize the panel; the scroll position will stick to the bottom pretty intelligently.
  • Because browsers anchor the scroll position to the top until there's any scrolling, this uses an intersection observer to detect when the content becomes scrollable and force it to scroll. I actually like the behavior without that, but have implemented this for consistency with what we had.
  • When there's a new human message, scroll to the bottom. This means when you commit input in the chat box, we scroll to it.

I've made some subtle UX changes like animating some of the scrolls.

The scroll anchor adds a 5px gutter at the bottom of the content which is the "grippy" region for the scroll. We can avoid that extra space if we want, I took a look at it, it requires a couple of stacking contexts and I thought it wasn't worth it. But we can do it if we want.

Test plan

  1. New Cody chat, ask it to enumerate 50 states in order of accession in a numbered list. The scroll should follow the content as it streams in.
  2. Scroll up, chat to ask it to enumerate the 50 states and their state vegetables. The scroll should jump to the new question when you hit enter; then follow the content.
  3. Scroll up, switch to the files panel, switch back. The scroll position should be where you left it.
  4. While content is streaming in, scroll away from it. As new content appears the scroll should not jump back to the bottom.
  5. Scroll to the bottom, ask to enumerate 50 states etc., while content is streaming in switch to the files panel, wait, then switch back. The scroll position should be where it was when you switched away. That is, not pinned any more.
  6. Do /search foo and the scroll position should keep up with the bottom of the content. (This comes in very fast and I think we should add a heuristic to maybe not do that. But it is better than the behavior today, which quietly drops the new content below the fold.)
  7. Reload the webviews/restart the extension with a long transcript. The restored transcript should be scrolled to the bottom.

@arafatkatze
Copy link
Contributor

@dominiccooney I verified all the 5 steps and they work perfectly for me. I do have a followup question about step 4.
Right now, the search response comes all at once like a blob of text and with the changes introduced it will be much better to scroll down automagically rather than having to do it manually by hands I was wondering if there might be a way to make the process a tab bit smoother? all I could think of was simulate some kind of streaming but that seems too absurd to simulate streaming just to make the UI look nicer. Alternatively once could break down the entire response into chunks and yield those chunks one at a time. I would be curious if you have any other thoughts like some special javascript magic.

❤️ Great work ❤️

@dominiccooney
Copy link
Contributor Author

@arafatkatze,

Right now, the search response comes all at once like a blob of text and with the changes introduced it will be much better to scroll down automagically rather than having to do it manually by hands I was wondering if there might be a way to make the process a tab bit smoother?

Agree that the search results appear too fast. There's a few opportunities to make this better; see #714.

Copy link
Contributor

@toolmantim toolmantim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. This feels much better!

At a glance the animation seemed a bit slow, and I wondered if we should support reduced-motion, but I see it's using the native scrollTo properties, so that's okay speed wise. I assume under the hood it supports reduced motion at the O/S preference level?

The only gotcha I found is that it now scrolls back to the bottom whenever you switch back to the Cody pane from another pane.

e.g. If you have a long chat and scroll up to copy+paste some code, switch to File Explorer, open a file, then re-open the Cody pane… it scrolls down and your code goes out of view. We should retain the scroll position.

Although looking at the code, that could be unrelated to this PR, but now just more obvious and annoying because of the smooth scroll?


.scroll-anchor {
overflow-anchor: auto;
height: 5px; /* this is the grippy region for autoscroll */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was worried this was too small, but after testing, any larger and it would fight with your ability to scroll 👍🏼

@dominiccooney
Copy link
Contributor Author

it now scrolls back to the bottom whenever you switch back to the Cody pane from another pane.

@toolmantim good catch, I think that is a regression in this PR. Will look.

@dominiccooney
Copy link
Contributor Author

I've updated this so it doesn't scroll on switch away and back.

In the edge case that you switch away, then LLM response streams in, then switch back we keep the scroll position so you can read from there.

Chromium turns off scroll animations for prefers-reduced-motion. I'm assuming there's some way to set that in vscode.

@dominiccooney dominiccooney merged commit f057796 into main Aug 18, 2023
10 checks passed
@dominiccooney dominiccooney deleted the dpc/scroll-pin branch August 18, 2023 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants