/* El puente entre el HUD y el nucleo, por WebSocket. * * En la version sobre Newelle el HUD vivia dentro de un widget WebKit y hablaba * por window.webkit.messageHandlers. Fuera del flatpak no hay tal widget, pero * hud.js usa ese puente en ocho sitios y no merece la pena tocarlos: aqui se * SUPLANTA window.webkit con un objeto que manda lo mismo por el socket. * * Asi hud.js se queda exactamente igual que estaba —cero diff sobre 2.064 * lineas que ya funcionaban— y ademas sigue abriendose suelto en un navegador * para mirar el diseño, que es como se ha estado trabajando en el. * * Este fichero se carga ANTES que hud.js: cuando hud.js pregunte por * window.webkit, ya esta. */ (function () { "use strict"; // Ya estamos dentro de WebKit (queda de la epoca de Newelle): no tocar nada. if (window.webkit && window.webkit.messageHandlers) return; const URL = "ws://" + (location.host || "127.0.0.1:8790") + "/puente"; let socket = null; let cola = []; // lo que se pulse antes de que abra el socket let esperaReconexion = 500; function manda(canal, dato) { const mensaje = JSON.stringify({ canal: canal, dato: String(dato) }); if (socket && socket.readyState === WebSocket.OPEN) { socket.send(mensaje); } else { // No se pierde: un boton pulsado mientras reconecta tiene que llegar // igual, o el panel parece que se ha colgado. Con tope, que si el nucleo // esta caido de verdad no queremos acumular mil pulsaciones. if (cola.length < 50) cola.push(mensaje); } } // El mismo interfaz que ofrecia WebKit, para que hud.js no note el cambio. window.webkit = { messageHandlers: { accion: { postMessage: (d) => manda("accion", d) }, listo: { postMessage: (d) => manda("listo", d) }, }, }; function conecta() { try { socket = new WebSocket(URL); } catch (e) { reintenta(); return; } socket.addEventListener("open", () => { esperaReconexion = 500; marcaCaido(false); const pendientes = cola; cola = []; pendientes.forEach((m) => socket.send(m)); }); socket.addEventListener("message", (ev) => { let mensaje; try { mensaje = JSON.parse(ev.data); } catch (e) { return; } // El formato {tipo, datos} es el mismo que empujaba Python por // evaluate_javascript, asi que recibe() no cambia. if (window.jarvis && window.jarvis.recibe) window.jarvis.recibe(mensaje); }); socket.addEventListener("close", () => { marcaCaido(true); reintenta(); }); socket.addEventListener("error", () => { try { socket.close(); } catch (e) {} }); } function reintenta() { // Espera creciente hasta 8 s: reintentar cada 500 ms contra un nucleo // parado calienta el portatil para nada. setTimeout(conecta, esperaReconexion); esperaReconexion = Math.min(esperaReconexion * 2, 8000); } // Que se vea que el panel esta hablando solo. Un HUD con datos congelados y // sin avisar es peor que uno que dice claramente que perdio el hilo. function marcaCaido(caido) { document.documentElement.classList.toggle("sin-nucleo", caido); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", conecta); } else { conecta(); } })();