File size: 1,674 Bytes
8aab1a5
98051f8
 
 
ef7aeda
feb88db
98051f8
 
ef7aeda
 
 
8aab1a5
 
949cae0
 
8aab1a5
 
feb88db
 
 
 
 
 
 
4a396c5
feb88db
 
8aab1a5
 
45dbaaf
6a0861b
070d5c7
45dbaaf
 
6a0861b
949cae0
ef7aeda
 
 
 
 
8aab1a5
e02c369
8aab1a5
949cae0
ef7aeda
949cae0
8aab1a5
 
45dbaaf
6a0861b
45dbaaf
 
8aab1a5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<script lang="ts">
	import type { Message } from "$lib/types/Message";
	import { snapScrollToBottom } from "$lib/actions/snapScrollToBottom";
	import ScrollToBottomBtn from "$lib/components/ScrollToBottomBtn.svelte";
	import { createEventDispatcher, tick } from "svelte";

	import ChatIntroduction from "./ChatIntroduction.svelte";
	import ChatMessage from "./ChatMessage.svelte";
	import { randomUUID } from "$lib/utils/randomUuid";

	const dispatch = createEventDispatcher<{ retry: { id: Message["id"]; content: string } }>();

	export let messages: Message[];
	export let loading: boolean;
	export let pending: boolean;

	let chatContainer: HTMLElement;

	async function scrollToBottom() {
		await tick();
		chatContainer.scrollTop = chatContainer.scrollHeight;
	}

	// If last message is from user, scroll to bottom
	$: if (messages[messages.length - 1]?.from === "user") {
		scrollToBottom();
	}
</script>

<div
	class="scrollbar-custom mr-1 h-full overflow-y-auto"
	use:snapScrollToBottom={messages.length ? messages : false}
	bind:this={chatContainer}
>
	<div class="mx-auto flex h-full max-w-3xl flex-col gap-5 px-5 pt-6 sm:gap-8 xl:max-w-4xl">
		{#each messages as message, i}
			<ChatMessage
				loading={loading && i === messages.length - 1}
				{message}
				on:retry={() => dispatch("retry", { id: message.id, content: message.content })}
			/>
		{:else}
			<ChatIntroduction on:message />
		{/each}
		{#if pending}
			<ChatMessage message={{ from: "assistant", content: "", id: randomUUID() }} />
		{/if}
		<div class="h-32 flex-none" />
	</div>
	<ScrollToBottomBtn
		class="bottom-36 right-4 max-md:hidden lg:right-10"
		scrollNode={chatContainer}
	/>
</div>