2024-11-03 17:02:13 +08:00
|
|
|
import { useState, useRef, useEffect } from "react";
|
2025-02-25 17:34:10 +08:00
|
|
|
import { invoke } from "@tauri-apps/api/core";
|
2024-11-03 17:02:13 +08:00
|
|
|
|
2025-02-20 15:38:55 +08:00
|
|
|
import ChatAI, { ChatAIRef } from "@/components/Assistant/Chat";
|
2025-02-17 16:37:33 +08:00
|
|
|
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";
|
2024-11-03 17:02:13 +08:00
|
|
|
|
2025-02-20 15:38:55 +08:00
|
|
|
interface ChatProps {}
|
2024-11-03 17:02:13 +08:00
|
|
|
|
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-01-05 09:38:12 +08:00
|
|
|
|
2025-02-20 15:38:55 +08:00
|
|
|
const chatAIRef = useRef<ChatAIRef>(null);
|
2025-01-09 15:46:34 +08:00
|
|
|
|
2024-11-09 11:30:36 +08:00
|
|
|
const [chats, setChats] = useState<Chat[]>([]);
|
|
|
|
|
const [activeChat, setActiveChat] = useState<Chat>();
|
2024-11-20 10:08:08 +08:00
|
|
|
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
|
2024-11-03 17:02:13 +08:00
|
|
|
const [isTyping, setIsTyping] = useState(false);
|
|
|
|
|
|
2024-11-09 11:30:36 +08:00
|
|
|
const [curChatEnd, setCurChatEnd] = useState(true);
|
2024-11-27 19:41:54 +08:00
|
|
|
|
2025-02-13 23:01:21 +08:00
|
|
|
const [isSearchActive, setIsSearchActive] = useState(false);
|
2025-02-17 16:37:33 +08:00
|
|
|
const [isDeepThinkActive, setIsDeepThinkActive] = useState(false);
|
2025-02-13 23:01:21 +08:00
|
|
|
|
2024-11-09 11:30:36 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
getChatHistory();
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const getChatHistory = async () => {
|
|
|
|
|
try {
|
2025-02-25 17:34:10 +08:00
|
|
|
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,
|
2024-11-09 11:30:36 +08:00
|
|
|
});
|
2025-02-26 10:20:53 +08:00
|
|
|
response = JSON.parse(response || "");
|
2024-11-09 11:30:36 +08:00
|
|
|
console.log("_history", response);
|
2025-02-25 17:34:10 +08:00
|
|
|
const hits = response?.hits?.hits || [];
|
2024-11-09 11:30:36 +08:00
|
|
|
setChats(hits);
|
|
|
|
|
if (hits[0]) {
|
|
|
|
|
onSelectChat(hits[0]);
|
|
|
|
|
} else {
|
2025-02-20 15:38:55 +08:00
|
|
|
chatAIRef.current?.init("");
|
2024-11-09 11:30:36 +08:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to fetch user data:", error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-11-03 17:02:13 +08:00
|
|
|
const deleteChat = (chatId: string) => {
|
2024-11-09 11:30:36 +08:00
|
|
|
setChats((prev) => prev.filter((chat) => chat._id !== chatId));
|
|
|
|
|
if (activeChat?._id === chatId) {
|
|
|
|
|
const remainingChats = chats.filter((chat) => chat._id !== chatId);
|
2024-11-03 17:02:13 +08:00
|
|
|
if (remainingChats.length > 0) {
|
|
|
|
|
setActiveChat(remainingChats[0]);
|
|
|
|
|
} else {
|
2025-02-20 15:38:55 +08:00
|
|
|
chatAIRef.current?.init("");
|
2024-11-03 17:02:13 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-11-09 11:30:36 +08:00
|
|
|
const handleSendMessage = async (content: string) => {
|
2025-03-03 20:51:45 +08:00
|
|
|
chatAIRef.current?.init(content);
|
2024-11-09 11:30:36 +08:00
|
|
|
};
|
2024-11-03 17:02:13 +08:00
|
|
|
|
2024-11-09 11:30:36 +08:00
|
|
|
const chatHistory = async (chat: Chat) => {
|
|
|
|
|
try {
|
2025-02-25 17:34:10 +08:00
|
|
|
let response: any = await invoke("session_chat_history", {
|
2025-02-26 10:20:53 +08:00
|
|
|
serverId: currentService?.id,
|
2025-02-25 17:34:10 +08:00
|
|
|
sessionId: chat?._id,
|
|
|
|
|
from: 0,
|
|
|
|
|
size: 20,
|
2024-11-09 11:30:36 +08:00
|
|
|
});
|
2025-02-26 10:20:53 +08:00
|
|
|
response = JSON.parse(response || "");
|
2024-11-09 11:30:36 +08:00
|
|
|
console.log("id_history", response);
|
2025-02-25 17:34:10 +08:00
|
|
|
const hits = response?.hits?.hits || [];
|
2024-11-09 11:30:36 +08:00
|
|
|
const updatedChat: Chat = {
|
|
|
|
|
...chat,
|
|
|
|
|
messages: hits,
|
2024-11-03 17:02:13 +08:00
|
|
|
};
|
2024-11-09 11:30:36 +08:00
|
|
|
setActiveChat(updatedChat);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to fetch user data:", error);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-11-03 17:02:13 +08:00
|
|
|
|
2024-11-09 11:30:36 +08:00
|
|
|
const chatClose = async () => {
|
|
|
|
|
if (!activeChat?._id) return;
|
|
|
|
|
try {
|
2025-02-25 17:34:10 +08:00
|
|
|
let response: any = await invoke("close_session_chat", {
|
2025-02-26 10:20:53 +08:00
|
|
|
serverId: currentService?.id,
|
2025-02-25 17:34:10 +08:00
|
|
|
sessionId: activeChat?._id,
|
2024-11-09 11:30:36 +08:00
|
|
|
});
|
2025-02-26 10:20:53 +08:00
|
|
|
response = JSON.parse(response || "");
|
2024-11-09 11:30:36 +08:00
|
|
|
console.log("_close", response);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to fetch user data:", error);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-11-03 17:02:13 +08:00
|
|
|
|
2024-11-09 11:30:36 +08:00
|
|
|
const onSelectChat = async (chat: any) => {
|
|
|
|
|
chatClose();
|
|
|
|
|
try {
|
2025-02-25 17:34:10 +08:00
|
|
|
let response: any = await invoke("open_session_chat", {
|
2025-02-26 10:20:53 +08:00
|
|
|
serverId: currentService?.id,
|
2025-02-25 17:34:10 +08:00
|
|
|
sessionId: chat?._id,
|
2024-11-09 11:30:36 +08:00
|
|
|
});
|
2025-02-26 10:20:53 +08:00
|
|
|
response = JSON.parse(response || "");
|
2024-11-09 11:30:36 +08:00
|
|
|
console.log("_open", response);
|
2025-02-25 17:34:10 +08:00
|
|
|
chatHistory(response);
|
2024-11-20 10:08:08 +08:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to fetch user data:", error);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-11-24 19:25:47 +08:00
|
|
|
|
2024-11-20 10:08:08 +08:00
|
|
|
const cancelChat = async () => {
|
|
|
|
|
if (!activeChat?._id) return;
|
|
|
|
|
try {
|
2025-02-25 17:34:10 +08:00
|
|
|
let response: any = await invoke("cancel_session_chat", {
|
2025-02-26 10:20:53 +08:00
|
|
|
serverId: currentService?.id,
|
2025-02-25 17:34:10 +08:00
|
|
|
sessionId: activeChat?._id,
|
2024-11-20 10:08:08 +08:00
|
|
|
});
|
2025-02-26 10:20:53 +08:00
|
|
|
response = JSON.parse(response || "");
|
2024-11-20 10:08:08 +08:00
|
|
|
console.log("_cancel", response);
|
2024-11-09 11:30:36 +08:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to fetch user data:", error);
|
|
|
|
|
}
|
2024-11-03 17:02:13 +08:00
|
|
|
};
|
|
|
|
|
|
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
|
|
|
|
2024-11-03 17:02:13 +08:00
|
|
|
return (
|
2024-11-27 19:41:54 +08:00
|
|
|
<div className="h-screen">
|
2024-11-03 17:02:13 +08:00
|
|
|
<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}
|
2024-11-03 17:02:13 +08:00
|
|
|
|
|
|
|
|
{/* Main content */}
|
2024-11-27 19:41:54 +08:00
|
|
|
<div className={`flex-1 flex flex-col bg-white dark:bg-gray-900`}>
|
2024-11-03 17:02:13 +08:00
|
|
|
{/* 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
|
|
|
/>
|
2024-11-03 17:02:13 +08:00
|
|
|
|
|
|
|
|
{/* Input area */}
|
2024-11-24 19:25:47 +08:00
|
|
|
<div className={`border-t p-4 border-gray-200 dark:border-gray-800`}>
|
2024-11-09 11:30:36 +08:00
|
|
|
<ChatInput
|
|
|
|
|
onSend={handleSendMessage}
|
|
|
|
|
disabled={isTyping}
|
2024-11-27 19:41:54 +08:00
|
|
|
curChatEnd={curChatEnd}
|
|
|
|
|
disabledChange={() => {
|
2024-11-24 19:25:47 +08:00
|
|
|
cancelChat();
|
2024-11-27 19:41:54 +08:00
|
|
|
setCurChatEnd(true);
|
|
|
|
|
setIsTyping(false);
|
2024-11-14 09:39:22 +08:00
|
|
|
}}
|
2025-02-13 23:01:21 +08:00
|
|
|
isSearchActive={isSearchActive}
|
|
|
|
|
setIsSearchActive={() => setIsSearchActive((prev) => !prev)}
|
2025-02-17 16:37:33 +08:00
|
|
|
isDeepThinkActive={isDeepThinkActive}
|
|
|
|
|
setIsDeepThinkActive={() => setIsDeepThinkActive((prev) => !prev)}
|
2024-11-09 11:30:36 +08:00
|
|
|
/>
|
2024-11-24 19:25:47 +08:00
|
|
|
</div>
|
2024-11-03 17:02:13 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-11-24 19:25:47 +08:00
|
|
|
</div>
|
2024-11-03 17:02:13 +08:00
|
|
|
);
|
|
|
|
|
}
|