mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-08 20:25:19 +02:00
refactor: enhance chat functionality with query invalidation and navigation improvements
- Integrated useQueryClient from React Query to manage query invalidation for threads, ensuring real-time updates in the sidebar when a new chat is created or a thread is deleted. - Updated the AllChatsSidebar to close the sidebar and navigate to the new chat page if the currently open chat is deleted. - Improved error handling and user experience during thread deletion by ensuring the sidebar closes smoothly before redirection.
This commit is contained in:
parent
d9df63f57e
commit
287fc236ad
3 changed files with 36 additions and 4 deletions
|
|
@ -6,6 +6,7 @@ import {
|
|||
type ThreadMessageLike,
|
||||
useExternalStoreRuntime,
|
||||
} from "@assistant-ui/react";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useAtomValue, useSetAtom } from "jotai";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
|
@ -140,6 +141,7 @@ interface ThinkingStepData {
|
|||
|
||||
export default function NewChatPage() {
|
||||
const params = useParams();
|
||||
const queryClient = useQueryClient();
|
||||
const [isInitializing, setIsInitializing] = useState(true);
|
||||
const [threadId, setThreadId] = useState<number | null>(null);
|
||||
const [messages, setMessages] = useState<ThreadMessageLike[]>([]);
|
||||
|
|
@ -300,11 +302,13 @@ export default function NewChatPage() {
|
|||
|
||||
// Lazy thread creation: create thread on first message if it doesn't exist
|
||||
let currentThreadId = threadId;
|
||||
let isNewThread = false;
|
||||
if (!currentThreadId) {
|
||||
try {
|
||||
const newThread = await createThread(searchSpaceId, "New Chat");
|
||||
currentThreadId = newThread.id;
|
||||
setThreadId(currentThreadId);
|
||||
isNewThread = true;
|
||||
// Update URL silently using browser API (not router.replace) to avoid
|
||||
// interrupting the ongoing fetch/streaming with React navigation
|
||||
window.history.replaceState(
|
||||
|
|
@ -362,7 +366,15 @@ export default function NewChatPage() {
|
|||
appendMessage(currentThreadId, {
|
||||
role: "user",
|
||||
content: persistContent,
|
||||
}).catch((err) => console.error("Failed to persist user message:", err));
|
||||
})
|
||||
.then(() => {
|
||||
// For new threads, the backend updates the title from the first user message
|
||||
// Invalidate threads query so sidebar shows the updated title in real-time
|
||||
if (isNewThread) {
|
||||
queryClient.invalidateQueries({ queryKey: ["threads", String(searchSpaceId)] });
|
||||
}
|
||||
})
|
||||
.catch((err) => console.error("Failed to persist user message:", err));
|
||||
|
||||
// Start streaming response
|
||||
setIsRunning(true);
|
||||
|
|
@ -692,6 +704,7 @@ export default function NewChatPage() {
|
|||
setMentionedDocumentIds,
|
||||
setMentionedDocuments,
|
||||
setMessageDocumentsMap,
|
||||
queryClient,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@ export function AppSidebarProvider({
|
|||
await deleteThread(threadToDelete.id);
|
||||
// Invalidate threads query to refresh the list
|
||||
queryClient.invalidateQueries({ queryKey: ["threads", searchSpaceId] });
|
||||
// Navigate to new-chat after successful deletion
|
||||
router.push(`/dashboard/${searchSpaceId}/new-chat`);
|
||||
} catch (error) {
|
||||
console.error("Error deleting thread:", error);
|
||||
} finally {
|
||||
|
|
@ -156,7 +158,7 @@ export function AppSidebarProvider({
|
|||
setShowDeleteDialog(false);
|
||||
setThreadToDelete(null);
|
||||
}
|
||||
}, [threadToDelete, queryClient, searchSpaceId]);
|
||||
}, [threadToDelete, queryClient, searchSpaceId, router]);
|
||||
|
||||
// Handle delete note with confirmation
|
||||
const handleDeleteNote = useCallback(async () => {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import {
|
|||
X,
|
||||
} from "lucide-react";
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
|
|
@ -47,7 +47,15 @@ interface AllChatsSidebarProps {
|
|||
export function AllChatsSidebar({ open, onOpenChange, searchSpaceId }: AllChatsSidebarProps) {
|
||||
const t = useTranslations("sidebar");
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Get the current chat ID from URL to check if user is deleting the currently open chat
|
||||
const currentChatId = Array.isArray(params.chat_id)
|
||||
? Number(params.chat_id[0])
|
||||
: params.chat_id
|
||||
? Number(params.chat_id)
|
||||
: null;
|
||||
const [deletingThreadId, setDeletingThreadId] = useState<number | null>(null);
|
||||
const [archivingThreadId, setArchivingThreadId] = useState<number | null>(null);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
|
|
@ -126,6 +134,15 @@ export function AllChatsSidebar({ open, onOpenChange, searchSpaceId }: AllChatsS
|
|||
queryClient.invalidateQueries({ queryKey: ["all-threads", searchSpaceId] });
|
||||
queryClient.invalidateQueries({ queryKey: ["search-threads", searchSpaceId] });
|
||||
queryClient.invalidateQueries({ queryKey: ["threads", searchSpaceId] });
|
||||
|
||||
// If the deleted chat is currently open, close sidebar first then redirect
|
||||
if (currentChatId === threadId) {
|
||||
onOpenChange(false);
|
||||
// Wait for sidebar close animation to complete before navigating
|
||||
setTimeout(() => {
|
||||
router.push(`/dashboard/${searchSpaceId}/new-chat`);
|
||||
}, 250);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error deleting thread:", error);
|
||||
toast.error(t("error_deleting_chat") || "Failed to delete chat");
|
||||
|
|
@ -133,7 +150,7 @@ export function AllChatsSidebar({ open, onOpenChange, searchSpaceId }: AllChatsS
|
|||
setDeletingThreadId(null);
|
||||
}
|
||||
},
|
||||
[queryClient, searchSpaceId, t]
|
||||
[queryClient, searchSpaceId, t, currentChatId, router, onOpenChange]
|
||||
);
|
||||
|
||||
// Handle thread archive/unarchive
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue