diff --git a/README.md b/README.md index fc083bf..5becaca 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ fetch -qo - https://raw.githubusercontent.com/imengying/NodeFlare/main/agent/ins | `GET` | `/api/latency/:id?hours=24` | 节点延迟任务历史 | | `GET` | `/api/ws` | 实时 WebSocket | | `GET` | `/api/agent/ws` | Agent 配置同步与指标上报 WebSocket,节点 Bearer Token | +| `POST` | `/api/live/wake` | 总览页连上实时通道后批量唤醒可见节点的实时推送 | | `POST` | `/api/admin/login` | 管理登录 | | `POST` | `/api/admin/logout` | 退出登录(清除会话 Cookie) | | `GET/POST` | `/api/admin/servers` | 管理节点 | diff --git a/frontend/src/AppProvider.tsx b/frontend/src/AppProvider.tsx index 94bdb39..c614f65 100644 --- a/frontend/src/AppProvider.tsx +++ b/frontend/src/AppProvider.tsx @@ -155,10 +155,13 @@ export function AppProvider({ children }: { children: ReactNode }) { // Poll as a safety net: often when the live feed is down, rarely when it is // healthy, so a missed frame cannot leave the page stale indefinitely. + // Hidden tabs skip polling entirely — the live socket is dropped while + // hidden, and a background tab has nobody to keep fresh. useEffect(() => { if (access !== "ok") return; let ticks = 0; const timer = window.setInterval(() => { + if (document.hidden) return; ticks += 1; if (!liveConnectedRef.current || ticks % BOOTSTRAP_POLL_TICKS_WHEN_LIVE === 0) void reload(true); }, BOOTSTRAP_POLL_INTERVAL); diff --git a/frontend/src/components/NodeCard.tsx b/frontend/src/components/NodeCard.tsx index 8487d2a..2837b80 100644 --- a/frontend/src/components/NodeCard.tsx +++ b/frontend/src/components/NodeCard.tsx @@ -142,11 +142,10 @@ export function NodeCard({ server, config, onOpen }: { server: Server; config: C 0 ? `${traffic.toFixed(1)}%` : "∞"} used={traffic} sub={`${formatBytes(usedTraffic)} / ${server.traffic_limit > 0 ? formatBytes(server.traffic_limit) : "∞"}`} muted={!online} valueTone={server.traffic_limit <= 0 ? "" : traffic >= 95 ? "danger-text" : traffic >= 60 ? "warning-text" : "success-text"} /> - {/* 这三个面板原来各挂一个 aria-label(实时速率 / 累计流量 / 剩余周期),全都没生效: - 无 role 的 div 是 generic,规范禁止命名;就算补上 role="group",整张卡片是