mirror of
https://github.com/infinilabs/coco-app.git
synced 2025-12-16 11:37:47 +01:00
fix: chat params (#164)
This commit is contained in:
@@ -8,7 +8,6 @@ import {
|
||||
useState,
|
||||
useMemo,
|
||||
} from "react";
|
||||
import { MessageSquarePlus, PanelLeft } from "lucide-react";
|
||||
import { isTauri } from "@tauri-apps/api/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { debounce } from "lodash-es";
|
||||
@@ -20,7 +19,7 @@ import { useWebSocket } from "@/hooks/useWebSocket";
|
||||
import { useChatStore } from "@/stores/chatStore";
|
||||
import { useWindows } from "@/hooks/useWindows";
|
||||
import { clientEnv } from "@/utils/env";
|
||||
|
||||
import { ChatHeader } from "./ChatHeader";
|
||||
interface ChatAIProps {
|
||||
isTransitioned: boolean;
|
||||
isSearchActive?: boolean;
|
||||
@@ -249,7 +248,7 @@ const ChatAI = memo(
|
||||
console.error("Failed to fetch user data:", error);
|
||||
}
|
||||
},
|
||||
[activeChat?._id]
|
||||
[activeChat?._id, isSearchActive, isDeepThinkActive]
|
||||
);
|
||||
|
||||
const chatClose = async () => {
|
||||
@@ -327,26 +326,10 @@ const ChatAI = memo(
|
||||
className={`h-full flex flex-col rounded-xl overflow-hidden`}
|
||||
>
|
||||
{isChatPage ? null : (
|
||||
<header
|
||||
data-tauri-drag-region
|
||||
className={`flex items-center justify-between py-2 px-1`}
|
||||
>
|
||||
<button
|
||||
onClick={() => openChatAI()}
|
||||
className={`p-2 rounded-lg transition-colors text-[#333] dark:text-[#d8d8d8]`}
|
||||
>
|
||||
<PanelLeft className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
createNewChat();
|
||||
}}
|
||||
className={`p-2 rounded-lg transition-colors text-[#333] dark:text-[#d8d8d8]`}
|
||||
>
|
||||
<MessageSquarePlus className="h-4 w-4" />
|
||||
</button>
|
||||
</header>
|
||||
<ChatHeader
|
||||
onCreateNewChat={createNewChat}
|
||||
onOpenChatAI={openChatAI}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Chat messages */}
|
||||
|
||||
127
src/components/Assistant/ChatHeader.tsx
Normal file
127
src/components/Assistant/ChatHeader.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
import { MessageSquarePlus, PanelLeft, Pin, MoreHorizontal } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Listbox, Popover } from "@headlessui/react";
|
||||
|
||||
interface Server {
|
||||
id: string;
|
||||
name: string;
|
||||
status: 'online' | 'offline';
|
||||
assistantCount: number;
|
||||
}
|
||||
|
||||
interface ChatHeaderProps {
|
||||
onCreateNewChat: () => void;
|
||||
onOpenChatAI: () => void;
|
||||
}
|
||||
|
||||
export function ChatHeader({ onCreateNewChat, onOpenChatAI }: ChatHeaderProps) {
|
||||
const [isPinned, setIsPinned] = useState(false);
|
||||
const [showAI] = useState(false);
|
||||
const [servers] = useState<Server[]>([
|
||||
{ id: '1', name: 'Coco Cloud', status: 'online', assistantCount: 3 },
|
||||
{ id: '2', name: 'Searchkit', status: 'online', assistantCount: 3 },
|
||||
{ id: '3', name: 'INFINI Labs', status: 'online', assistantCount: 2 },
|
||||
{ id: '4', name: 'Test server', status: 'offline', assistantCount: 1 },
|
||||
]);
|
||||
const [selectedServer, setSelectedServer] = useState(servers[0]);
|
||||
|
||||
return (
|
||||
<header className="flex items-center justify-between py-2 px-3" data-tauri-drag-region>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={onOpenChatAI}
|
||||
className="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
|
||||
>
|
||||
<PanelLeft className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
{showAI ? <Listbox value={selectedServer} onChange={setSelectedServer}>
|
||||
<div className="relative">
|
||||
<Listbox.Button className="relative w-48 h-8 px-3 py-1 text-left bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<div className="flex items-center gap-2">
|
||||
<img src="/path-to-server-icon.png" className="w-4 h-4 rounded-full" />
|
||||
<span className="block truncate">{selectedServer.name}</span>
|
||||
</div>
|
||||
</Listbox.Button>
|
||||
<Listbox.Options className="absolute w-full mt-1 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700">
|
||||
{servers.map((server) => (
|
||||
<Listbox.Option
|
||||
key={server.id}
|
||||
value={server}
|
||||
className={({ active }) =>
|
||||
`relative cursor-pointer select-none py-2 px-3 ${
|
||||
active ? 'bg-gray-100 dark:bg-gray-700' : ''
|
||||
}`
|
||||
}
|
||||
>
|
||||
<div className="flex items-center justify-between w-full">
|
||||
<div className="flex items-center gap-2">
|
||||
<img src="/path-to-server-icon.png" className="w-4 h-4 rounded-full" />
|
||||
<span>{server.name}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`w-2 h-2 rounded-full ${
|
||||
server.status === 'online' ? 'bg-green-500' : 'bg-gray-400'
|
||||
}`} />
|
||||
<span className="text-xs text-gray-500">
|
||||
AI Assistant: {server.assistantCount}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Listbox.Option>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
</div>
|
||||
</Listbox> : null}
|
||||
|
||||
<button
|
||||
onClick={onCreateNewChat}
|
||||
className="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
|
||||
>
|
||||
<MessageSquarePlus className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => setIsPinned(!isPinned)}
|
||||
className={`p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 ${
|
||||
isPinned ? 'text-blue-500' : ''
|
||||
}`}
|
||||
>
|
||||
<Pin className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
<Popover className="relative">
|
||||
<Popover.Button className="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Popover.Button>
|
||||
|
||||
<Popover.Panel className="absolute right-0 mt-2 w-60 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700">
|
||||
<div className="p-2">
|
||||
<h3 className="font-medium mb-2">Servers</h3>
|
||||
<div className="space-y-2">
|
||||
{servers.map(server => (
|
||||
<div key={server.id} className="flex items-center justify-between p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg">
|
||||
<div className="flex items-center gap-2">
|
||||
<img src="/path-to-server-icon.png" className="w-6 h-6 rounded-full" />
|
||||
<div>
|
||||
<div className="font-medium">{server.name}</div>
|
||||
<div className="text-xs text-gray-500">
|
||||
AI Assistant: {server.assistantCount}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span className={`w-2 h-2 rounded-full ${
|
||||
server.status === 'online' ? 'bg-green-500' : 'bg-gray-400'
|
||||
}`} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@@ -76,10 +76,10 @@ export function SourceResult({ text }: SourceResultProps) {
|
||||
<div
|
||||
key={idx}
|
||||
onClick={() => item.url && OpenURLWithBrowser(item.url)}
|
||||
className="group flex items-center px-2 py-1 hover:bg-[#F7F7F7] dark:hover:bg-[#2C2C2C] border-b border-[#E6E6E6] dark:border-[#272626] last:border-b-0 cursor-pointer transition-colors"
|
||||
className="group flex items-center p-2 hover:bg-[#F7F7F7] dark:hover:bg-[#2C2C2C] border-b border-[#E6E6E6] dark:border-[#272626] last:border-b-0 cursor-pointer transition-colors"
|
||||
>
|
||||
<div className="flex-1 min-w-0 flex items-center gap-2">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex-1 min-w-0 flex items-center gap-1">
|
||||
<File className="w-3 h-3" />
|
||||
<div className="text-xs text-[#333333] dark:text-[#D8D8D8] truncate font-normal group-hover:text-[#0072FF] dark:group-hover:text-[#0072FF]">
|
||||
{item.title || item.category}
|
||||
|
||||
Reference in New Issue
Block a user