Timothy J. Baek 8 months ago
parent
commit
351c29917b

+ 8 - 3
backend/open_webui/apps/webui/models/chats.py

@@ -519,9 +519,14 @@ class ChatTable:
         self, folder_id: str, user_id: str
     ) -> list[ChatModel]:
         with get_db() as db:
-            all_chats = (
-                db.query(Chat).filter_by(folder_id=folder_id, user_id=user_id).all()
-            )
+            query = db.query(Chat).filter_by(folder_id=folder_id, user_id=user_id)
+
+            query = query.filter_by(archived=False)
+            query = query.filter(or_(Chat.pinned == False, Chat.pinned == None))
+
+            query = query.order_by(Chat.updated_at.desc())
+
+            all_chats = query.all()
             return [ChatModel.model_validate(chat) for chat in all_chats]
 
     def update_chat_folder_id_by_id_and_user_id(

+ 5 - 63
src/lib/components/layout/Sidebar.svelte

@@ -39,7 +39,6 @@
 	import ArchivedChatsModal from './Sidebar/ArchivedChatsModal.svelte';
 	import UserMenu from './Sidebar/UserMenu.svelte';
 	import ChatItem from './Sidebar/ChatItem.svelte';
-	import DeleteConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
 	import Spinner from '../common/Spinner.svelte';
 	import Loader from '../common/Loader.svelte';
 	import AddFilesPlaceholder from '../AddFilesPlaceholder.svelte';
@@ -152,6 +151,8 @@
 	const initChatList = async () => {
 		// Reset pagination variables
 		tags.set(await getAllTags(localStorage.token));
+		pinnedChats.set(await getPinnedChatList(localStorage.token));
+		initFolders();
 
 		currentChatPage.set(1);
 		allChatsLoaded = false;
@@ -207,28 +208,6 @@
 		}
 	};
 
-	const deleteChatHandler = async (id) => {
-		const res = await deleteChatById(localStorage.token, id).catch((error) => {
-			toast.error(error);
-			return null;
-		});
-
-		if (res) {
-			tags.set(await getAllTags(localStorage.token));
-
-			if ($chatId === id) {
-				await chatId.set('');
-				await tick();
-				goto('/');
-			}
-
-			allChatsLoaded = false;
-			currentChatPage.set(1);
-			await chats.set(await getChatList(localStorage.token, $currentChatPage));
-			await pinnedChats.set(await getPinnedChatList(localStorage.token));
-		}
-	};
-
 	const inputFilesHandler = async (files) => {
 		console.log(files);
 
@@ -364,8 +343,6 @@
 			localStorage.sidebar = value;
 		});
 
-		await initFolders();
-		await pinnedChats.set(await getPinnedChatList(localStorage.token));
 		await initChatList();
 
 		window.addEventListener('keydown', onKeyDown);
@@ -405,23 +382,10 @@
 <ArchivedChatsModal
 	bind:show={$showArchivedChats}
 	on:change={async () => {
-		await pinnedChats.set(await getPinnedChatList(localStorage.token));
 		await initChatList();
 	}}
 />
 
-<DeleteConfirmDialog
-	bind:show={showDeleteConfirm}
-	title={$i18n.t('Delete chat?')}
-	on:confirm={() => {
-		deleteChatHandler(deleteChat.id);
-	}}
->
-	<div class=" text-sm text-gray-500 flex-1 line-clamp-3">
-		{$i18n.t('This will delete')} <span class="  font-semibold">{deleteChat.title}</span>.
-	</div>
-</DeleteConfirmDialog>
-
 <!-- svelte-ignore a11y-no-static-element-interactions -->
 
 {#if $showSidebar}
@@ -632,7 +596,6 @@
 
 										if (res) {
 											initChatList();
-											await initFolders();
 										}
 									}
 
@@ -640,9 +603,7 @@
 										const res = await toggleChatPinnedStatusById(localStorage.token, id);
 
 										if (res) {
-											await pinnedChats.set(await getPinnedChatList(localStorage.token));
 											initChatList();
-											await initFolders();
 										}
 									}
 								}
@@ -666,16 +627,7 @@
 									on:unselect={() => {
 										selectedChatId = null;
 									}}
