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 = ''; | ||||
| 
 | ||||
| 	// Chats | ||||
| 	let saveChatHistory = true; | ||||
| 	let importFiles; | ||||
| 	let showDeleteConfirm = false; | ||||
| 
 | ||||
|  | @ -235,8 +236,14 @@ | |||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	const toggleAuthHeader = async () => { | ||||
| 		authEnabled = !authEnabled; | ||||
| 	const toggleSaveChatHistory = async () => { | ||||
| 		saveChatHistory = !saveChatHistory; | ||||
| 		console.log(saveChatHistory); | ||||
| 
 | ||||
| 		if (saveChatHistory === false) { | ||||
| 			await goto('/'); | ||||
| 		} | ||||
| 		saveSettings({ saveChatHistory: saveChatHistory }); | ||||
| 	}; | ||||
| 
 | ||||
| 	const pullModelHandler = async () => { | ||||
|  | @ -576,6 +583,8 @@ | |||
| 		titleAutoGenerateModel = settings.titleAutoGenerateModel ?? ''; | ||||
| 		gravatarEmail = settings.gravatarEmail ?? ''; | ||||
| 
 | ||||
| 		saveChatHistory = settings.saveChatHistory ?? true; | ||||
| 
 | ||||
| 		authEnabled = settings.authHeader !== undefined ? true : false; | ||||
| 		if (authEnabled) { | ||||
| 			authType = settings.authHeader.split(' ')[0]; | ||||
|  | @ -1616,6 +1625,64 @@ | |||
| 				{:else if selectedTab === 'chats'} | ||||
| 					<div class="flex flex-col h-full justify-between space-y-3 text-sm"> | ||||
| 						<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"> | ||||
| 								<input | ||||
| 									id="chat-import-input" | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| 
 | ||||
| 	import { goto, invalidateAll } from '$app/navigation'; | ||||
| 	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 { deleteChatById, getChatList, updateChatById } from '$lib/apis/chats'; | ||||
| 
 | ||||
|  | @ -49,6 +49,12 @@ | |||
| 		await deleteChatById(localStorage.token, id); | ||||
| 		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> | ||||
| 
 | ||||
| <div | ||||
|  | @ -159,6 +165,48 @@ | |||
| 			</div> | ||||
| 		{/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="flex w-full" id="chat-search"> | ||||
| 					<div class="self-center pl-3 py-2 rounded-l bg-gray-950"> | ||||
|  | @ -407,6 +455,7 @@ | |||
| 					</div> | ||||
| 				{/each} | ||||
| 			</div> | ||||
| 		</div> | ||||
| 
 | ||||
| 		<div class="px-2.5"> | ||||
| 			<hr class=" border-gray-900 mb-1 w-full" /> | ||||
|  |  | |||
|  | @ -280,12 +280,14 @@ | |||
| 			} | ||||
| 
 | ||||
| 			if ($chatId == _chatId) { | ||||
| 				if ($settings.saveChatHistory ?? true) { | ||||
| 					chat = await updateChatById(localStorage.token, _chatId, { | ||||
| 						messages: messages, | ||||
| 						history: history | ||||
| 					}); | ||||
| 					await chats.set(await getChatList(localStorage.token)); | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (res !== null) { | ||||
| 				const error = await res.json(); | ||||
|  | @ -444,12 +446,14 @@ | |||
| 			} | ||||
| 
 | ||||
| 			if ($chatId == _chatId) { | ||||
| 				if ($settings.saveChatHistory ?? true) { | ||||
| 					chat = await updateChatById(localStorage.token, _chatId, { | ||||
| 						messages: messages, | ||||
| 						history: history | ||||
| 					}); | ||||
| 					await chats.set(await getChatList(localStorage.token)); | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (res !== null) { | ||||
| 				const error = await res.json(); | ||||
|  | @ -527,6 +531,7 @@ | |||
| 
 | ||||
| 			// Create new chat if only one message in messages | ||||
| 			if (messages.length == 1) { | ||||
| 				if ($settings.saveChatHistory ?? true) { | ||||
| 					chat = await createNewChat(localStorage.token, { | ||||
| 						id: $chatId, | ||||
| 						title: 'New Chat', | ||||
|  | @ -541,6 +546,9 @@ | |||
| 					}); | ||||
| 					await chats.set(await getChatList(localStorage.token)); | ||||
| 					await chatId.set(chat.id); | ||||
| 				} else { | ||||
| 					await chatId.set('local'); | ||||
| 				} | ||||
| 				await tick(); | ||||
| 			} | ||||
| 
 | ||||
|  | @ -592,8 +600,10 @@ | |||
| 			title = _title; | ||||
| 		} | ||||
| 
 | ||||
| 		if ($settings.saveChatHistory ?? true) { | ||||
| 			chat = await updateChatById(localStorage.token, _chatId, { title: _title }); | ||||
| 			await chats.set(await getChatList(localStorage.token)); | ||||
| 		} | ||||
| 	}; | ||||
| </script> | ||||
| 
 | ||||
|  |  | |||
|  | @ -609,6 +609,12 @@ | |||
| 		chat = await updateChatById(localStorage.token, _chatId, { title: _title }); | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| 
 | ||||
| 	onMount(async () => { | ||||
| 		if (!($settings.saveChatHistory ?? true)) { | ||||
| 			await goto('/'); | ||||
| 		} | ||||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| <svelte:window | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Jaeryang Baek
						Timothy Jaeryang Baek