File size: 2,490 Bytes
1b66f8d
5da61b4
 
 
5b779a6
4a6603b
2606dde
 
5b779a6
 
0c4cf03
1b66f8d
 
3aa8136
 
5b779a6
2606dde
 
b7b2c8c
 
6434339
1b66f8d
6434339
1b66f8d
77c7055
0c4cf03
 
77c7055
 
 
 
 
 
9c038aa
77c7055
 
6434339
 
 
 
 
 
 
 
 
 
 
1b66f8d
 
0714764
b2387f6
0c4cf03
0714764
 
5b779a6
3aa8136
6434339
 
 
 
 
 
 
 
 
 
1b66f8d
b7b2c8c
1b66f8d
3aa8136
ad6275a
 
 
0c4cf03
ad6275a
3aa8136
0c4cf03
1b66f8d
0714764
b2387f6
0714764
 
1b66f8d
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<script lang="ts">
	import type { Message } from "$lib/types/Message";
	import { snapScrollToBottom } from "$lib/actions/snapScrollToBottom";
	import ScrollToBottomBtn from "$lib/components/ScrollToBottomBtn.svelte";
	import { tick } from "svelte";
	import { randomUUID } from "$lib/utils/randomUuid";
	import type { Model } from "$lib/types/Model";
	import type { LayoutData } from "../../../routes/$types";
	import ChatIntroduction from "./ChatIntroduction.svelte";
	import ChatMessage from "./ChatMessage.svelte";
	import type { WebSearchMessage } from "$lib/types/WebSearch";

	export let messages: Message[];
	export let loading: boolean;
	export let pending: boolean;
	export let isAuthor: boolean;
	export let currentModel: Model;
	export let settings: LayoutData["settings"];
	export let models: Model[];
	export let readOnly: boolean;
	export let searches: Record<string, WebSearchMessage[]>;

	let webSearchArray: Array<WebSearchMessage[] | undefined> = [];
	let chatContainer: HTMLElement;

	export let webSearchMessages: WebSearchMessage[] = [];

	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();
	}

	$: messages,
		(webSearchArray = messages.map((message, idx) => {
			if (message.webSearchId) {
				return searches[message.webSearchId] ?? [];
			} else if (idx === messages.length - 1) {
				return webSearchMessages;
			} else {
				return [];
			}
		}));
</script>

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