-									on:delete={(e) => {
-										if ((e?.detail ?? '') === 'shift') {
-											deleteChatHandler(chat.id);
-										} else {
-											deleteChat = chat;
-											showDeleteConfirm = true;
-										}
-									}}
 									on:change={async () => {
-										await pinnedChats.set(await getPinnedChatList(localStorage.token));
 										initChatList();
 									}}
 									on:tag={(e) => {
@@ -695,7 +647,9 @@
 						{folders}
 						on:update={async (e) => {
 							initChatList();
-							await initFolders();
+						}}
+						on:change={async () => {
+							initChatList();
 						}}
 					/>
 				{/if}
@@ -722,7 +676,6 @@
 
 									if (res) {
 										initChatList();
-										await initFolders();
 									}
 								}
 
@@ -730,9 +683,7 @@
 									const res = await toggleChatPinnedStatusById(localStorage.token, id);
 
 									if (res) {
-										await pinnedChats.set(await getPinnedChatList(localStorage.token));
 										initChatList();
-										await initFolders();
 									}
 								}
 							}
@@ -798,16 +749,7 @@
 									on:unselect={() => {
 										selectedChatId = null;
 									}}
-									on:delete={(e) => {
-										if ((e?.detail ?? '') === 'shift') {
-											deleteChatHandler(chat.id);
-										} else {
-											deleteChat = chat;
-											showDeleteConfirm = true;
-										}
-									}}
 									on:change={async () => {
-										await pinnedChats.set(await getPinnedChatList(localStorage.token));
 										initChatList();
 									}}
 									on:tag={(e) => {

+ 36 - 7
src/lib/components/layout/Sidebar/ChatItem.svelte

@@ -28,6 +28,7 @@
 	} from '$lib/stores';
 
 	import ChatMenu from './ChatMenu.svelte';
+	import DeleteConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
 	import ShareChatModal from '$lib/components/chat/ShareChatModal.svelte';
 	import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
@@ -85,13 +86,27 @@
 		}
 	};
 
+	const deleteChatHandler = async (id) => {
+		const res = await deleteChatById(localStorage.token, id).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (res) {
+			tags.set(await getAllTags(localStorage.token));
+			if ($chatId === id) {
+				await chatId.set('');
+				await tick();
+				goto('/');
+			}
+
+			dispatch('change');
+		}
+	};
+
 	const archiveChatHandler = async (id) => {
 		await archiveChatById(localStorage.token, id);
-		tags.set(await getAllTags(localStorage.token));
-
-		currentChatPage.set(1);
-		await chats.set(await getChatList(localStorage.token, $currentChatPage));
-		await pinnedChats.set(await getPinnedChatList(localStorage.token));
+		dispatch('change');
 	};
 
 	const focusEdit = async (node: HTMLInputElement) => {
@@ -158,10 +173,24 @@
 			itemElement.removeEventListener('dragend', onDragEnd);
 		}
 	});
+
+	let showDeleteConfirm = false;
 </script>
 
 <ShareChatModal bind:show={showShareChatModal} chatId={id} />
 
+<DeleteConfirmDialog
+	bind:show={showDeleteConfirm}
+	title={$i18n.t('Delete chat?')}
+	on:confirm={() => {
+		deleteChatHandler(id);
+	}}
+>
+	<div class=" text-sm text-gray-500 flex-1 line-clamp-3">
+		{$i18n.t('This will delete')} <span class="  font-semibold">{title}</span>.
+	</div>
+</DeleteConfirmDialog>
+
 {#if dragged && x && y}
 	<DragGhost {x} {y}>
 		<div class=" bg-black/80 backdrop-blur-2xl px-2 py-1 rounded-lg w-fit max-w-40">
@@ -295,7 +324,7 @@
 					<button
 						class=" self-center dark:hover:text-white transition"
 						on:click={() => {
-							dispatch('delete', 'shift');
+							deleteChatHandler(id);
 						}}
 						type="button"
 					>
@@ -322,7 +351,7 @@
 						confirmEdit = true;
 					}}
 					deleteHandler={() => {
-						dispatch('delete');
+						showDeleteConfirm = true;
 					}}
 					onClose={() => {
 						dispatch('unselect');

+ 3 - 0
src/lib/components/layout/Sidebar/Folders.svelte

@@ -25,5 +25,8 @@
 		on:update={(e) => {
 			dispatch('update', e.detail);
 		}}
+		on:change={(e) => {
+			dispatch('change', e.detail);
+		}}
 	/>
 {/each}

+ 10 - 1
src/lib/components/layout/Sidebar/RecursiveFolder.svelte

@@ -381,13 +381,22 @@
 								on:update={(e) => {
 									dispatch('update', e.detail);
 								}}
+								on:change={(e) => {
+									dispatch('change', e.detail);
+								}}
 							/>
 						{/each}
 					{/if}
 
 					{#if folders[folderId].items?.chats}
 						{#each folders[folderId].items.chats as chat (chat.id)}
-							<ChatItem id={chat.id} title={chat.title} />
+							<ChatItem
+								id={chat.id}
+								title={chat.title}
+								on:change={(e) => {
+									dispatch('change', e.detail);
+								}}
+							/>
 						{/each}
 					{/if}
 				</div>