import { useEffect, useState } from "react"; import { useNavigate, useRouterState } from "@tanstack/react-router"; import { formatDistanceToNow } from "date-fns"; import { PlusCircle, MoreVertical, Trash2, Edit3, Search } from "lucide-react"; import { useAtom } from "jotai"; import { selectedChatIdAtom } from "@/atoms/chatAtoms"; import { selectedAppIdAtom } from "@/atoms/appAtoms"; import { dropdownOpenAtom } from "@/atoms/uiAtoms"; import { IpcClient } from "@/ipc/ipc_client"; import { showError, showSuccess } from "@/lib/toast"; import { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuItem, } from "@/components/ui/sidebar"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { useChats } from "@/hooks/useChats"; import { RenameChatDialog } from "@/components/chat/RenameChatDialog"; import { DeleteChatDialog } from "@/components/chat/DeleteChatDialog"; import { ChatSearchDialog } from "./ChatSearchDialog"; import { useSelectChat } from "@/hooks/useSelectChat"; export function ChatList({ show }: { show?: boolean }) { const navigate = useNavigate(); const [selectedChatId, setSelectedChatId] = useAtom(selectedChatIdAtom); const [selectedAppId] = useAtom(selectedAppIdAtom); const [, setIsDropdownOpen] = useAtom(dropdownOpenAtom); const { chats, loading, refreshChats } = useChats(selectedAppId); const routerState = useRouterState(); const isChatRoute = routerState.location.pathname === "/chat"; // Rename dialog state const [isRenameDialogOpen, setIsRenameDialogOpen] = useState(false); const [renameChatId, setRenameChatId] = useState(null); const [renameChatTitle, setRenameChatTitle] = useState(""); // Delete dialog state const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const [deleteChatId, setDeleteChatId] = useState(null); const [deleteChatTitle, setDeleteChatTitle] = useState(""); // search dialog state const [isSearchDialogOpen, setIsSearchDialogOpen] = useState(false); const { selectChat } = useSelectChat(); // Update selectedChatId when route changes useEffect(() => { if (isChatRoute) { const id = routerState.location.search.id; if (id) { console.log("Setting selected chat id to", id); setSelectedChatId(id); } } }, [isChatRoute, routerState.location.search, setSelectedChatId]); if (!show) { return; } const handleChatClick = ({ chatId, appId, }: { chatId: number; appId: number; }) => { selectChat({ chatId, appId }); setIsSearchDialogOpen(false); }; const handleNewChat = async () => { // Only create a new chat if an app is selected if (selectedAppId) { try { // Create a new chat with an empty title for now const chatId = await IpcClient.getInstance().createChat(selectedAppId); // Navigate to the new chat setSelectedChatId(chatId); navigate({ to: "/chat", search: { id: chatId }, }); // Refresh the chat list await refreshChats(); } catch (error) { // DO A TOAST showError(`Failed to create new chat: ${(error as any).toString()}`); } } else { // If no app is selected, navigate to home page navigate({ to: "/" }); } }; const handleDeleteChat = async (chatId: number) => { try { await IpcClient.getInstance().deleteChat(chatId); showSuccess("Chat deleted successfully"); // If the deleted chat was selected, navigate to home if (selectedChatId === chatId) { setSelectedChatId(null); navigate({ to: "/chat" }); } // Refresh the chat list await refreshChats(); } catch (error) { showError(`Failed to delete chat: ${(error as any).toString()}`); } }; const handleDeleteChatClick = (chatId: number, chatTitle: string) => { setDeleteChatId(chatId); setDeleteChatTitle(chatTitle); setIsDeleteDialogOpen(true); }; const handleConfirmDelete = async () => { if (deleteChatId !== null) { await handleDeleteChat(deleteChatId); setIsDeleteDialogOpen(false); setDeleteChatId(null); setDeleteChatTitle(""); } }; const handleRenameChat = (chatId: number, currentTitle: string) => { setRenameChatId(chatId); setRenameChatTitle(currentTitle); setIsRenameDialogOpen(true); }; const handleRenameDialogClose = (open: boolean) => { setIsRenameDialogOpen(open); if (!open) { setRenameChatId(null); setRenameChatTitle(""); } }; return ( <> Recent Chats
{loading ? (
Loading chats...
) : chats.length === 0 ? (
No chats found
) : ( {chats.map((chat) => (
{selectedChatId === chat.id && ( setIsDropdownOpen(open)} > handleRenameChat(chat.id, chat.title || "") } className="px-3 py-2" > Rename Chat handleDeleteChatClick( chat.id, chat.title || "New Chat", ) } className="px-3 py-2 text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-950/50 focus:bg-red-50 dark:focus:bg-red-950/50" > Delete Chat )}
))}
)}
{/* Rename Chat Dialog */} {renameChatId !== null && ( )} {/* Delete Chat Dialog */} {/* Chat Search Dialog */} ); }