diff --git a/onchain_scout_gate/static/app.js b/onchain_scout_gate/static/app.js index f63df7b..564b606 100644 --- a/onchain_scout_gate/static/app.js +++ b/onchain_scout_gate/static/app.js @@ -262,6 +262,64 @@ function renderDailyReport(payload) { `; } +const PANEL_FOLD_STORAGE_KEY = "matrix_panel_fold_v1"; + +function initPanelFolds() { + let saved = {}; + try { + const raw = localStorage.getItem(PANEL_FOLD_STORAGE_KEY); + if (raw) saved = JSON.parse(raw); + } catch (_) { + saved = {}; + } + + function applyFold(panel, folded) { + const toggle = panel.querySelector(".matrix-panel-fold-toggle"); + if (folded) { + panel.classList.add("is-folded"); + if (toggle) toggle.setAttribute("aria-expanded", "false"); + } else { + panel.classList.remove("is-folded"); + if (toggle) toggle.setAttribute("aria-expanded", "true"); + } + } + + document.querySelectorAll(".matrix-panel-fold[data-fold-id]").forEach((panel) => { + const id = panel.dataset.foldId; + const defaultOpen = panel.dataset.foldDefault === "open"; + let folded; + if (Object.prototype.hasOwnProperty.call(saved, id)) { + folded = saved[id] === true; + } else { + folded = !defaultOpen; + } + applyFold(panel, folded); + + const toggle = panel.querySelector(".matrix-panel-fold-toggle"); + if (!toggle) return; + + const onToggle = (e) => { + if (e.target.closest("[data-fold-ignore]")) return; + const willFold = !panel.classList.contains("is-folded"); + applyFold(panel, willFold); + saved[id] = willFold; + try { + localStorage.setItem(PANEL_FOLD_STORAGE_KEY, JSON.stringify(saved)); + } catch (_) { + /* ignore quota */ + } + }; + + toggle.addEventListener("click", onToggle); + toggle.addEventListener("keydown", (e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + onToggle(e); + } + }); + }); +} + function escapeHtml(s) { return String(s) .replace(/&/g, "&") @@ -782,6 +840,7 @@ tickClock(); setInterval(tickClock, 1000); initMatrixRain(); initFunnelWindowControls(); +initPanelFolds(); refresh(); setInterval(refresh, 4000); document.addEventListener("visibilitychange", () => { diff --git a/onchain_scout_gate/static/style.css b/onchain_scout_gate/static/style.css index 78463cd..c6690e1 100644 --- a/onchain_scout_gate/static/style.css +++ b/onchain_scout_gate/static/style.css @@ -1058,6 +1058,56 @@ pre { flex-wrap: wrap; } +.matrix-panel-head.matrix-panel-fold-toggle:not(.matrix-panel-head-row) { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.matrix-panel-fold-toggle { + cursor: pointer; + user-select: none; + width: 100%; +} + +.matrix-panel-fold-toggle:focus-visible { + outline: 1px solid rgba(0, 255, 213, 0.55); + outline-offset: 2px; +} + +.matrix-fold-head-right { + display: inline-flex; + align-items: center; + gap: 10px; + flex-shrink: 0; +} + +.matrix-fold-chevron { + display: inline-block; + font-size: 10px; + color: #5ee0c5; + transition: transform 0.2s ease; + line-height: 1; +} + +.matrix-panel-fold.is-folded .matrix-fold-chevron { + transform: rotate(-90deg); +} + +.matrix-panel-fold.is-folded .matrix-panel-fold-body { + display: none; +} + +.matrix-panel-fold.is-folded { + padding-bottom: 12px; +} + +.matrix-panel-nested { + padding: 12px 14px; + background: rgba(0, 0, 0, 0.2); +} + .matrix-chip { font-size: 9px; letter-spacing: 0.18em; diff --git a/onchain_scout_gate/templates/dashboard.html b/onchain_scout_gate/templates/dashboard.html index da6f5bb..4806ac4 100644 --- a/onchain_scout_gate/templates/dashboard.html +++ b/onchain_scout_gate/templates/dashboard.html @@ -82,17 +82,21 @@
-
+
+
+

// GEMMA 漏斗 · 优先矩阵

+ + LIVE FEED + + +
+
-
-

// GEMMA 漏斗 · 优先矩阵

- LIVE FEED -

合成评分 · 成交量 · 日线结构 · 上方空间 · 中间阻力 → 达标企业微信推送

@@ -102,13 +106,18 @@

// 数据同步中…

+
-
-
+
+

// 关键位突破监控

- 人工录入 · 5m 门控 + + 人工录入 · 5m 门控 + +
+

GEMMA 漏斗仅供参考;在此录入上/下沿。箱体突破与收敛突破均支持「标准突破」或「趋势突破」(无 1.5H 方案)。

// 规则加载中…

@@ -148,13 +157,18 @@
+
-
-
+
+ +
@@ -169,13 +183,18 @@

// 等待晨报数据…

+
-
-
+
+ +

Gate USDT 永续左侧 base(每行一个或逗号分隔),如 XAU XAUT XAGall_swapswatchlist 均会在入池后剔除。保存后下一轮扫描生效。 @@ -192,13 +211,18 @@

+
-
-
+
+ +

关键位门控通过且计划 RR 达标后,向列表中已启用的执行器 POST /v1/signal(单一 SL/TP,与录入方案一致)。 各执行器自行配置 Gate API、盈亏比、移动保本等;不支持执行器反向注册。 @@ -225,10 +249,15 @@

+
-
-

// 策略寄存器 · 5m

+
+ +

全市场雷达:横盘 + 5m 突破 + 放量 · 仅参考推送 · 正式下单请用「关键位突破监控」

@@ -248,30 +277,50 @@

+
-
-
-

// 观察层 · WATCH

-
-
-
-

// 触发层 · TRIGGER

-
-
-
+
+ +
+

自动箱体雷达 · 默认折叠 · 与关键位下单无关

+
+
+

// 观察层 · WATCH

+
+
+
+

// 触发层 · TRIGGER

+
+
+
+
+
-
-

// 系统遥测

+
+ +

                     

                 
+
-
-

// 运行日志

+
+ +
+