From 980f048773cfebbd9e63d48d9ee35c84d8078ce4 Mon Sep 17 00:00:00 2001 From: Curtis Upshall Date: Mon, 6 Jan 2025 14:28:11 -0800 Subject: [PATCH] Use URL params to cache and reload last accessed conversation (#235) * Use URL params to cache and reload last accessed conversation * Corrected typo --------- Co-authored-by: David Camden --- webapi/Plugins/Chat/ChatPlugin.cs | 1 - .../components/chat/chat-list/ChatList.tsx | 23 +++++++++++++ webapp/src/libs/hooks/useAppLoader.ts | 32 ++++++++++++++----- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/webapi/Plugins/Chat/ChatPlugin.cs b/webapi/Plugins/Chat/ChatPlugin.cs index 76d34c1d3..7483db475 100755 --- a/webapi/Plugins/Chat/ChatPlugin.cs +++ b/webapi/Plugins/Chat/ChatPlugin.cs @@ -181,7 +181,6 @@ public async Task ChatAsync( await this.SetSystemDescriptionAsync(chatId, cancellationToken); // Save this new message to memory such that subsequent chat responses can use it - // await this.UpdateBotResponseStatusOnClientAsync(chatId, "Generating bot response", cancellationToken); this._logger.LogInformation("Saving user message to chat history"); diff --git a/webapp/src/components/chat/chat-list/ChatList.tsx b/webapp/src/components/chat/chat-list/ChatList.tsx index dfce31583..f7f4ecbee 100644 --- a/webapp/src/components/chat/chat-list/ChatList.tsx +++ b/webapp/src/components/chat/chat-list/ChatList.tsx @@ -84,6 +84,7 @@ export const ChatList: FC = () => { const classes = useClasses(); const { features } = useAppSelector((state: RootState) => state.app); const { conversations } = useAppSelector((state: RootState) => state.conversations); + const { selectedId } = useAppSelector((state: RootState) => state.conversations); const [isFiltering, setIsFiltering] = useState(false); const [filterText, setFilterText] = useState(''); @@ -170,6 +171,28 @@ export const ChatList: FC = () => { [fileHandler, chat, dispatch], ); + useEffect(() => { + const setConversationIdInUrl = (conversationId: string) => { + const urlParams = new URLSearchParams(window.location.search); + urlParams.set('conversation', conversationId); + window.history.replaceState({}, '', `${window.location.pathname}?${urlParams}`); + }; + + const removeConversationIdInUrl = () => { + const urlParams = new URLSearchParams(window.location.search); + urlParams.delete('conversation'); + window.history.replaceState({}, '', `${window.location.pathname}?${urlParams}`); + }; + + if (selectedId) { + setConversationIdInUrl(selectedId); + } + + return () => { + removeConversationIdInUrl(); + }; + }, [selectedId]); + return (
diff --git a/webapp/src/libs/hooks/useAppLoader.ts b/webapp/src/libs/hooks/useAppLoader.ts index 936cbd19d..a2d183177 100644 --- a/webapp/src/libs/hooks/useAppLoader.ts +++ b/webapp/src/libs/hooks/useAppLoader.ts @@ -152,16 +152,32 @@ export const useAppLoader = (): [AppState, Dispatch>] = }; const loadInitialChat = async () => { - const firstConvo = maxBy(Object.values(conversations), (chatState) => chatState.lastUpdatedTimestamp ?? 0); - if (firstConvo?.createdOnServer) { - dispatch(setSelectedConversation(firstConvo.id)); - try { - await chat.loadChatMessagesByChatId(firstConvo.id); - } catch (err) { - console.log((err as Error).message); - setAppState(AppState.ErrorLoadingChats); + let chatIdToLoad: string | undefined = undefined; + + // Check if the conversation is in the URL + const urlParams = new URLSearchParams(window.location.search); + const conversationId = urlParams.get('conversation'); + + if (conversationId) { + chatIdToLoad = conversationId; + } else { + const firstConvo = maxBy(Object.values(conversations), (chatState) => chatState.lastUpdatedTimestamp ?? 0); + if (firstConvo?.createdOnServer) { + chatIdToLoad = firstConvo.id; } } + + if (!chatIdToLoad) { + return; + } + + dispatch(setSelectedConversation(chatIdToLoad)); + try { + await chat.loadChatMessagesByChatId(chatIdToLoad); + } catch (err) { + console.log((err as Error).message); + setAppState(AppState.ErrorLoadingChats); + } }; // Watches for changes in the application state and loads the app accordingly