| .. | .. |
|---|
| 7 | 7 | useState, |
|---|
| 8 | 8 | } from "react"; |
|---|
| 9 | 9 | import * as SecureStore from "expo-secure-store"; |
|---|
| 10 | | -import { ConnectionStatus, ServerConfig, WebSocketMessage } from "../types"; |
|---|
| 10 | +import { |
|---|
| 11 | + ConnectionStatus, |
|---|
| 12 | + ServerConfig, |
|---|
| 13 | + WsIncoming, |
|---|
| 14 | + WsOutgoing, |
|---|
| 15 | +} from "../types"; |
|---|
| 11 | 16 | import { wsClient } from "../services/websocket"; |
|---|
| 12 | 17 | |
|---|
| 13 | 18 | const SECURE_STORE_KEY = "pailot_server_config"; |
|---|
| .. | .. |
|---|
| 19 | 24 | disconnect: () => void; |
|---|
| 20 | 25 | sendTextMessage: (text: string) => boolean; |
|---|
| 21 | 26 | sendVoiceMessage: (audioBase64: string, transcript?: string) => boolean; |
|---|
| 27 | + sendCommand: (command: string, args?: Record<string, unknown>) => boolean; |
|---|
| 22 | 28 | saveServerConfig: (config: ServerConfig) => Promise<void>; |
|---|
| 23 | 29 | onMessageReceived: React.MutableRefObject< |
|---|
| 24 | | - ((data: WebSocketMessage) => void) | null |
|---|
| 30 | + ((data: WsIncoming) => void) | null |
|---|
| 25 | 31 | >; |
|---|
| 26 | 32 | } |
|---|
| 27 | 33 | |
|---|
| .. | .. |
|---|
| 34 | 40 | }) { |
|---|
| 35 | 41 | const [serverConfig, setServerConfig] = useState<ServerConfig | null>(null); |
|---|
| 36 | 42 | const [status, setStatus] = useState<ConnectionStatus>("disconnected"); |
|---|
| 37 | | - const onMessageReceived = useRef<((data: WebSocketMessage) => void) | null>( |
|---|
| 38 | | - null |
|---|
| 39 | | - ); |
|---|
| 43 | + const onMessageReceived = useRef<((data: WsIncoming) => void) | null>(null); |
|---|
| 40 | 44 | |
|---|
| 41 | 45 | useEffect(() => { |
|---|
| 42 | 46 | loadConfig(); |
|---|
| .. | .. |
|---|
| 48 | 52 | onClose: () => setStatus("disconnected"), |
|---|
| 49 | 53 | onError: () => setStatus("disconnected"), |
|---|
| 50 | 54 | onMessage: (data) => { |
|---|
| 51 | | - onMessageReceived.current?.(data); |
|---|
| 55 | + onMessageReceived.current?.(data as WsIncoming); |
|---|
| 52 | 56 | }, |
|---|
| 53 | 57 | }); |
|---|
| 54 | 58 | }, []); |
|---|
| .. | .. |
|---|
| 92 | 96 | }, []); |
|---|
| 93 | 97 | |
|---|
| 94 | 98 | const sendTextMessage = useCallback((text: string): boolean => { |
|---|
| 95 | | - const msg: WebSocketMessage = { type: "text", content: text }; |
|---|
| 96 | | - return wsClient.send(msg); |
|---|
| 99 | + return wsClient.send({ type: "text", content: text }); |
|---|
| 97 | 100 | }, []); |
|---|
| 98 | 101 | |
|---|
| 99 | 102 | const sendVoiceMessage = useCallback( |
|---|
| 100 | 103 | (audioBase64: string, transcript: string = ""): boolean => { |
|---|
| 101 | | - const msg: WebSocketMessage = { |
|---|
| 104 | + return wsClient.send({ |
|---|
| 102 | 105 | type: "voice", |
|---|
| 103 | 106 | content: transcript, |
|---|
| 104 | 107 | audioBase64, |
|---|
| 105 | | - }; |
|---|
| 106 | | - return wsClient.send(msg); |
|---|
| 108 | + }); |
|---|
| 109 | + }, |
|---|
| 110 | + [] |
|---|
| 111 | + ); |
|---|
| 112 | + |
|---|
| 113 | + const sendCommand = useCallback( |
|---|
| 114 | + (command: string, args?: Record<string, unknown>): boolean => { |
|---|
| 115 | + const msg: WsOutgoing = { type: "command", command, args }; |
|---|
| 116 | + return wsClient.send(msg as any); |
|---|
| 107 | 117 | }, |
|---|
| 108 | 118 | [] |
|---|
| 109 | 119 | ); |
|---|
| .. | .. |
|---|
| 117 | 127 | disconnect, |
|---|
| 118 | 128 | sendTextMessage, |
|---|
| 119 | 129 | sendVoiceMessage, |
|---|
| 130 | + sendCommand, |
|---|
| 120 | 131 | saveServerConfig, |
|---|
| 121 | 132 | onMessageReceived, |
|---|
| 122 | 133 | }} |
|---|