multica/apps/desktop/src/components/remote-chat.tsx
Naiyuan Qing 607adeb667 feat(desktop): implement local chat with direct IPC and mode switching
Add LocalChat component using useLocalChat hook that communicates with
the Hub via IPC (no Gateway required). Fix streamId extraction to use
event.message.id matching Hub behavior. Fix history to return raw
AgentMessageItem[] instead of flattened strings. Add exec approval
forwarding over IPC. Use conditional rendering for LocalChat to prevent
event leaking from remote sessions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:50:55 +08:00

51 lines
1.5 KiB
TypeScript

import { Loading } from '@multica/ui/components/ui/loading'
import { ChatView } from '@multica/ui/components/chat-view'
import { DevicePairing } from '@multica/ui/components/device-pairing'
import { useGatewayChat } from '@multica/hooks/use-gateway-chat'
import type { UseGatewayConnectionReturn } from '@multica/hooks/use-gateway-connection'
export function RemoteChat({ gateway }: { gateway: UseGatewayConnectionReturn }) {
const { pageState, connectionState, error, client, identity, pairingKey, connect, disconnect } = gateway
return (
<div className="h-full flex flex-col overflow-hidden w-full">
{pageState === 'loading' && (
<div className="flex-1 flex items-center justify-center gap-2 text-muted-foreground text-sm">
<Loading />
Loading...
</div>
)}
{(pageState === 'not-connected' || pageState === 'connecting') && (
<DevicePairing
key={pairingKey}
connectionState={connectionState}
lastError={error}
onConnect={connect}
onCancel={disconnect}
/>
)}
{pageState === 'connected' && client && identity && (
<ConnectedChat
client={client}
hubId={identity.hubId}
agentId={identity.agentId}
/>
)}
</div>
)
}
function ConnectedChat({
client,
hubId,
agentId,
}: {
client: NonNullable<UseGatewayConnectionReturn['client']>
hubId: string
agentId: string
}) {
const chat = useGatewayChat({ client, hubId, agentId })
return <ChatView {...chat} />
}