|
1 | 1 | <script lang="ts"> |
2 | 2 | import { afterNavigate } from '$app/navigation'; |
3 | | - import { navigating } from '$app/state'; |
4 | 3 | import { ChatForm, ChatMessages, ServerInfo } from '$lib/components'; |
5 | 4 | import { |
6 | 5 | activeMessages, |
7 | 6 | activeConversation, |
8 | 7 | isLoading, |
9 | 8 | sendMessage, |
10 | 9 | stopGeneration, |
11 | | -
|
12 | | - chatStore |
13 | | -
|
14 | 10 | } from '$lib/stores/chat.svelte'; |
15 | 11 | import { onMount } from 'svelte'; |
16 | 12 | import { fly, slide } from 'svelte/transition'; |
17 | 13 |
|
18 | 14 | let { showCenteredEmpty = false } = $props(); |
19 | 15 |
|
| 16 | + let chatScrollContainer: HTMLDivElement | undefined = $state(); |
| 17 | + let scrollInterval: ReturnType<typeof setInterval> | undefined; |
| 18 | + let autoScrollEnabled = $state(true); |
| 19 | +
|
20 | 20 | const isEmpty = $derived( |
21 | 21 | showCenteredEmpty && !activeConversation() && activeMessages().length === 0 && !isLoading() |
22 | 22 | ); |
|
25 | 25 | await sendMessage(message); |
26 | 26 | } |
27 | 27 |
|
28 | | - let chatScrollContainer: HTMLDivElement | undefined = $state(); |
29 | 28 |
|
30 | 29 | function scrollChatToBottom() { |
31 | 30 | chatScrollContainer?.scrollTo({top: chatScrollContainer?.scrollHeight, behavior: 'instant'}) |
|
39 | 38 | setTimeout(scrollChatToBottom, 10); // This is a dirty workaround, need to find racing conditions |
40 | 39 | }) |
41 | 40 |
|
42 | | - let scrollInterval: ReturnType<typeof setInterval> | undefined; |
43 | | - let autoScrollEnabled = $state(true); |
44 | 41 |
|
45 | 42 | function handleScroll() { |
46 | 43 | if (!chatScrollContainer) return; |
47 | 44 | |
48 | 45 | const { scrollTop, scrollHeight, clientHeight } = chatScrollContainer; |
49 | 46 | const distanceFromBottom = scrollHeight - scrollTop - clientHeight; |
50 | 47 | |
51 | | - // Disable auto-scroll when user scrolls up 50px+ from bottom |
52 | 48 | if (distanceFromBottom > 50) { |
53 | 49 | autoScrollEnabled = false; |
54 | | - } |
55 | | - // Re-enable auto-scroll when user reaches bottom |
56 | | - else if (distanceFromBottom <= 1) { |
| 50 | + } else if (distanceFromBottom <= 1) { |
57 | 51 | autoScrollEnabled = true; |
58 | 52 | } |
59 | 53 | } |
60 | 54 |
|
61 | 55 | $effect(() => { |
62 | 56 | if (isLoading() && autoScrollEnabled) { |
63 | 57 | scrollInterval = setInterval(scrollChatToBottom, 100); |
64 | | - } else { |
65 | | - if (scrollInterval) { |
66 | | - clearInterval(scrollInterval); |
67 | | - scrollInterval = undefined; |
68 | | - } |
| 58 | + } else if (scrollInterval) { |
| 59 | + clearInterval(scrollInterval); |
| 60 | + scrollInterval = undefined; |
69 | 61 | } |
70 | 62 | }) |
71 | | -
|
72 | | - $inspect(chatStore.isLoading) |
73 | 63 | </script> |
74 | 64 |
|
75 | 65 | {#if !isEmpty} |
76 | 66 | <div class="flex h-full flex-col overflow-y-auto" bind:this={chatScrollContainer} onscroll={handleScroll}> |
77 | | - <ChatMessages class="mb-36" messages={activeMessages()} isLoading={isLoading()} /> |
| 67 | + <ChatMessages class="mb-36" messages={activeMessages()} /> |
78 | 68 |
|
79 | 69 | <div |
80 | 70 | class="z-999 sticky bottom-0 mx-auto mt-auto max-w-[56rem]" |
|
0 commit comments