Files
coco-app/src/pages/chat/index.tsx

196 lines
5.8 KiB
TypeScript
Raw Normal View History

import { useState, useRef, useEffect } from "react";
import { invoke } from "@tauri-apps/api/core";
2025-02-20 15:38:55 +08:00
import ChatAI, { ChatAIRef } from "@/components/Assistant/Chat";
import { ChatInput } from "@/components/Assistant/ChatInput";
import { Sidebar } from "@/components/Assistant/Sidebar";
2025-02-20 15:38:55 +08:00
import type { Chat } from "@/components/Assistant/types";
2025-02-26 10:20:53 +08:00
import { useConnectStore } from "@/stores/connectStore";
2025-02-20 15:38:55 +08:00
interface ChatProps {}
2025-02-20 15:38:55 +08:00
export default function Chat({}: ChatProps) {
2025-02-26 10:20:53 +08:00
const currentService = useConnectStore((state) => state.currentService);
2025-02-20 15:38:55 +08:00
const chatAIRef = useRef<ChatAIRef>(null);
const [chats, setChats] = useState<Chat[]>([]);
const [activeChat, setActiveChat] = useState<Chat>();
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
const [isTyping, setIsTyping] = useState(false);
const [curChatEnd, setCurChatEnd] = useState(true);
2024-11-27 19:41:54 +08:00
const [isSearchActive, setIsSearchActive] = useState(false);
const [isDeepThinkActive, setIsDeepThinkActive] = useState(false);
useEffect(() => {
getChatHistory();
}, []);
const getChatHistory = async () => {
try {
let response: any = await invoke("chat_history", {
2025-02-26 10:20:53 +08:00
serverId: currentService?.id,
2025-02-26 09:27:51 +08:00
from: 0,
size: 20,
});
2025-02-26 10:20:53 +08:00
response = JSON.parse(response || "");
console.log("_history", response);
const hits = response?.hits?.hits || [];
setChats(hits);
if (hits[0]) {
onSelectChat(hits[0]);
} else {
2025-02-20 15:38:55 +08:00
chatAIRef.current?.init("");
}
} catch (error) {
console.error("Failed to fetch user data:", error);
}
};
const deleteChat = (chatId: string) => {
setChats((prev) => prev.filter((chat) => chat._id !== chatId));
if (activeChat?._id === chatId) {
const remainingChats = chats.filter((chat) => chat._id !== chatId);
if (remainingChats.length > 0) {
setActiveChat(remainingChats[0]);
} else {
2025-02-20 15:38:55 +08:00
chatAIRef.current?.init("");
}
}
};
const handleSendMessage = async (content: string) => {
chatAIRef.current?.init(content);
};
const chatHistory = async (chat: Chat) => {
try {
let response: any = await invoke("session_chat_history", {
2025-02-26 10:20:53 +08:00
serverId: currentService?.id,
sessionId: chat?._id,
from: 0,
size: 20,
});
2025-02-26 10:20:53 +08:00
response = JSON.parse(response || "");
console.log("id_history", response);
const hits = response?.hits?.hits || [];
const updatedChat: Chat = {
...chat,
messages: hits,
};
setActiveChat(updatedChat);
} catch (error) {
console.error("Failed to fetch user data:", error);
}
};
const chatClose = async () => {
if (!activeChat?._id) return;
try {
let response: any = await invoke("close_session_chat", {
2025-02-26 10:20:53 +08:00
serverId: currentService?.id,
sessionId: activeChat?._id,
});
2025-02-26 10:20:53 +08:00
response = JSON.parse(response || "");
console.log("_close", response);
} catch (error) {
console.error("Failed to fetch user data:", error);
}
};
const onSelectChat = async (chat: any) => {
chatClose();
try {
let response: any = await invoke("open_session_chat", {
2025-02-26 10:20:53 +08:00
serverId: currentService?.id,
sessionId: chat?._id,
});
2025-02-26 10:20:53 +08:00
response = JSON.parse(response || "");
console.log("_open", response);
chatHistory(response);
} catch (error) {
console.error("Failed to fetch user data:", error);
}
};
const cancelChat = async () => {
if (!activeChat?._id) return;
try {
let response: any = await invoke("cancel_session_chat", {
2025-02-26 10:20:53 +08:00
serverId: currentService?.id,
sessionId: activeChat?._id,
});
2025-02-26 10:20:53 +08:00
response = JSON.parse(response || "");
console.log("_cancel", response);
} catch (error) {
console.error("Failed to fetch user data:", error);
}
};
2025-02-26 09:27:51 +08:00
const clearChat = () => {
chatClose();
setActiveChat(undefined);
2025-02-26 10:20:53 +08:00
};
2025-02-26 09:27:51 +08:00
return (
2024-11-27 19:41:54 +08:00
<div className="h-screen">
<div className="h-[100%] flex">
{/* Sidebar */}
2024-11-12 09:44:49 +08:00
{isSidebarOpen ? (
<div
className={`fixed inset-y-0 left-0 z-50 w-64 transform ${
isSidebarOpen ? "translate-x-0" : "-translate-x-full"
2024-11-27 19:41:54 +08:00
} transition-transform duration-300 ease-in-out md:translate-x-0 md:static md:block bg-gray-100 dark:bg-gray-800`}
2024-11-12 09:44:49 +08:00
>
2025-02-26 09:27:51 +08:00
<Sidebar
chats={chats}
activeChat={activeChat}
onNewChat={() => {
chatAIRef.current?.clearChat();
}}
onSelectChat={onSelectChat}
onDeleteChat={deleteChat}
/>
2024-11-12 09:44:49 +08:00
</div>
) : null}
{/* Main content */}
2024-11-27 19:41:54 +08:00
<div className={`flex-1 flex flex-col bg-white dark:bg-gray-900`}>
{/* Chat messages */}
2025-02-20 15:38:55 +08:00
<ChatAI
ref={chatAIRef}
key="ChatAI"
activeChatProp={activeChat}
isTransitioned={true}
isSearchActive={isSearchActive}
isDeepThinkActive={isDeepThinkActive}
2025-02-24 18:42:49 +08:00
setIsSidebarOpen={setIsSidebarOpen}
isSidebarOpen={isSidebarOpen}
2025-02-26 09:27:51 +08:00
clearChatPage={clearChat}
2025-02-20 15:38:55 +08:00
/>
{/* Input area */}
<div className={`border-t p-4 border-gray-200 dark:border-gray-800`}>
<ChatInput
onSend={handleSendMessage}
disabled={isTyping}
2024-11-27 19:41:54 +08:00
curChatEnd={curChatEnd}
disabledChange={() => {
cancelChat();
2024-11-27 19:41:54 +08:00
setCurChatEnd(true);
setIsTyping(false);
2024-11-14 09:39:22 +08:00
}}
isSearchActive={isSearchActive}
setIsSearchActive={() => setIsSearchActive((prev) => !prev)}
isDeepThinkActive={isDeepThinkActive}
setIsDeepThinkActive={() => setIsDeepThinkActive((prev) => !prev)}
/>
</div>
</div>
</div>
</div>
);
}