import { hostCore } from "./chunk-KL66PICH.js"; // src/plugins/sat.ts var satWindow = window; var satDom = { status: document.getElementById("sat-status"), liveView: document.getElementById("sat-live-view"), historyView: document.getElementById("sat-history-view"), liveLatest: document.getElementById("sat-live-latest"), historyList: document.getElementById("sat-history-list"), historyCount: document.getElementById("sat-history-count"), filterInput: document.getElementById("sat-filter"), sortSelect: document.getElementById("sat-sort"), typeFilter: document.getElementById("sat-type-filter"), lrptState: document.getElementById("sat-lrpt-state"), viewLiveBtn: document.getElementById("sat-view-live"), viewHistoryBtn: document.getElementById("sat-view-history") }; var satImageHistory = []; var SAT_MAX_IMAGES = 100; var satFilterText = ""; var satActiveView = "live"; function scheduleSatUi(key, job) { if (typeof satWindow.trxScheduleUiFrameJob === "function") { satWindow.trxScheduleUiFrameJob(key, job); return; } job(); } function switchSatView(view) { satActiveView = view; if (satDom.liveView) satDom.liveView.style.display = view === "live" ? "" : "none"; if (satDom.historyView) satDom.historyView.style.display = view === "history" ? "" : "none"; if (satDom.viewLiveBtn) satDom.viewLiveBtn.classList.toggle("sat-view-active", view === "live"); if (satDom.viewHistoryBtn) satDom.viewHistoryBtn.classList.toggle("sat-view-active", view === "history"); if (view === "history") renderSatHistoryTable(); } satDom.viewLiveBtn?.addEventListener("click", () => { switchSatView("live"); }); satDom.viewHistoryBtn?.addEventListener("click", () => { switchSatView("history"); }); var lastSatLrptOn = null; satWindow.updateSatLiveState = function(update) { if (!satDom.lrptState) return; const lrptOn = !!update.lrpt_decode_enabled; if (lrptOn !== lastSatLrptOn) { lastSatLrptOn = lrptOn; satDom.lrptState.textContent = lrptOn ? "Listening" : "Idle"; satDom.lrptState.className = "sat-live-value " + (lrptOn ? "sat-state-listening" : "sat-state-idle"); if (satDom.status) { if (lrptOn) { satDom.status.textContent = "Decoder active — waiting for signal"; } else { satDom.status.textContent = "Decoder idle"; } } } }; function renderSatLatestCard() { if (!satDom.liveLatest) return; if (satImageHistory.length === 0) { satDom.liveLatest.innerHTML = '
No images decoded yet. Enable a decoder and wait for a satellite pass.
'; return; } const img = satImageHistory[0]; if (!img) return; const typeName = "Meteor LRPT"; const satellite = img.satellite || ""; const channels = img.channels || img.channel_a || ""; const lines = img.mcu_count || img.line_count || 0; const unit = "MCU rows"; const ts = img._ts || "--"; const date = img._tsMs ? new Date(img._tsMs).toLocaleDateString() : ""; const meta = [typeName]; if (satellite) meta.push(satellite); if (channels) meta.push(channels); meta.push(`${lines} ${unit}`); meta.push(`${date} ${ts}`); let html = `
`; html += `
Latest decoded image
`; html += `
${meta.join(" · ")}
`; if (img.path) { html += `Download PNG`; } if (img.geo_bounds) { html += ` `; } html += `
`; satDom.liveLatest.innerHTML = html; } function getSatFilteredHistory() { let items = satImageHistory; const typeVal = satDom.typeFilter ? satDom.typeFilter.value : "all"; if (typeVal === "lrpt") items = items.filter((i) => i._decoder === "lrpt"); if (satFilterText) { items = items.filter((i) => { const haystack = [ "meteor lrpt", i.satellite || "", i.channels || "", i.channel_a || "", i.channel_b || "" ].join(" ").toUpperCase(); return haystack.includes(satFilterText); }); } const sortVal = satDom.sortSelect ? satDom.sortSelect.value : "newest"; if (sortVal === "oldest") items = items.slice().reverse(); return items; } function renderSatHistoryRow(img) { const row = document.createElement("div"); row.className = "sat-history-row"; const typeName = "Meteor LRPT"; const typeClass = "sat-type-lrpt"; const ts = img._ts || "--"; const date = img._tsMs ? new Date(img._tsMs).toLocaleDateString([], { month: "short", day: "numeric" }) : ""; const satellite = img.satellite || "--"; const channels = img.channels || "--"; const lines = img.mcu_count || img.line_count || 0; const unit = "MCU"; let link = img.path ? `PNG` : "--"; if (img.geo_bounds) { link += ` Map`; } row.innerHTML = [ `${date} ${ts}`, `${typeName}`, `${satellite}`, `${channels}`, `${lines} ${unit}`, `${link}` ].join(""); return row; } function renderSatHistoryTable() { if (!satDom.historyList) return; const items = getSatFilteredHistory(); const fragment = document.createDocumentFragment(); for (const image of items) { fragment.appendChild(renderSatHistoryRow(image)); } satDom.historyList.replaceChildren(fragment); if (satDom.historyCount) { const total = satImageHistory.length; const shown = items.length; satDom.historyCount.textContent = total === 0 ? "No images yet" : shown === total ? `${total} image${total === 1 ? "" : "s"}` : `${shown} of ${total} images`; } } function addSatImage(img, decoder) { const tsMs = Number.isFinite(img.ts_ms) ? Number(img.ts_ms) : Date.now(); img._tsMs = tsMs; img._ts = new Date(tsMs).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" }); img._decoder = decoder; satImageHistory.unshift(img); if (satImageHistory.length > SAT_MAX_IMAGES) { satImageHistory = satImageHistory.slice(0, SAT_MAX_IMAGES); } scheduleSatUi("sat-latest", () => { renderSatLatestCard(); }); if (satActiveView === "history") { scheduleSatUi("sat-history", () => { renderSatHistoryTable(); }); } } function onServerLrptProgress(msg) { if (satDom.status && (msg.mcu_count ?? 0) > 0) { satDom.status.textContent = `Receiving — ${String(msg.mcu_count ?? 0)} MCU rows decoded`; } } function onServerLrptImage(msg) { if (satDom.status) satDom.status.textContent = "Image received (Meteor LRPT)"; addSatImage(msg, "lrpt"); if (msg.geo_bounds && msg.path && satWindow.addSatMapOverlay) { satWindow.addSatMapOverlay(msg); } } function resetSatHistoryView() { satImageHistory = []; if (satDom.historyList) satDom.historyList.innerHTML = ""; renderSatLatestCard(); renderSatHistoryTable(); satWindow.clearSatMapOverlays?.(); } function pruneSatHistoryView() { renderSatHistoryTable(); renderSatLatestCard(); } satWindow.trxPluginRuntime.registerDecoder({ id: "lrpt_image", onMessage: onServerLrptImage, reset: resetSatHistoryView, prune: pruneSatHistoryView }); satWindow.trxPluginRuntime.registerDecoder({ id: "lrpt_progress", onMessage: onServerLrptProgress }); var lrptDecodeToggleBtn = document.getElementById("lrpt-decode-toggle-btn"); lrptDecodeToggleBtn?.addEventListener("click", () => { void (async () => { try { await satWindow.takeSchedulerControlForDecoderDisable?.(lrptDecodeToggleBtn); await hostCore.postPath("/toggle_lrpt_decode"); } catch (e) { console.error("LRPT toggle failed", e); } })(); }); var satFilterInput = satDom.filterInput; satFilterInput?.addEventListener("input", () => { satFilterText = satFilterInput.value.trim().toUpperCase(); renderSatHistoryTable(); }); satDom.sortSelect?.addEventListener("change", () => { renderSatHistoryTable(); }); satDom.typeFilter?.addEventListener("change", () => { renderSatHistoryTable(); }); document.getElementById("settings-clear-sat-history")?.addEventListener("click", () => { void (async () => { if (!await satWindow.trxUi.confirm({ title: "Clear satellite history?", message: "All stored satellite decodes will be permanently removed.", confirmLabel: "Clear history" })) return; try { await hostCore.postPath("/clear_lrpt_decode"); resetSatHistoryView(); } catch (e) { console.error("Weather satellite history clear failed", e); } })(); }); satWindow.satShowOnMap = function(south, west, north, east) { if (typeof satWindow.enableMapSourceFilter === "function") { satWindow.enableMapSourceFilter("sat"); } const lat = (south + north) / 2; const lon = (west + east) / 2; if (satWindow.navigateToAprsMap) { satWindow.navigateToAprsMap(lat, lon); } }; renderSatLatestCard(); renderSatHistoryTable();