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,6 +165,48 @@ | ||||||
| 			</div> | 			</div> | ||||||
| 		{/if} | 		{/if} | ||||||
| 
 | 
 | ||||||
|  | 		<div class="relative flex flex-col flex-1 overflow-y-auto"> | ||||||
|  | 			{#if !($settings.saveChatHistory ?? true)} | ||||||
|  | 				<div class="absolute z-40 w-full h-full bg-black/90 flex justify-center"> | ||||||
|  | 					<div class=" text-left px-5 py-2"> | ||||||
|  | 						<div class=" font-medium">Chat History is off for this browser.</div> | ||||||
|  | 						<div class="text-xs mt-2"> | ||||||
|  | 							When history is turned off, new chats on this browser won't appear in your history on | ||||||
|  | 							any of your devices. <span class=" font-semibold" | ||||||
|  | 								>This setting does not sync across browsers or devices.</span | ||||||
|  | 							> | ||||||
|  | 						</div> | ||||||
|  | 
 | ||||||
|  | 						<div class="mt-3"> | ||||||
|  | 							<button | ||||||
|  | 								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" | ||||||
|  | 								type="button" | ||||||
|  | 								on:click={() => { | ||||||
|  | 									saveSettings({ | ||||||
|  | 										saveChatHistory: true | ||||||
|  | 									}); | ||||||
|  | 								}} | ||||||
|  | 							> | ||||||
|  | 								<svg | ||||||
|  | 									xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 									viewBox="0 0 16 16" | ||||||
|  | 									fill="currentColor" | ||||||
|  | 									class="w-3 h-3" | ||||||
|  | 								> | ||||||
|  | 									<path | ||||||
|  | 										fill-rule="evenodd" | ||||||
|  | 										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" | ||||||
|  | 										clip-rule="evenodd" | ||||||
|  | 									/> | ||||||
|  | 								</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="px-2.5 mt-1 mb-2 flex justify-center space-x-2"> | ||||||
| 				<div class="flex w-full" id="chat-search"> | 				<div class="flex w-full" id="chat-search"> | ||||||
| 					<div class="self-center pl-3 py-2 rounded-l bg-gray-950"> | 					<div class="self-center pl-3 py-2 rounded-l bg-gray-950"> | ||||||
|  | @ -407,6 +455,7 @@ | ||||||
| 					</div> | 					</div> | ||||||
| 				{/each} | 				{/each} | ||||||
| 			</div> | 			</div> | ||||||
|  | 		</div> | ||||||
| 
 | 
 | ||||||
| 		<div class="px-2.5"> | 		<div class="px-2.5"> | ||||||
| 			<hr class=" border-gray-900 mb-1 w-full" /> | 			<hr class=" border-gray-900 mb-1 w-full" /> | ||||||
|  |  | ||||||
|  | @ -280,12 +280,14 @@ | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if ($chatId == _chatId) { | 			if ($chatId == _chatId) { | ||||||
|  | 				if ($settings.saveChatHistory ?? true) { | ||||||
| 					chat = await updateChatById(localStorage.token, _chatId, { | 					chat = await updateChatById(localStorage.token, _chatId, { | ||||||
| 						messages: messages, | 						messages: messages, | ||||||
| 						history: history | 						history: history | ||||||
| 					}); | 					}); | ||||||
| 					await chats.set(await getChatList(localStorage.token)); | 					await chats.set(await getChatList(localStorage.token)); | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			if (res !== null) { | 			if (res !== null) { | ||||||
| 				const error = await res.json(); | 				const error = await res.json(); | ||||||
|  | @ -444,12 +446,14 @@ | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if ($chatId == _chatId) { | 			if ($chatId == _chatId) { | ||||||
|  | 				if ($settings.saveChatHistory ?? true) { | ||||||
| 					chat = await updateChatById(localStorage.token, _chatId, { | 					chat = await updateChatById(localStorage.token, _chatId, { | ||||||
| 						messages: messages, | 						messages: messages, | ||||||
| 						history: history | 						history: history | ||||||
| 					}); | 					}); | ||||||
| 					await chats.set(await getChatList(localStorage.token)); | 					await chats.set(await getChatList(localStorage.token)); | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			if (res !== null) { | 			if (res !== null) { | ||||||
| 				const error = await res.json(); | 				const error = await res.json(); | ||||||
|  | @ -527,6 +531,7 @@ | ||||||
| 
 | 
 | ||||||
| 			// 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) { | ||||||
|  | 				if ($settings.saveChatHistory ?? true) { | ||||||
| 					chat = await createNewChat(localStorage.token, { | 					chat = await createNewChat(localStorage.token, { | ||||||
| 						id: $chatId, | 						id: $chatId, | ||||||
| 						title: 'New Chat', | 						title: 'New Chat', | ||||||
|  | @ -541,6 +546,9 @@ | ||||||
| 					}); | 					}); | ||||||
| 					await chats.set(await getChatList(localStorage.token)); | 					await chats.set(await getChatList(localStorage.token)); | ||||||
| 					await chatId.set(chat.id); | 					await chatId.set(chat.id); | ||||||
|  | 				} else { | ||||||
|  | 					await chatId.set('local'); | ||||||
|  | 				} | ||||||
| 				await tick(); | 				await tick(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -592,8 +600,10 @@ | ||||||
| 			title = _title; | 			title = _title; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if ($settings.saveChatHistory ?? true) { | ||||||
| 			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)); | ||||||
|  | 		} | ||||||
| 	}; | 	}; | ||||||
| </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