From af1543135d42adc2e97dc5243aeef7418cd3b00d Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Sat, 07 Mar 2026 08:39:26 +0100
Subject: [PATCH] feat: dual address auto-switch, custom icon, notifications, image support

---
 contexts/ConnectionContext.tsx |   36 ++++++++++++++++++++++++++++++++----
 1 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/contexts/ConnectionContext.tsx b/contexts/ConnectionContext.tsx
index 860ec59..e01d867 100644
--- a/contexts/ConnectionContext.tsx
+++ b/contexts/ConnectionContext.tsx
@@ -14,6 +14,7 @@
   WsOutgoing,
 } from "../types";
 import { wsClient } from "../services/websocket";
+import { sendWol, isValidMac } from "../services/wol";
 
 const SECURE_STORE_KEY = "pailot_server_config";
 
@@ -24,6 +25,7 @@
   disconnect: () => void;
   sendTextMessage: (text: string) => boolean;
   sendVoiceMessage: (audioBase64: string, transcript?: string) => boolean;
+  sendImageMessage: (imageBase64: string, caption: string, mimeType: string) => boolean;
   sendCommand: (command: string, args?: Record<string, unknown>) => boolean;
   saveServerConfig: (config: ServerConfig) => Promise<void>;
   onMessageReceived: React.MutableRefObject<
@@ -52,7 +54,14 @@
       onClose: () => setStatus("disconnected"),
       onError: () => setStatus("disconnected"),
       onMessage: (data) => {
-        onMessageReceived.current?.(data as WsIncoming);
+        const msg = data as unknown as WsIncoming;
+        // Handle server-side status changes (compaction indicator)
+        if (msg.type === "status") {
+          if (msg.status === "compacting") setStatus("compacting");
+          else if (msg.status === "online") setStatus("connected");
+          return;
+        }
+        onMessageReceived.current?.(msg);
       },
     });
   }, []);
@@ -70,10 +79,21 @@
     }
   }
 
-  function connectToServer(config: ServerConfig) {
+  async function connectToServer(config: ServerConfig) {
     setStatus("connecting");
-    const url = `ws://${config.host}:${config.port}`;
-    wsClient.connect(url);
+
+    // Fire-and-forget WoL — never block the WebSocket connection
+    if (config.macAddress && isValidMac(config.macAddress)) {
+      sendWol(config.macAddress, config.host).catch(() => {});
+    }
+
+    // Build URL list: local first (preferred), then remote
+    const urls: string[] = [];
+    if (config.localHost) {
+      urls.push(`ws://${config.localHost}:${config.port}`);
+    }
+    urls.push(`ws://${config.host}:${config.port}`);
+    wsClient.connect(urls);
   }
 
   const connect = useCallback(
@@ -110,6 +130,13 @@
     []
   );
 
+  const sendImageMessage = useCallback(
+    (imageBase64: string, caption: string = "", mimeType: string = "image/jpeg"): boolean => {
+      return wsClient.send({ type: "image", imageBase64, caption, mimeType });
+    },
+    []
+  );
+
   const sendCommand = useCallback(
     (command: string, args?: Record<string, unknown>): boolean => {
       const msg: WsOutgoing = { type: "command", command, args };
@@ -127,6 +154,7 @@
         disconnect,
         sendTextMessage,
         sendVoiceMessage,
+        sendImageMessage,
         sendCommand,
         saveServerConfig,
         onMessageReceived,

--
Gitblit v1.3.1