multica/apps/desktop/src/hooks/use-devices.ts
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

67 lines
1.6 KiB
TypeScript

import { useState, useEffect, useCallback } from 'react'
export interface DeviceMeta {
userAgent?: string
platform?: string
language?: string
}
export interface DeviceEntry {
deviceId: string
agentId: string
addedAt: number
meta?: DeviceMeta
}
export interface UseDevicesReturn {
devices: DeviceEntry[]
loading: boolean
refresh: () => Promise<void>
revokeDevice: (deviceId: string) => Promise<boolean>
}
export function useDevices(): UseDevicesReturn {
const [devices, setDevices] = useState<DeviceEntry[]>([])
const [loading, setLoading] = useState(true)
const refresh = useCallback(async () => {
try {
const list = await window.electronAPI?.hub.listDevices()
setDevices((list as DeviceEntry[]) ?? [])
} catch (err) {
console.error('Failed to load devices:', err)
} finally {
setLoading(false)
}
}, [])
const revokeDevice = useCallback(async (deviceId: string): Promise<boolean> => {
try {
const result = await window.electronAPI?.hub.revokeDevice(deviceId)
if (result?.ok) {
setDevices((prev) => prev.filter((d) => d.deviceId !== deviceId))
return true
}
return false
} catch (err) {
console.error('Failed to revoke device:', err)
return false
}
}, [])
useEffect(() => {
refresh()
}, [refresh])
// Subscribe to device list changes pushed from main process
useEffect(() => {
window.electronAPI?.hub.onDevicesChanged(() => {
refresh()
})
return () => {
window.electronAPI?.hub.offDevicesChanged()
}
}, [refresh])
return { devices, loading, refresh, revokeDevice }
}