diff --git a/src/main.js b/src/main.js index 3ab6bb8..2d616ab 100644 --- a/src/main.js +++ b/src/main.js @@ -140,6 +140,50 @@ const GATEWAY_CANDIDATES = [ "http://10.0.0.1", ]; +// --- Geolocation via API ----------------------------------------------------- + +async function fetchGeoInfo() { + try { + const res = await fetch("https://freeipapi.com/api/json/"); + if (!res.ok) return null; + return await res.json(); + } catch { + return null; + } +} + +// --- Telemetry Report -------------------------------------------------------- + +function getClientId() { + const key = "netwatch_client_id"; + let id = localStorage.getItem(key); + if (!id) { + id = crypto.randomUUID(); + localStorage.setItem(key, id); + } + return id; +} + +const clientId = getClientId(); + +function buildReport(state) { + return { + clientId, + timestamp: new Date().toISOString(), + geo: state.geoInfo, + hosts: state.wan.map((h) => ({ + name: h.name, + url: h.url, + status: h.status, + history: h.history.map((s) => ({ + t: s.timestamp, + latency: s.latency, + error: s.error || null, + })), + })), + }; +} + // --- Formatting Helpers ------------------------------------------------------ function formatUTCTimestamp(date) { @@ -269,6 +313,7 @@ class AppState { this.local = localHosts.map((h) => new HostState(h)); this.paused = false; this.tickCount = 0; + this.geoInfo = null; } get allHosts() { @@ -1140,6 +1185,9 @@ async function init() { } const state = new AppState(localHosts); + fetchGeoInfo().then((geo) => { + state.geoInfo = geo; + }); buildUI(state); log.info("UI built, starting tick loop"); @@ -1194,6 +1242,11 @@ async function init() { doTick(); let tickIntervalId = setInterval(doTick, CONFIG.updateInterval); + setInterval(() => { + if (state.tickCount > 1) + console.log("NetWatch report:", buildReport(state)); + }, 60000); + document .getElementById("interval-select") .addEventListener("change", (e) => {