diff --git a/onchain_scout_gate/static/app.js b/onchain_scout_gate/static/app.js index 9d2d4eb..d0315ad 100644 --- a/onchain_scout_gate/static/app.js +++ b/onchain_scout_gate/static/app.js @@ -430,7 +430,14 @@ async function saveDailyReportSettings() { } } +function isPanelFolded(foldId) { + const panel = document.querySelector(`.matrix-panel-fold[data-fold-id="${foldId}"]`); + return !!(panel && panel.classList.contains("is-folded")); +} + async function refresh() { + if (document.visibilityState !== "visible") return; + const mobileLite = isMobileLite(); try { const funnelWindowH = getFunnelWindowHours(); const [status, alerts, logs, config, funnel, dailyReport] = await Promise.all([ @@ -445,8 +452,16 @@ async function refresh() { const statusPre = document.getElementById("status"); const cf = document.getElementById("config"); - if (statusPre) statusPre.textContent = pretty(status); - if (cf) cf.textContent = pretty(config); + if (!mobileLite) { + if (statusPre) { + const st = pretty(status); + if (statusPre.textContent !== st) statusPre.textContent = st; + } + if (cf) { + const cfgTxt = pretty(config); + if (cf.textContent !== cfgTxt) cf.textContent = cfgTxt; + } + } const runState = (status && status.state) || {}; const funnelWindowApplied = @@ -497,7 +512,8 @@ async function refresh() { const watchRows = allAlerts.filter((a) => (a.details && a.details.signal_level) === "WATCH"); const triggerRows = allAlerts.filter((a) => (a.details && a.details.signal_level) === "TRIGGER"); - renderItems("watchAlerts", watchRows, (a) => ` + if (!mobileLite || !isPanelFolded("scan-layers")) { + renderItems("watchAlerts", watchRows, (a) => `
${a.symbol} ${escapeHtml(a.chain || "")}
级别: ${(a.details && a.details.signal_level) || "N/A"}
信号: ${(a.trigger_types || []).join(" · ")}
@@ -523,11 +539,14 @@ async function refresh() {
${formatIsoToBeijing(a.created_at)}
`); } + } - renderItems("logs", logs.items || [], (l) => ` + if (!mobileLite || !isPanelFolded("runtime-logs")) { + renderItems("logs", logs.items || [], (l) => `
[${l.level}] ${escapeHtml(l.message)}
${formatIsoToBeijing(l.created_at)}
`); + } } catch (error) { console.error("refresh failed", error); setText("hudLink", "ERR"); @@ -536,8 +555,25 @@ async function refresh() { } } -/** 轻量 Canvas 代码雨(仅 dashboard 有 canvas) */ +/** 手机 / 触控:关闭重动画与代码雨,减轻闪屏与发热 */ +function isMobileLite() { + return ( + document.documentElement.classList.contains("matrix-lite") || + window.matchMedia("(max-width: 640px), (hover: none) and (pointer: coarse)").matches + ); +} + +function applyMobileLiteClass() { + if (isMobileLite()) { + document.documentElement.classList.add("matrix-lite"); + document.body.classList.add("matrix-lite"); + } +} + +/** 轻量 Canvas 代码雨(仅 dashboard 有 canvas;手机端不启动) */ function initMatrixRain() { + applyMobileLiteClass(); + if (isMobileLite()) return; const canvas = document.getElementById("matrixRain"); if (!canvas || !canvas.getContext) return; const ctx = canvas.getContext("2d"); @@ -843,7 +879,8 @@ initMatrixRain(); initFunnelWindowControls(); initPanelFolds(); refresh(); -setInterval(refresh, 4000); +const REFRESH_MS = isMobileLite() ? 10000 : 4000; +setInterval(refresh, REFRESH_MS); document.addEventListener("visibilitychange", () => { if (document.visibilityState === "visible") refresh(); }); diff --git a/onchain_scout_gate/static/style.css b/onchain_scout_gate/static/style.css index 36cff7e..d6ae676 100644 --- a/onchain_scout_gate/static/style.css +++ b/onchain_scout_gate/static/style.css @@ -1647,12 +1647,60 @@ body.matrix-theme { } .matrix-rain-canvas { - opacity: 0.3; + display: none !important; } .matrix-scanlines, - .matrix-noise { - opacity: 0.45; + .matrix-noise, + .matrix-aurora { + display: none !important; + } + + .matrix-vignette { + opacity: 0.35; + background: radial-gradient(ellipse at center, transparent 40%, rgba(0, 0, 0, 0.55) 100%); + } + + .matrix-hero-radar, + .matrix-radar-header { + display: none !important; + } + + .matrix-panel-chrome::before, + .matrix-hud-block::after, + .matrix-card::before { + display: none !important; + } + + .matrix-glitch-c, + .matrix-glitch-m { + display: none !important; + } + + .matrix-glitch-base { + text-shadow: 0 0 12px rgba(0, 255, 213, 0.35); + } + + .matrix-hud-dot { + animation: none !important; + } + + .matrix-tagline-glow, + .matrix-btn-pulse, + .matrix-chip-magenta, + .matrix-card::before, + .matrix-panel-chrome::before, + .matrix-hud-block::after, + .matrix-hero-radar-sweep, + .matrix-radar-h-sweep, + .matrix-bar { + animation: none !important; + } + + .matrix-chrome, + .matrix-main, + .matrix-panel { + transform: translateZ(0); } .matrix-table { @@ -1670,16 +1718,66 @@ body.matrix-theme { } } +/* 手机轻量模式(head 内联脚本提前打标 + 触控设备) */ +html.matrix-lite .matrix-rain-canvas, +html.matrix-lite .matrix-scanlines, +html.matrix-lite .matrix-noise, +html.matrix-lite .matrix-aurora { + display: none !important; +} + +html.matrix-lite .matrix-hero-radar, +html.matrix-lite .matrix-radar-header, +html.matrix-lite .matrix-panel-chrome::before, +html.matrix-lite .matrix-hud-block::after, +html.matrix-lite .matrix-card::before, +html.matrix-lite .matrix-glitch-c, +html.matrix-lite .matrix-glitch-m { + display: none !important; +} + +html.matrix-lite .matrix-glitch-base { + text-shadow: 0 0 12px rgba(0, 255, 213, 0.35); +} + +html.matrix-lite .matrix-hud-dot, +html.matrix-lite .matrix-tagline-glow, +html.matrix-lite .matrix-btn-pulse, +html.matrix-lite .matrix-chip-magenta, +html.matrix-lite .matrix-hero-radar-sweep, +html.matrix-lite .matrix-radar-h-sweep, +html.matrix-lite .matrix-bar, +html.matrix-lite .matrix-glitch-c, +html.matrix-lite .matrix-glitch-m { + animation: none !important; +} + +html.matrix-lite body.matrix-theme { + background: #020806; +} + @media (prefers-reduced-motion: reduce) { .matrix-rain-canvas { - display: none; + display: none !important; + } + + .matrix-scanlines, + .matrix-noise, + .matrix-aurora { + display: none !important; } .matrix-glitch-c, .matrix-glitch-m, .matrix-tagline-glow, .matrix-btn-pulse, - .matrix-chip-magenta { + .matrix-chip-magenta, + .matrix-hud-dot, + .matrix-panel-chrome::before, + .matrix-hud-block::after, + .matrix-card::before, + .matrix-hero-radar-sweep, + .matrix-radar-h-sweep { animation: none !important; } } diff --git a/onchain_scout_gate/templates/dashboard.html b/onchain_scout_gate/templates/dashboard.html index 6b0ec27..6c74bfc 100644 --- a/onchain_scout_gate/templates/dashboard.html +++ b/onchain_scout_gate/templates/dashboard.html @@ -3,6 +3,12 @@ + MATRIX · FUNNEL diff --git a/onchain_scout_gate/templates/login.html b/onchain_scout_gate/templates/login.html index a396ea6..e7e47af 100644 --- a/onchain_scout_gate/templates/login.html +++ b/onchain_scout_gate/templates/login.html @@ -3,6 +3,13 @@ + MATRIX · 接入