|
2 | 2 | import { sticktobottom, type StickToBottomControls } from '$lib/actions/div.svelte';
|
3 | 3 | import Input from '$lib/components/messages/Input.svelte';
|
4 | 4 | import Message from '$lib/components/messages/Message.svelte';
|
5 |
| - import { Thread } from '$lib/services/chat/thread.svelte'; |
6 |
| - import { ChatService, EditorService, type Messages, type Project } from '$lib/services'; |
7 |
| - import { fade } from 'svelte/transition'; |
8 |
| - import { onDestroy } from 'svelte'; |
| 5 | + import { getLayout } from '$lib/context/layout.svelte'; |
9 | 6 | import { toHTMLFromMarkdown } from '$lib/markdown';
|
| 7 | + import { ChatService, EditorService, type Messages, type Project } from '$lib/services'; |
| 8 | + import { Thread } from '$lib/services/chat/thread.svelte'; |
10 | 9 | import type { EditorItem } from '$lib/services/editor/index.svelte';
|
11 |
| - import { getLayout } from '$lib/context/layout.svelte'; |
| 10 | + import { onDestroy } from 'svelte'; |
| 11 | + import type { UIEventHandler } from 'svelte/elements'; |
| 12 | + import { fade } from 'svelte/transition'; |
12 | 13 |
|
13 | 14 | interface Props {
|
14 | 15 | id?: string;
|
|
24 | 25 | let messagesDiv = $state<HTMLDivElement>();
|
25 | 26 | let scrollSmooth = $state(false);
|
26 | 27 |
|
27 |
| - $effect(() => { |
28 |
| - const update = () => (scrollSmooth = true); |
29 |
| - container?.addEventListener('scroll', update); |
30 |
| - return () => { |
31 |
| - container?.removeEventListener('scroll', update); |
32 |
| - scrollSmooth = false; |
33 |
| - }; |
34 |
| - }); |
35 |
| -
|
36 | 28 | $effect(() => {
|
37 | 29 | // Close and recreate thread if id changes
|
38 | 30 | if (thread && thread.threadID !== id) {
|
|
44 | 36 | };
|
45 | 37 | }
|
46 | 38 |
|
| 39 | + scrollSmooth = false; |
| 40 | +
|
47 | 41 | if (id && !thread) {
|
48 | 42 | constructThread();
|
49 | 43 | }
|
|
89 | 83 | thread = newThread;
|
90 | 84 | }
|
91 | 85 |
|
| 86 | + const onScrollEnd: UIEventHandler<HTMLDivElement> = (e) => { |
| 87 | + const isAtBottom = |
| 88 | + e.currentTarget.scrollHeight - e.currentTarget.scrollTop - e.currentTarget.clientHeight <= 0; |
| 89 | +
|
| 90 | + if (isAtBottom) { |
| 91 | + scrollSmooth = true; |
| 92 | + } |
| 93 | + }; |
| 94 | +
|
92 | 95 | function onSendCredentials(id: string, credentials: Record<string, string>) {
|
93 | 96 | thread?.sendCredentials(id, credentials);
|
94 | 97 | }
|
|
103 | 106 | contentEl: messagesDiv,
|
104 | 107 | setControls: (controls) => (scrollControls = controls)
|
105 | 108 | }}
|
| 109 | + onscrollend={onScrollEnd} |
106 | 110 | >
|
107 | 111 | <div
|
108 | 112 | in:fade|global
|
|
0 commit comments