Skip to content

Commit 3e3d127

Browse files
authored
codegen-scrolling-fixes (#10187)
* remove extra effect fro scroll to bottom Since events is derived from selectedBranch, changing the branch will cause events to update, triggering the first effect anyway. The second effect becomes redundant and causes double scrolling. * feat(chat): add scroll detection and conditional scroll-to-bottom button
1 parent 4332fba commit 3e3d127

File tree

2 files changed

+29
-21
lines changed

2 files changed

+29
-21
lines changed

apps/desktop/src/components/codegen/CodegenChatLayout.svelte

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import ConfigurableScrollableContainer from '$components/ConfigurableScrollableContainer.svelte';
33
import { Button } from '@gitbutler/ui';
44
import { focusable } from '@gitbutler/ui/focus/focusable';
5+
import { fade } from 'svelte/transition';
56
import type { Snippet } from 'svelte';
67
78
type Props = {
@@ -17,13 +18,21 @@
1718
$props();
1819
1920
let scrollableContainer: ConfigurableScrollableContainer;
21+
let scrollDistanceFromBottom = $state(0);
2022
2123
// Export method to scroll to bottom
2224
export function scrollToBottom() {
23-
if (scrollableContainer?.scrollToBottom) {
24-
scrollableContainer.scrollToBottom();
25-
}
25+
scrollableContainer?.scrollToBottom();
26+
}
27+
28+
// Calculate distance from bottom when scrolling
29+
function handleScroll(event: Event) {
30+
const { scrollTop, scrollHeight, clientHeight } = event.target as HTMLElement;
31+
scrollDistanceFromBottom = scrollHeight - scrollTop - clientHeight;
2632
}
33+
34+
// Show button only when user has scrolled more than 1000px from bottom
35+
const showScrollButton = $derived(scrollDistanceFromBottom > 600);
2736
</script>
2837

2938
<div class="chat" use:focusable={{ vertical: true }}>
@@ -43,20 +52,26 @@
4352
</div>
4453

4554
<div class="chat-container">
46-
<ConfigurableScrollableContainer bind:this={scrollableContainer} childrenWrapHeight="100%">
55+
<ConfigurableScrollableContainer
56+
bind:this={scrollableContainer}
57+
childrenWrapHeight="100%"
58+
onscroll={handleScroll}
59+
>
4760
<div class="chat-messages">
4861
{@render messages()}
4962
</div>
5063
</ConfigurableScrollableContainer>
5164

52-
<div class="chat-scroll-to-bottom">
53-
<Button
54-
kind="outline"
55-
icon="arrow-down"
56-
tooltip="Scroll to bottom"
57-
onclick={scrollToBottom}
58-
/>
59-
</div>
65+
{#if showScrollButton}
66+
<div class="chat-scroll-to-bottom" transition:fade={{ duration: 150 }}>
67+
<Button
68+
kind="outline"
69+
icon="arrow-down"
70+
tooltip="Scroll to bottom"
71+
onclick={scrollToBottom}
72+
/>
73+
</div>
74+
{/if}
6075
</div>
6176

6277
<div class="chat-footer" use:focusable>
@@ -119,7 +134,7 @@
119134
transform var(--transition-medium);
120135
121136
&:hover {
122-
transform: translateY(-2px);
137+
transform: scale(1.05) translateY(-2px);
123138
box-shadow: var(--fx-shadow-s);
124139
}
125140
}

apps/desktop/src/components/codegen/CodegenPage.svelte

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -356,21 +356,14 @@
356356
let createBranchModal = $state<CreateBranchModal>();
357357
let chatLayout = $state<CodegenChatLayout>();
358358
359-
// Auto-scroll when new messages are added
359+
// Auto-scroll when new messages are added or branch changes
360360
$effect(() => {
361361
if (events?.current.data) {
362362
setTimeout(() => {
363363
chatLayout?.scrollToBottom();
364364
}, 50);
365365
}
366366
});
367-
368-
$effect(() => {
369-
void selectedBranch;
370-
setTimeout(() => {
371-
chatLayout?.scrollToBottom();
372-
}, 50);
373-
});
374367
</script>
375368

376369
<div class="page">

0 commit comments

Comments
 (0)