forked from open-webui/open-webui
		
	Merge pull request #404 from ollama-webui/incognito
feat: chat history incognito mode
This commit is contained in:
		
						commit
						f1bda3f9c8
					
				
					 4 changed files with 396 additions and 264 deletions
				
			
		|  | @ -99,6 +99,7 @@ | ||||||
| 	let titleAutoGenerateModel = ''; | 	let titleAutoGenerateModel = ''; | ||||||
| 
 | 
 | ||||||
| 	// Chats | 	// Chats | ||||||
|  | 	let saveChatHistory = true; | ||||||
| 	let importFiles; | 	let importFiles; | ||||||
| 	let showDeleteConfirm = false; | 	let showDeleteConfirm = false; | ||||||
| 
 | 
 | ||||||
|  | @ -235,8 +236,14 @@ | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const toggleAuthHeader = async () => { | 	const toggleSaveChatHistory = async () => { | ||||||
| 		authEnabled = !authEnabled; | 		saveChatHistory = !saveChatHistory; | ||||||
|  | 		console.log(saveChatHistory); | ||||||
|  | 
 | ||||||
|  | 		if (saveChatHistory === false) { | ||||||
|  | 			await goto('/'); | ||||||
|  | 		} | ||||||
|  | 		saveSettings({ saveChatHistory: saveChatHistory }); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const pullModelHandler = async () => { | 	const pullModelHandler = async () => { | ||||||
|  | @ -576,6 +583,8 @@ | ||||||
| 		titleAutoGenerateModel = settings.titleAutoGenerateModel ?? ''; | 		titleAutoGenerateModel = settings.titleAutoGenerateModel ?? ''; | ||||||
| 		gravatarEmail = settings.gravatarEmail ?? ''; | 		gravatarEmail = settings.gravatarEmail ?? ''; | ||||||
| 
 | 
 | ||||||
|  | 		saveChatHistory = settings.saveChatHistory ?? true; | ||||||
|  | 
 | ||||||
| 		authEnabled = settings.authHeader !== undefined ? true : false; | 		authEnabled = settings.authHeader !== undefined ? true : false; | ||||||
| 		if (authEnabled) { | 		if (authEnabled) { | ||||||
| 			authType = settings.authHeader.split(' ')[0]; | 			authType = settings.authHeader.split(' ')[0]; | ||||||
|  | @ -1616,6 +1625,64 @@ | ||||||
| 				{:else if selectedTab === 'chats'} | 				{:else if selectedTab === 'chats'} | ||||||
| 					<div class="flex flex-col h-full justify-between space-y-3 text-sm"> | 					<div class="flex flex-col h-full justify-between space-y-3 text-sm"> | ||||||
| 						<div class=" space-y-2"> | 						<div class=" space-y-2"> | ||||||
|  | 							<div | ||||||
|  | 								class="flex flex-col justify-between rounded-md items-center py-2 px-3.5 w-full transition" | ||||||
|  | 							> | ||||||
|  | 								<div class="flex w-full justify-between"> | ||||||
|  | 									<div class=" self-center text-sm font-medium">Chat History</div> | ||||||
|  | 
 | ||||||
|  | 									<button | ||||||
|  | 										class="p-1 px-3 text-xs flex rounded transition" | ||||||
|  | 										type="button" | ||||||
|  | 										on:click={() => { | ||||||
|  | 											toggleSaveChatHistory(); | ||||||
|  | 										}} | ||||||
|  | 									> | ||||||
|  | 										{#if saveChatHistory === true} | ||||||
|  | 											<svg | ||||||
|  | 												xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 												viewBox="0 0 16 16" | ||||||
|  | 												fill="currentColor" | ||||||
|  | 												class="w-4 h-4" | ||||||
|  | 											> | ||||||
|  | 												<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" /> | ||||||
|  | 												<path | ||||||
|  | 													fill-rule="evenodd" | ||||||
|  | 													d="M1.38 8.28a.87.87 0 0 1 0-.566 7.003 7.003 0 0 1 13.238.006.87.87 0 0 1 0 .566A7.003 7.003 0 0 1 1.379 8.28ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" | ||||||
|  | 													clip-rule="evenodd" | ||||||
|  | 												/> | ||||||
|  | 											</svg> | ||||||
|  | 
 | ||||||
|  | 											<span class="ml-2 self-center"> On </span> | ||||||
|  | 										{:else} | ||||||
|  | 											<svg | ||||||
|  | 												xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 												viewBox="0 0 16 16" | ||||||
|  | 												fill="currentColor" | ||||||
|  | 												class="w-4 h-4" | ||||||
|  | 											> | ||||||
|  | 												<path | ||||||
|  | 													fill-rule="evenodd" | ||||||
|  | 													d="M3.28 2.22a.75.75 0 0 0-1.06 1.06l10.5 10.5a.75.75 0 1 0 1.06-1.06l-1.322-1.323a7.012 7.012 0 0 0 2.16-3.11.87.87 0 0 0 0-.567A7.003 7.003 0 0 0 4.82 3.76l-1.54-1.54Zm3.196 3.195 1.135 1.136A1.502 1.502 0 0 1 9.45 8.389l1.136 1.135a3 3 0 0 0-4.109-4.109Z" | ||||||
|  | 													clip-rule="evenodd" | ||||||
|  | 												/> | ||||||
|  | 												<path | ||||||
|  | 													d="m7.812 10.994 1.816 1.816A7.003 7.003 0 0 1 1.38 8.28a.87.87 0 0 1 0-.566 6.985 6.985 0 0 1 1.113-2.039l2.513 2.513a3 3 0 0 0 2.806 2.806Z" | ||||||
|  | 												/> | ||||||
|  | 											</svg> | ||||||
|  | 
 | ||||||
|  | 											<span class="ml-2 self-center">Off</span> | ||||||
|  | 										{/if} | ||||||
|  | 									</button> | ||||||
|  | 								</div> | ||||||
|  | 
 | ||||||
|  | 								<div class="text-xs text-left w-full font-medium mt-0.5"> | ||||||
|  | 									This setting does not sync across browsers or devices. | ||||||
|  | 								</div> | ||||||
|  | 							</div> | ||||||
|  | 
 | ||||||
|  | 							<hr class=" dark:border-gray-700" /> | ||||||
|  | 
 | ||||||
| 							<div class="flex flex-col"> | 							<div class="flex flex-col"> | ||||||
| 								<input | 								<input | ||||||
| 									id="chat-import-input" | 									id="chat-import-input" | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ | ||||||
| 
 | 
 | ||||||
| 	import { goto, invalidateAll } from '$app/navigation'; | 	import { goto, invalidateAll } from '$app/navigation'; | ||||||
| 	import { page } from '$app/stores'; | 	import { page } from '$app/stores'; | ||||||
| 	import { user, chats, showSettings, chatId } from '$lib/stores'; | 	import { user, chats, settings, showSettings, chatId } from '$lib/stores'; | ||||||
| 	import { onMount } from 'svelte'; | 	import { onMount } from 'svelte'; | ||||||
| 	import { deleteChatById, getChatList, updateChatById } from '$lib/apis/chats'; | 	import { deleteChatById, getChatList, updateChatById } from '$lib/apis/chats'; | ||||||
| 
 | 
 | ||||||
|  | @ -49,6 +49,12 @@ | ||||||
| 		await deleteChatById(localStorage.token, id); | 		await deleteChatById(localStorage.token, id); | ||||||
| 		await chats.set(await getChatList(localStorage.token)); | 		await chats.set(await getChatList(localStorage.token)); | ||||||
| 	}; | 	}; | ||||||
|  | 
 | ||||||
|  | 	const saveSettings = async (updated) => { | ||||||
|  | 		await settings.set({ ...$settings, ...updated }); | ||||||
|  | 		localStorage.setItem('settings', JSON.stringify($settings)); | ||||||
|  | 		location.href = '/'; | ||||||
|  | 	}; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <div | <div | ||||||
|  | @ -159,253 +165,296 @@ | ||||||
| 			</div> | 			</div> | ||||||
| 		{/if} | 		{/if} | ||||||
| 
 | 
 | ||||||
| 		<div class="px-2.5 mt-1 mb-2 flex justify-center space-x-2"> | 		<div class="relative flex flex-col flex-1 overflow-y-auto"> | ||||||
| 			<div class="flex w-full" id="chat-search"> | 			{#if !($settings.saveChatHistory ?? true)} | ||||||
| 				<div class="self-center pl-3 py-2 rounded-l bg-gray-950"> | 				<div class="absolute z-40 w-full h-full bg-black/90 flex justify-center"> | ||||||
| 					<svg | 					<div class=" text-left px-5 py-2"> | ||||||
| 						xmlns="http://www.w3.org/2000/svg" | 						<div class=" font-medium">Chat History is off for this browser.</div> | ||||||
| 						viewBox="0 0 20 20" | 						<div class="text-xs mt-2"> | ||||||
| 						fill="currentColor" | 							When history is turned off, new chats on this browser won't appear in your history on | ||||||
| 						class="w-4 h-4" | 							any of your devices. <span class=" font-semibold" | ||||||
| 					> | 								>This setting does not sync across browsers or devices.</span | ||||||
| 						<path | 							> | ||||||
| 							fill-rule="evenodd" | 						</div> | ||||||
| 							d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" |  | ||||||
| 							clip-rule="evenodd" |  | ||||||
| 						/> |  | ||||||
| 					</svg> |  | ||||||
| 				</div> |  | ||||||
| 
 | 
 | ||||||
| 				<input | 						<div class="mt-3"> | ||||||
| 					class="w-full rounded-r py-1.5 pl-2.5 pr-4 text-sm text-gray-300 bg-gray-950 outline-none" | 							<button | ||||||
| 					placeholder="Search" | 								class="flex justify-center items-center space-x-1.5 px-3 py-2.5 rounded-lg text-xs bg-gray-200 hover:bg-gray-300 transition text-gray-800 font-medium w-full" | ||||||
| 					bind:value={search} | 								type="button" | ||||||
| 				/> | 								on:click={() => { | ||||||
| 
 | 									saveSettings({ | ||||||
| 				<!-- <div class="self-center pr-3 py-2  bg-gray-900"> | 										saveChatHistory: true | ||||||
| 					<svg | 									}); | ||||||
| 						xmlns="http://www.w3.org/2000/svg" | 								}} | ||||||
| 						fill="none" | 							> | ||||||
| 						viewBox="0 0 24 24" |  | ||||||
| 						stroke-width="1.5" |  | ||||||
| 						stroke="currentColor" |  | ||||||
| 						class="w-4 h-4" |  | ||||||
| 					> |  | ||||||
| 						<path |  | ||||||
| 							stroke-linecap="round" |  | ||||||
| 							stroke-linejoin="round" |  | ||||||
| 							d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 01-.659 1.591l-5.432 5.432a2.25 2.25 0 00-.659 1.591v2.927a2.25 2.25 0 01-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 00-.659-1.591L3.659 7.409A2.25 2.25 0 013 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0112 3z" |  | ||||||
| 						/> |  | ||||||
| 					</svg> |  | ||||||
| 				</div> --> |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 
 |  | ||||||
| 		<div class="pl-2.5 my-2 flex-1 flex flex-col space-y-1 overflow-y-auto"> |  | ||||||
| 			{#each $chats.filter((chat) => { |  | ||||||
| 				if (search === '') { |  | ||||||
| 					return true; |  | ||||||
| 				} else { |  | ||||||
| 					let title = chat.title.toLowerCase(); |  | ||||||
| 
 |  | ||||||
| 					if (title.includes(search)) { |  | ||||||
| 						return true; |  | ||||||
| 					} else { |  | ||||||
| 						return false; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			}) as chat, i} |  | ||||||
| 				<div class=" w-full pr-2 relative"> |  | ||||||
| 					<button |  | ||||||
| 						class=" w-full flex justify-between rounded-md px-3 py-2 hover:bg-gray-900 {chat.id === |  | ||||||
| 						$chatId |  | ||||||
| 							? 'bg-gray-900' |  | ||||||
| 							: ''} transition whitespace-nowrap text-ellipsis" |  | ||||||
| 						on:click={() => { |  | ||||||
| 							// goto(`/c/${chat.id}`); |  | ||||||
| 							if (chat.id !== chatTitleEditId) { |  | ||||||
| 								chatTitleEditId = null; |  | ||||||
| 								chatTitle = ''; |  | ||||||
| 							} |  | ||||||
| 
 |  | ||||||
| 							if (chat.id !== $chatId) { |  | ||||||
| 								loadChat(chat.id); |  | ||||||
| 							} |  | ||||||
| 						}} |  | ||||||
| 					> |  | ||||||
| 						<div class=" flex self-center flex-1"> |  | ||||||
| 							<div class=" self-center mr-3"> |  | ||||||
| 								<svg | 								<svg | ||||||
| 									xmlns="http://www.w3.org/2000/svg" | 									xmlns="http://www.w3.org/2000/svg" | ||||||
| 									fill="none" | 									viewBox="0 0 16 16" | ||||||
| 									viewBox="0 0 24 24" | 									fill="currentColor" | ||||||
| 									stroke-width="1.5" | 									class="w-3 h-3" | ||||||
| 									stroke="currentColor" |  | ||||||
| 									class="w-4 h-4" |  | ||||||
| 								> | 								> | ||||||
| 									<path | 									<path | ||||||
| 										stroke-linecap="round" | 										fill-rule="evenodd" | ||||||
| 										stroke-linejoin="round" | 										d="M8 1a.75.75 0 0 1 .75.75v6.5a.75.75 0 0 1-1.5 0v-6.5A.75.75 0 0 1 8 1ZM4.11 3.05a.75.75 0 0 1 0 1.06 5.5 5.5 0 1 0 7.78 0 .75.75 0 0 1 1.06-1.06 7 7 0 1 1-9.9 0 .75.75 0 0 1 1.06 0Z" | ||||||
| 										d="M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.076-4.076a1.526 1.526 0 011.037-.443 48.282 48.282 0 005.68-.494c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z" | 										clip-rule="evenodd" | ||||||
| 									/> | 									/> | ||||||
| 								</svg> | 								</svg> | ||||||
|  | 
 | ||||||
|  | 								<div>Enable Chat History</div> | ||||||
|  | 							</button> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 				</div> | ||||||
|  | 			{/if} | ||||||
|  | 
 | ||||||
|  | 			<div class="px-2.5 mt-1 mb-2 flex justify-center space-x-2"> | ||||||
|  | 				<div class="flex w-full" id="chat-search"> | ||||||
|  | 					<div class="self-center pl-3 py-2 rounded-l bg-gray-950"> | ||||||
|  | 						<svg | ||||||
|  | 							xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 							viewBox="0 0 20 20" | ||||||
|  | 							fill="currentColor" | ||||||
|  | 							class="w-4 h-4" | ||||||
|  | 						> | ||||||
|  | 							<path | ||||||
|  | 								fill-rule="evenodd" | ||||||
|  | 								d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" | ||||||
|  | 								clip-rule="evenodd" | ||||||
|  | 							/> | ||||||
|  | 						</svg> | ||||||
|  | 					</div> | ||||||
|  | 
 | ||||||
|  | 					<input | ||||||
|  | 						class="w-full rounded-r py-1.5 pl-2.5 pr-4 text-sm text-gray-300 bg-gray-950 outline-none" | ||||||
|  | 						placeholder="Search" | ||||||
|  | 						bind:value={search} | ||||||
|  | 					/> | ||||||
|  | 
 | ||||||
|  | 					<!-- <div class="self-center pr-3 py-2  bg-gray-900"> | ||||||
|  | 						<svg | ||||||
|  | 							xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 							fill="none" | ||||||
|  | 							viewBox="0 0 24 24" | ||||||
|  | 							stroke-width="1.5" | ||||||
|  | 							stroke="currentColor" | ||||||
|  | 							class="w-4 h-4" | ||||||
|  | 						> | ||||||
|  | 							<path | ||||||
|  | 								stroke-linecap="round" | ||||||
|  | 								stroke-linejoin="round" | ||||||
|  | 								d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 01-.659 1.591l-5.432 5.432a2.25 2.25 0 00-.659 1.591v2.927a2.25 2.25 0 01-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 00-.659-1.591L3.659 7.409A2.25 2.25 0 013 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0112 3z" | ||||||
|  | 							/> | ||||||
|  | 						</svg> | ||||||
|  | 					</div> --> | ||||||
|  | 				</div> | ||||||
|  | 			</div> | ||||||
|  | 
 | ||||||
|  | 			<div class="pl-2.5 my-2 flex-1 flex flex-col space-y-1 overflow-y-auto"> | ||||||
|  | 				{#each $chats.filter((chat) => { | ||||||
|  | 					if (search === '') { | ||||||
|  | 						return true; | ||||||
|  | 					} else { | ||||||
|  | 						let title = chat.title.toLowerCase(); | ||||||
|  | 
 | ||||||
|  | 						if (title.includes(search)) { | ||||||
|  | 							return true; | ||||||
|  | 						} else { | ||||||
|  | 							return false; | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				}) as chat, i} | ||||||
|  | 					<div class=" w-full pr-2 relative"> | ||||||
|  | 						<button | ||||||
|  | 							class=" w-full flex justify-between rounded-md px-3 py-2 hover:bg-gray-900 {chat.id === | ||||||
|  | 							$chatId | ||||||
|  | 								? 'bg-gray-900' | ||||||
|  | 								: ''} transition whitespace-nowrap text-ellipsis" | ||||||
|  | 							on:click={() => { | ||||||
|  | 								// goto(`/c/${chat.id}`); | ||||||
|  | 								if (chat.id !== chatTitleEditId) { | ||||||
|  | 									chatTitleEditId = null; | ||||||
|  | 									chatTitle = ''; | ||||||
|  | 								} | ||||||
|  | 
 | ||||||
|  | 								if (chat.id !== $chatId) { | ||||||
|  | 									loadChat(chat.id); | ||||||
|  | 								} | ||||||
|  | 							}} | ||||||
|  | 						> | ||||||
|  | 							<div class=" flex self-center flex-1"> | ||||||
|  | 								<div class=" self-center mr-3"> | ||||||
|  | 									<svg | ||||||
|  | 										xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 										fill="none" | ||||||
|  | 										viewBox="0 0 24 24" | ||||||
|  | 										stroke-width="1.5" | ||||||
|  | 										stroke="currentColor" | ||||||
|  | 										class="w-4 h-4" | ||||||
|  | 									> | ||||||
|  | 										<path | ||||||
|  | 											stroke-linecap="round" | ||||||
|  | 											stroke-linejoin="round" | ||||||
|  | 											d="M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.076-4.076a1.526 1.526 0 011.037-.443 48.282 48.282 0 005.68-.494c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z" | ||||||
|  | 										/> | ||||||
|  | 									</svg> | ||||||
|  | 								</div> | ||||||
|  | 								<div | ||||||
|  | 									class=" text-left self-center overflow-hidden {chat.id === $chatId | ||||||
|  | 										? 'w-[120px]' | ||||||
|  | 										: 'w-[180px]'} " | ||||||
|  | 								> | ||||||
|  | 									{#if chatTitleEditId === chat.id} | ||||||
|  | 										<input bind:value={chatTitle} class=" bg-transparent w-full" /> | ||||||
|  | 									{:else} | ||||||
|  | 										{chat.title} | ||||||
|  | 									{/if} | ||||||
|  | 								</div> | ||||||
| 							</div> | 							</div> | ||||||
| 							<div | 						</button> | ||||||
| 								class=" text-left self-center overflow-hidden {chat.id === $chatId | 
 | ||||||
| 									? 'w-[120px]' | 						{#if chat.id === $chatId} | ||||||
| 									: 'w-[180px]'} " | 							<div class=" absolute right-[22px] top-[10px]"> | ||||||
| 							> |  | ||||||
| 								{#if chatTitleEditId === chat.id} | 								{#if chatTitleEditId === chat.id} | ||||||
| 									<input bind:value={chatTitle} class=" bg-transparent w-full" /> | 									<div class="flex self-center space-x-1.5"> | ||||||
|  | 										<button | ||||||
|  | 											class=" self-center hover:text-white transition" | ||||||
|  | 											on:click={() => { | ||||||
|  | 												editChatTitle(chat.id, chatTitle); | ||||||
|  | 												chatTitleEditId = null; | ||||||
|  | 												chatTitle = ''; | ||||||
|  | 											}} | ||||||
|  | 										> | ||||||
|  | 											<svg | ||||||
|  | 												xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 												viewBox="0 0 20 20" | ||||||
|  | 												fill="currentColor" | ||||||
|  | 												class="w-4 h-4" | ||||||
|  | 											> | ||||||
|  | 												<path | ||||||
|  | 													fill-rule="evenodd" | ||||||
|  | 													d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" | ||||||
|  | 													clip-rule="evenodd" | ||||||
|  | 												/> | ||||||
|  | 											</svg> | ||||||
|  | 										</button> | ||||||
|  | 										<button | ||||||
|  | 											class=" self-center hover:text-white transition" | ||||||
|  | 											on:click={() => { | ||||||
|  | 												chatTitleEditId = null; | ||||||
|  | 												chatTitle = ''; | ||||||
|  | 											}} | ||||||
|  | 										> | ||||||
|  | 											<svg | ||||||
|  | 												xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 												viewBox="0 0 20 20" | ||||||
|  | 												fill="currentColor" | ||||||
|  | 												class="w-4 h-4" | ||||||
|  | 											> | ||||||
|  | 												<path | ||||||
|  | 													d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" | ||||||
|  | 												/> | ||||||
|  | 											</svg> | ||||||
|  | 										</button> | ||||||
|  | 									</div> | ||||||
|  | 								{:else if chatDeleteId === chat.id} | ||||||
|  | 									<div class="flex self-center space-x-1.5"> | ||||||
|  | 										<button | ||||||
|  | 											class=" self-center hover:text-white transition" | ||||||
|  | 											on:click={() => { | ||||||
|  | 												deleteChat(chat.id); | ||||||
|  | 											}} | ||||||
|  | 										> | ||||||
|  | 											<svg | ||||||
|  | 												xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 												viewBox="0 0 20 20" | ||||||
|  | 												fill="currentColor" | ||||||
|  | 												class="w-4 h-4" | ||||||
|  | 											> | ||||||
|  | 												<path | ||||||
|  | 													fill-rule="evenodd" | ||||||
|  | 													d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" | ||||||
|  | 													clip-rule="evenodd" | ||||||
|  | 												/> | ||||||
|  | 											</svg> | ||||||
|  | 										</button> | ||||||
|  | 										<button | ||||||
|  | 											class=" self-center hover:text-white transition" | ||||||
|  | 											on:click={() => { | ||||||
|  | 												chatDeleteId = null; | ||||||
|  | 											}} | ||||||
|  | 										> | ||||||
|  | 											<svg | ||||||
|  | 												xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 												viewBox="0 0 20 20" | ||||||
|  | 												fill="currentColor" | ||||||
|  | 												class="w-4 h-4" | ||||||
|  | 											> | ||||||
|  | 												<path | ||||||
|  | 													d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" | ||||||
|  | 												/> | ||||||
|  | 											</svg> | ||||||
|  | 										</button> | ||||||
|  | 									</div> | ||||||
| 								{:else} | 								{:else} | ||||||
| 									{chat.title} | 									<div class="flex self-center space-x-1.5"> | ||||||
|  | 										<button | ||||||
|  | 											id="delete-chat-button" | ||||||
|  | 											class=" hidden" | ||||||
|  | 											on:click={() => { | ||||||
|  | 												deleteChat(chat.id); | ||||||
|  | 											}} | ||||||
|  | 										/> | ||||||
|  | 										<button | ||||||
|  | 											class=" self-center hover:text-white transition" | ||||||
|  | 											on:click={() => { | ||||||
|  | 												chatTitle = chat.title; | ||||||
|  | 												chatTitleEditId = chat.id; | ||||||
|  | 												// editChatTitle(chat.id, 'a'); | ||||||
|  | 											}} | ||||||
|  | 										> | ||||||
|  | 											<svg | ||||||
|  | 												xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 												fill="none" | ||||||
|  | 												viewBox="0 0 24 24" | ||||||
|  | 												stroke-width="1.5" | ||||||
|  | 												stroke="currentColor" | ||||||
|  | 												class="w-4 h-4" | ||||||
|  | 											> | ||||||
|  | 												<path | ||||||
|  | 													stroke-linecap="round" | ||||||
|  | 													stroke-linejoin="round" | ||||||
|  | 													d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125" | ||||||
|  | 												/> | ||||||
|  | 											</svg> | ||||||
|  | 										</button> | ||||||
|  | 										<button | ||||||
|  | 											class=" self-center hover:text-white transition" | ||||||
|  | 											on:click={() => { | ||||||
|  | 												chatDeleteId = chat.id; | ||||||
|  | 											}} | ||||||
|  | 										> | ||||||
|  | 											<svg | ||||||
|  | 												xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 												fill="none" | ||||||
|  | 												viewBox="0 0 24 24" | ||||||
|  | 												stroke-width="1.5" | ||||||
|  | 												stroke="currentColor" | ||||||
|  | 												class="w-4 h-4" | ||||||
|  | 											> | ||||||
|  | 												<path | ||||||
|  | 													stroke-linecap="round" | ||||||
|  | 													stroke-linejoin="round" | ||||||
|  | 													d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" | ||||||
|  | 												/> | ||||||
|  | 											</svg> | ||||||
|  | 										</button> | ||||||
|  | 									</div> | ||||||
| 								{/if} | 								{/if} | ||||||
| 							</div> | 							</div> | ||||||
| 						</div> | 						{/if} | ||||||
| 					</button> | 					</div> | ||||||
| 
 | 				{/each} | ||||||
| 					{#if chat.id === $chatId} | 			</div> | ||||||
| 						<div class=" absolute right-[22px] top-[10px]"> |  | ||||||
| 							{#if chatTitleEditId === chat.id} |  | ||||||
| 								<div class="flex self-center space-x-1.5"> |  | ||||||
| 									<button |  | ||||||
| 										class=" self-center hover:text-white transition" |  | ||||||
| 										on:click={() => { |  | ||||||
| 											editChatTitle(chat.id, chatTitle); |  | ||||||
| 											chatTitleEditId = null; |  | ||||||
| 											chatTitle = ''; |  | ||||||
| 										}} |  | ||||||
| 									> |  | ||||||
| 										<svg |  | ||||||
| 											xmlns="http://www.w3.org/2000/svg" |  | ||||||
| 											viewBox="0 0 20 20" |  | ||||||
| 											fill="currentColor" |  | ||||||
| 											class="w-4 h-4" |  | ||||||
| 										> |  | ||||||
| 											<path |  | ||||||
| 												fill-rule="evenodd" |  | ||||||
| 												d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" |  | ||||||
| 												clip-rule="evenodd" |  | ||||||
| 											/> |  | ||||||
| 										</svg> |  | ||||||
| 									</button> |  | ||||||
| 									<button |  | ||||||
| 										class=" self-center hover:text-white transition" |  | ||||||
| 										on:click={() => { |  | ||||||
| 											chatTitleEditId = null; |  | ||||||
| 											chatTitle = ''; |  | ||||||
| 										}} |  | ||||||
| 									> |  | ||||||
| 										<svg |  | ||||||
| 											xmlns="http://www.w3.org/2000/svg" |  | ||||||
| 											viewBox="0 0 20 20" |  | ||||||
| 											fill="currentColor" |  | ||||||
| 											class="w-4 h-4" |  | ||||||
| 										> |  | ||||||
| 											<path |  | ||||||
| 												d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" |  | ||||||
| 											/> |  | ||||||
| 										</svg> |  | ||||||
| 									</button> |  | ||||||
| 								</div> |  | ||||||
| 							{:else if chatDeleteId === chat.id} |  | ||||||
| 								<div class="flex self-center space-x-1.5"> |  | ||||||
| 									<button |  | ||||||
| 										class=" self-center hover:text-white transition" |  | ||||||
| 										on:click={() => { |  | ||||||
| 											deleteChat(chat.id); |  | ||||||
| 										}} |  | ||||||
| 									> |  | ||||||
| 										<svg |  | ||||||
| 											xmlns="http://www.w3.org/2000/svg" |  | ||||||
| 											viewBox="0 0 20 20" |  | ||||||
| 											fill="currentColor" |  | ||||||
| 											class="w-4 h-4" |  | ||||||
| 										> |  | ||||||
| 											<path |  | ||||||
| 												fill-rule="evenodd" |  | ||||||
| 												d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" |  | ||||||
| 												clip-rule="evenodd" |  | ||||||
| 											/> |  | ||||||
| 										</svg> |  | ||||||
| 									</button> |  | ||||||
| 									<button |  | ||||||
| 										class=" self-center hover:text-white transition" |  | ||||||
| 										on:click={() => { |  | ||||||
| 											chatDeleteId = null; |  | ||||||
| 										}} |  | ||||||
| 									> |  | ||||||
| 										<svg |  | ||||||
| 											xmlns="http://www.w3.org/2000/svg" |  | ||||||
| 											viewBox="0 0 20 20" |  | ||||||
| 											fill="currentColor" |  | ||||||
| 											class="w-4 h-4" |  | ||||||
| 										> |  | ||||||
| 											<path |  | ||||||
| 												d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" |  | ||||||
| 											/> |  | ||||||
| 										</svg> |  | ||||||
| 									</button> |  | ||||||
| 								</div> |  | ||||||
| 							{:else} |  | ||||||
| 								<div class="flex self-center space-x-1.5"> |  | ||||||
| 									<button |  | ||||||
| 										id="delete-chat-button" |  | ||||||
| 										class=" hidden" |  | ||||||
| 										on:click={() => { |  | ||||||
| 											deleteChat(chat.id); |  | ||||||
| 										}} |  | ||||||
| 									/> |  | ||||||
| 									<button |  | ||||||
| 										class=" self-center hover:text-white transition" |  | ||||||
| 										on:click={() => { |  | ||||||
| 											chatTitle = chat.title; |  | ||||||
| 											chatTitleEditId = chat.id; |  | ||||||
| 											// editChatTitle(chat.id, 'a'); |  | ||||||
| 										}} |  | ||||||
| 									> |  | ||||||
| 										<svg |  | ||||||
| 											xmlns="http://www.w3.org/2000/svg" |  | ||||||
| 											fill="none" |  | ||||||
| 											viewBox="0 0 24 24" |  | ||||||
| 											stroke-width="1.5" |  | ||||||
| 											stroke="currentColor" |  | ||||||
| 											class="w-4 h-4" |  | ||||||
| 										> |  | ||||||
| 											<path |  | ||||||
| 												stroke-linecap="round" |  | ||||||
| 												stroke-linejoin="round" |  | ||||||
| 												d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125" |  | ||||||
| 											/> |  | ||||||
| 										</svg> |  | ||||||
| 									</button> |  | ||||||
| 									<button |  | ||||||
| 										class=" self-center hover:text-white transition" |  | ||||||
| 										on:click={() => { |  | ||||||
| 											chatDeleteId = chat.id; |  | ||||||
| 										}} |  | ||||||
| 									> |  | ||||||
| 										<svg |  | ||||||
| 											xmlns="http://www.w3.org/2000/svg" |  | ||||||
| 											fill="none" |  | ||||||
| 											viewBox="0 0 24 24" |  | ||||||
| 											stroke-width="1.5" |  | ||||||
| 											stroke="currentColor" |  | ||||||
| 											class="w-4 h-4" |  | ||||||
| 										> |  | ||||||
| 											<path |  | ||||||
| 												stroke-linecap="round" |  | ||||||
| 												stroke-linejoin="round" |  | ||||||
| 												d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" |  | ||||||
| 											/> |  | ||||||
| 										</svg> |  | ||||||
| 									</button> |  | ||||||
| 								</div> |  | ||||||
| 							{/if} |  | ||||||
| 						</div> |  | ||||||
| 					{/if} |  | ||||||
| 				</div> |  | ||||||
| 			{/each} |  | ||||||
| 		</div> | 		</div> | ||||||
| 
 | 
 | ||||||
| 		<div class="px-2.5"> | 		<div class="px-2.5"> | ||||||
|  |  | ||||||
|  | @ -280,11 +280,13 @@ | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if ($chatId == _chatId) { | 			if ($chatId == _chatId) { | ||||||
| 				chat = await updateChatById(localStorage.token, _chatId, { | 				if ($settings.saveChatHistory ?? true) { | ||||||
| 					messages: messages, | 					chat = await updateChatById(localStorage.token, _chatId, { | ||||||
| 					history: history | 						messages: messages, | ||||||
| 				}); | 						history: history | ||||||
| 				await chats.set(await getChatList(localStorage.token)); | 					}); | ||||||
|  | 					await chats.set(await getChatList(localStorage.token)); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			if (res !== null) { | 			if (res !== null) { | ||||||
|  | @ -444,11 +446,13 @@ | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if ($chatId == _chatId) { | 			if ($chatId == _chatId) { | ||||||
| 				chat = await updateChatById(localStorage.token, _chatId, { | 				if ($settings.saveChatHistory ?? true) { | ||||||
| 					messages: messages, | 					chat = await updateChatById(localStorage.token, _chatId, { | ||||||
| 					history: history | 						messages: messages, | ||||||
| 				}); | 						history: history | ||||||
| 				await chats.set(await getChatList(localStorage.token)); | 					}); | ||||||
|  | 					await chats.set(await getChatList(localStorage.token)); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			if (res !== null) { | 			if (res !== null) { | ||||||
|  | @ -527,20 +531,24 @@ | ||||||
| 
 | 
 | ||||||
| 			// Create new chat if only one message in messages | 			// Create new chat if only one message in messages | ||||||
| 			if (messages.length == 1) { | 			if (messages.length == 1) { | ||||||
| 				chat = await createNewChat(localStorage.token, { | 				if ($settings.saveChatHistory ?? true) { | ||||||
| 					id: $chatId, | 					chat = await createNewChat(localStorage.token, { | ||||||
| 					title: 'New Chat', | 						id: $chatId, | ||||||
| 					models: selectedModels, | 						title: 'New Chat', | ||||||
| 					system: $settings.system ?? undefined, | 						models: selectedModels, | ||||||
| 					options: { | 						system: $settings.system ?? undefined, | ||||||
| 						...($settings.options ?? {}) | 						options: { | ||||||
| 					}, | 							...($settings.options ?? {}) | ||||||
| 					messages: messages, | 						}, | ||||||
| 					history: history, | 						messages: messages, | ||||||
| 					timestamp: Date.now() | 						history: history, | ||||||
| 				}); | 						timestamp: Date.now() | ||||||
| 				await chats.set(await getChatList(localStorage.token)); | 					}); | ||||||
| 				await chatId.set(chat.id); | 					await chats.set(await getChatList(localStorage.token)); | ||||||
|  | 					await chatId.set(chat.id); | ||||||
|  | 				} else { | ||||||
|  | 					await chatId.set('local'); | ||||||
|  | 				} | ||||||
| 				await tick(); | 				await tick(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -592,8 +600,10 @@ | ||||||
| 			title = _title; | 			title = _title; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		chat = await updateChatById(localStorage.token, _chatId, { title: _title }); | 		if ($settings.saveChatHistory ?? true) { | ||||||
| 		await chats.set(await getChatList(localStorage.token)); | 			chat = await updateChatById(localStorage.token, _chatId, { title: _title }); | ||||||
|  | 			await chats.set(await getChatList(localStorage.token)); | ||||||
|  | 		} | ||||||
| 	}; | 	}; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -609,6 +609,12 @@ | ||||||
| 		chat = await updateChatById(localStorage.token, _chatId, { title: _title }); | 		chat = await updateChatById(localStorage.token, _chatId, { title: _title }); | ||||||
| 		await chats.set(await getChatList(localStorage.token)); | 		await chats.set(await getChatList(localStorage.token)); | ||||||
| 	}; | 	}; | ||||||
|  | 
 | ||||||
|  | 	onMount(async () => { | ||||||
|  | 		if (!($settings.saveChatHistory ?? true)) { | ||||||
|  | 			await goto('/'); | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <svelte:window | <svelte:window | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Jaeryang Baek
						Timothy Jaeryang Baek