Matthias Nott
2026-03-07 af1543135d42adc2e97dc5243aeef7418cd3b00d
contexts/ConnectionContext.tsx
....@@ -14,6 +14,7 @@
1414 WsOutgoing,
1515 } from "../types";
1616 import { wsClient } from "../services/websocket";
17
+import { sendWol, isValidMac } from "../services/wol";
1718
1819 const SECURE_STORE_KEY = "pailot_server_config";
1920
....@@ -24,6 +25,7 @@
2425 disconnect: () => void;
2526 sendTextMessage: (text: string) => boolean;
2627 sendVoiceMessage: (audioBase64: string, transcript?: string) => boolean;
28
+ sendImageMessage: (imageBase64: string, caption: string, mimeType: string) => boolean;
2729 sendCommand: (command: string, args?: Record<string, unknown>) => boolean;
2830 saveServerConfig: (config: ServerConfig) => Promise<void>;
2931 onMessageReceived: React.MutableRefObject<
....@@ -52,7 +54,14 @@
5254 onClose: () => setStatus("disconnected"),
5355 onError: () => setStatus("disconnected"),
5456 onMessage: (data) => {
55
- onMessageReceived.current?.(data as WsIncoming);
57
+ const msg = data as unknown as WsIncoming;
58
+ // Handle server-side status changes (compaction indicator)
59
+ if (msg.type === "status") {
60
+ if (msg.status === "compacting") setStatus("compacting");
61
+ else if (msg.status === "online") setStatus("connected");
62
+ return;
63
+ }
64
+ onMessageReceived.current?.(msg);
5665 },
5766 });
5867 }, []);
....@@ -70,10 +79,21 @@
7079 }
7180 }
7281
73
- function connectToServer(config: ServerConfig) {
82
+ async function connectToServer(config: ServerConfig) {
7483 setStatus("connecting");
75
- const url = `ws://${config.host}:${config.port}`;
76
- wsClient.connect(url);
84
+
85
+ // Fire-and-forget WoL — never block the WebSocket connection
86
+ if (config.macAddress && isValidMac(config.macAddress)) {
87
+ sendWol(config.macAddress, config.host).catch(() => {});
88
+ }
89
+
90
+ // Build URL list: local first (preferred), then remote
91
+ const urls: string[] = [];
92
+ if (config.localHost) {
93
+ urls.push(`ws://${config.localHost}:${config.port}`);
94
+ }
95
+ urls.push(`ws://${config.host}:${config.port}`);
96
+ wsClient.connect(urls);
7797 }
7898
7999 const connect = useCallback(
....@@ -110,6 +130,13 @@
110130 []
111131 );
112132
133
+ const sendImageMessage = useCallback(
134
+ (imageBase64: string, caption: string = "", mimeType: string = "image/jpeg"): boolean => {
135
+ return wsClient.send({ type: "image", imageBase64, caption, mimeType });
136
+ },
137
+ []
138
+ );
139
+
113140 const sendCommand = useCallback(
114141 (command: string, args?: Record<string, unknown>): boolean => {
115142 const msg: WsOutgoing = { type: "command", command, args };
....@@ -127,6 +154,7 @@
127154 disconnect,
128155 sendTextMessage,
129156 sendVoiceMessage,
157
+ sendImageMessage,
130158 sendCommand,
131159 saveServerConfig,
132160 onMessageReceived,