Timothy Jaeryang Baek 3 周之前
父節點
當前提交
b53ddfbd19

+ 1 - 0
src/lib/components/chat/MessageInput.svelte

@@ -1363,6 +1363,7 @@
 								<div class=" flex justify-between mt-0.5 mb-2.5 mx-0.5 max-w-full" dir="ltr">
 									<div class="ml-1 self-end flex items-center flex-1 max-w-[80%]">
 										<InputMenu
+											bind:files
 											selectedModels={atSelectedModel ? [atSelectedModel.id] : selectedModels}
 											{fileUploadCapableModels}
 											{screenCaptureHandler}

+ 21 - 6
src/lib/components/chat/MessageInput/InputMenu.svelte

@@ -27,7 +27,7 @@
 
 	const i18n = getContext('i18n');
 
-	export let selectedToolIds: string[] = [];
+	export let files = [];
 
 	export let selectedModels: string[] = [];
 	export let fileUploadCapableModels: string[] = [];
@@ -54,13 +54,28 @@
 		return /android|iphone|ipad|ipod|windows phone/i.test(userAgent);
 	};
 
-	function handleFileChange(event) {
+	const handleFileChange = (event) => {
 		const inputFiles = Array.from(event.target?.files);
 		if (inputFiles && inputFiles.length > 0) {
 			console.log(inputFiles);
 			inputFilesHandler(inputFiles);
 		}
-	}
+	};
+
+	const onSelect = (item) => {
+		if (files.find((f) => f.id === item.id)) {
+			return;
+		}
+		files = [
+			...files,
+			{
+				...item,
+				status: 'processed'
+			}
+		];
+
+		show = false;
+	};
 </script>
 
 <!-- Hidden file input used to open the camera on mobile -->
@@ -422,7 +437,7 @@
 						</div>
 					</button>
 
-					<Knowledge knowledge={$knowledge ?? []} />
+					<Knowledge knowledge={$knowledge ?? []} {onSelect} />
 				</div>
 			{:else if tab === 'notes'}
 				<div in:fly={{ x: 20, duration: 150 }}>
@@ -441,7 +456,7 @@
 						</div>
 					</button>
 
-					<Notes />
+					<Notes {onSelect} />
 				</div>
 			{:else if tab === 'chats'}
 				<div in:fly={{ x: 20, duration: 150 }}>
@@ -460,7 +475,7 @@
 						</div>
 					</button>
 
-					<Chats />
+					<Chats {onSelect} />
 				</div>
 			{/if}
 		</DropdownMenu.Content>

+ 30 - 27
src/lib/components/chat/MessageInput/InputMenu/Chats.svelte

@@ -8,6 +8,7 @@
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
 	import Spinner from '$lib/components/common/Spinner.svelte';
 	import Loader from '$lib/components/common/Loader.svelte';
+	import { chatId } from '$lib/stores';
 
 	const i18n = getContext('i18n');
 
@@ -70,33 +71,35 @@
 	{:else}
 		<div class="flex flex-col gap-0.5">
 			{#each items as item, idx}
-				<button
-					class=" px-2.5 py-1 rounded-xl w-full text-left flex justify-between items-center text-sm {idx ===
-					selectedIdx
-						? ' bg-gray-50 dark:bg-gray-800 dark:text-gray-100 selected-command-option-button'
-						: ''}"
-					type="button"
-					on:click={() => {
-						onSelect(item);
-					}}
-					on:mousemove={() => {
-						selectedIdx = idx;
-					}}
-					on:mouseleave={() => {
-						if (idx === 0) {
-							selectedIdx = -1;
-						}
-					}}
-					data-selected={idx === selectedIdx}
-				>
-					<div class="text-black dark:text-gray-100 flex items-center gap-1.5">
-						<Tooltip content={item.description || decodeString(item?.name)} placement="top-start">
-							<div class="line-clamp-1 flex-1">
-								{decodeString(item?.name)}
-							</div>
-						</Tooltip>
-					</div>
-				</button>
+				{#if item?.id !== $chatId}
+					<button
+						class=" px-2.5 py-1 rounded-xl w-full text-left flex justify-between items-center text-sm {idx ===
+						selectedIdx
+							? ' bg-gray-50 dark:bg-gray-800 dark:text-gray-100 selected-command-option-button'
+							: ''}"
+						type="button"
+						on:click={() => {
+							onSelect(item);
+						}}
+						on:mousemove={() => {
+							selectedIdx = idx;
+						}}
+						on:mouseleave={() => {
+							if (idx === 0) {
+								selectedIdx = -1;
+							}
+						}}
+						data-selected={idx === selectedIdx}
+					>
+						<div class="text-black dark:text-gray-100 flex items-center gap-1.5">
+							<Tooltip content={item.description || decodeString(item?.name)} placement="top-start">
+								<div class="line-clamp-1 flex-1">
+									{decodeString(item?.name)}
+								</div>
+							</Tooltip>
+						</div>
+					</button>
+				{/if}
 			{/each}
 
 			{#if !allItemsLoaded}

+ 1 - 1
src/lib/components/chat/Messages/ResponseMessage.svelte

@@ -668,7 +668,7 @@
 												name={file.name}
 												type={file.type}
 												size={file?.size}
-												colorClassName="bg-white dark:bg-gray-850 "
+												small={true}
 											/>
 										{/if}
 									</div>

+ 1 - 1
src/lib/components/chat/Messages/UserMessage.svelte

@@ -203,7 +203,7 @@
 										name={file.name}
 										type={file.type}
 										size={file?.size}
-										colorClassName="bg-white dark:bg-gray-850 "
+										small={true}
 									/>
 								{/if}
 							</div>

+ 17 - 1
src/lib/components/common/FileItem.svelte

@@ -31,6 +31,8 @@
 
 	import DocumentPage from '../icons/DocumentPage.svelte';
 	import Database from '../icons/Database.svelte';
+	import PageEdit from '../icons/PageEdit.svelte';
+	import ChatBubble from '../icons/ChatBubble.svelte';
 	let showModal = false;
 
 	const decodeString = (str: string) => {
@@ -96,11 +98,23 @@
 		<div class="pl-1">
 			{#if !loading}
 				<Tooltip
-					content={type === 'collection' ? $i18n.t('Collection') : $i18n.t('Document')}
+					content={type === 'collection'
+						? $i18n.t('Collection')
+						: type === 'note'
+							? $i18n.t('Note')
+							: type === 'chat'
+								? $i18n.t('Chat')
+								: type === 'file'
+									? $i18n.t('File')
+									: $i18n.t('Document')}
 					placement="top"
 				>
 					{#if type === 'collection'}
 						<Database />
+					{:else if type === 'note'}
+						<PageEdit />
+					{:else if type === 'chat'}
+						<ChatBubble />
 					{:else}
 						<DocumentPage />
 					{/if}
@@ -124,6 +138,8 @@
 			>
 				{#if type === 'file'}
 					{$i18n.t('File')}
+				{:else if type === 'note'}
+					{$i18n.t('Note')}
 				{:else if type === 'doc'}
 					{$i18n.t('Document')}
 				{:else if type === 'collection'}