fix: unarchive chats moved into folders and refresh sidebar folders after menu moves (#27485)

This commit is contained in:
G30 authored and GitHub committed 2026-07-26 18:43:34 -04:00
1 parent 71f8b6d5b4
commit db92ef292f
4 files changed
+38 -2

No files matched your search

+5
View File
@@ -1885,6 +1885,11 @@ class ChatTable:
chat.updated_at = int(time.time()) chat.updated_at = int(time.time())
chat.last_read_at = int(time.time()) chat.last_read_at = int(time.time())
chat.pinned = False chat.pinned = False
if folder_id is not None:
# Folder listings only show unarchived chats, so moving an archived
# chat into a folder would otherwise have no visible effect: the chat
# stays in the archived list and never appears in the folder.
chat.archived = False
await session.commit() await session.commit()
return ChatModel.model_validate(chat) return ChatModel.model_validate(chat)
except Exception: except Exception:
+3 -1
View File
@@ -48,7 +48,7 @@
chatRequestQueues, chatRequestQueues,
desktopEvent desktopEvent
} from '$lib/stores'; } from '$lib/stores';
import { refreshChatList } from '$lib/stores/chatList'; import { refreshChatList, refreshFolderChatLists } from '$lib/stores/chatList';
import { WEBUI_API_BASE_URL } from '$lib/constants'; import { WEBUI_API_BASE_URL } from '$lib/constants';
@@ -3566,6 +3566,7 @@
if (res) { if (res) {
await refreshChatList(localStorage.token, { refreshPinned: true }); await refreshChatList(localStorage.token, { refreshPinned: true });
await refreshFolderChatLists();
toast.success($i18n.t('Chat moved successfully')); toast.success($i18n.t('Chat moved successfully'));
} }
@@ -3580,6 +3581,7 @@
initNewChat(); initNewChat();
await goto('/'); await goto('/');
await refreshChatList(localStorage.token, { refreshPinned: true }); await refreshChatList(localStorage.token, { refreshPinned: true });
await refreshFolderChatLists();
toast.success($i18n.t('Chat archived.')); toast.success($i18n.t('Chat archived.'));
} catch (error) { } catch (error) {
console.error('Error archiving chat:', error); console.error('Error archiving chat:', error);
+12 -1
View File
@@ -27,7 +27,12 @@
WEBUI_NAME, WEBUI_NAME,
sidebarWidth sidebarWidth
} from '$lib/stores'; } from '$lib/stores';
import { loadNextChatListPage, refreshChatList, setChatActive } from '$lib/stores/chatList'; import {
loadNextChatListPage,
refreshChatList,
registerFolderRefreshHandler,
setChatActive
} from '$lib/stores/chatList';
import { onMount, getContext, tick, onDestroy } from 'svelte'; import { onMount, getContext, tick, onDestroy } from 'svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
@@ -649,6 +654,10 @@
socketInstance?.on('events', chatActiveEventHandler); socketInstance?.on('events', chatActiveEventHandler);
socketInstance?.on('connect', refreshChatRows); socketInstance?.on('connect', refreshChatRows);
const unregisterFolderRefreshHandler = registerFolderRefreshHandler(() =>
Promise.all(Object.values(folderRegistry).map((folder) => folder?.setFolderItems?.()))
);
await tick(); await tick();
initPinnedMenuSortable(); initPinnedMenuSortable();
@@ -672,6 +681,8 @@
socketInstance?.off('events', chatActiveEventHandler); socketInstance?.off('events', chatActiveEventHandler);
socketInstance?.off('connect', refreshChatRows); socketInstance?.off('connect', refreshChatRows);
unregisterFolderRefreshHandler();
}; };
}); });
+18
View File
@@ -61,6 +61,24 @@ export const refreshChatList = async (
return { accepted: true, allLoaded }; return { accepted: true, allLoaded };
}; };
// The sidebar's folders keep their chat lists in local component state, refreshed
// through a registry of per-folder callbacks that only the sidebar can reach.
// Handlers registered here let other components (e.g. the open chat's menu)
// request that refresh without a reference to the sidebar.
type FolderRefreshHandler = () => unknown;
const folderRefreshHandlers = new Set<FolderRefreshHandler>();
export const registerFolderRefreshHandler = (handler: FolderRefreshHandler) => {
folderRefreshHandlers.add(handler);
return () => {
folderRefreshHandlers.delete(handler);
};
};
export const refreshFolderChatLists = async () => {
await Promise.all([...folderRefreshHandlers].map((handler) => handler()));
};
export const loadNextChatListPage = async (token: string = ''): Promise<ChatListResult> => { export const loadNextChatListPage = async (token: string = ''): Promise<ChatListResult> => {
if (!paginationReady || allLoaded || loadingNextPage) { if (!paginationReady || allLoaded || loadingNextPage) {
return { accepted: false, allLoaded }; return { accepted: false, allLoaded };