From 87643699e762afca8028e1bd5c7e10ebd1a1c4f9 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Mon, 25 May 2026 21:06:57 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=93=E5=AD=98TTL=202min=E2=86=9210min?= =?UTF-8?q?=EF=BC=8C=E7=A9=BA=E9=97=B2=E6=97=B6=E9=A2=84=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E7=9B=B8=E9=82=BB=E5=8C=BA=E5=9F=9F=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scan-terminal/use-scan-terminal-query.ts | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/frontend/components/dashboard/scan-terminal/use-scan-terminal-query.ts b/frontend/components/dashboard/scan-terminal/use-scan-terminal-query.ts index 22ba9793..71c28925 100644 --- a/frontend/components/dashboard/scan-terminal/use-scan-terminal-query.ts +++ b/frontend/components/dashboard/scan-terminal/use-scan-terminal-query.ts @@ -8,10 +8,11 @@ import { shouldSkipManualTerminalRefresh, } from "@/components/dashboard/scan-terminal/scan-terminal-client"; import { useRemoteDataQuery } from "@/components/dashboard/scan-terminal/use-remote-data-query"; +import { REGIONS } from "@/components/dashboard/scan-terminal/continent-grouping"; import type { ScanTerminalResponse } from "@/lib/dashboard-types"; const SCAN_CACHE_PREFIX = "polyweather_scan_v2"; -const SCAN_CACHE_TTL_MS = 2 * 60 * 1000; // 2 min — cities list instant on revisit +const SCAN_CACHE_TTL_MS = 10 * 60 * 1000; // 10 min — cities list instant on revisit function scanCacheKey(tradingRegion: string): string { return `${SCAN_CACHE_PREFIX}:${tradingRegion || "all"}`; @@ -136,6 +137,37 @@ export function useScanTerminalQuery({ return () => window.clearInterval(intervalId); }, [fetchScanTerminal, isLoading, isPro, proAccessLoading]); + // Preload adjacent regions in idle time for instant tab switches + useEffect(() => { + if (typeof window === "undefined" || !tradingRegion || !isPro) return; + const sorted = [...REGIONS].sort((a, b) => a.sort - b.sort); + const idx = sorted.findIndex((r) => r.key === tradingRegion); + if (idx < 0) return; + const neighbors = [idx - 1, idx + 1] + .filter((i) => i >= 0 && i < sorted.length) + .map((i) => sorted[i].key); + if (!neighbors.length) return; + + const preloadOne = (region: string) => { + if (readScanCache(region)) return; // already cached + const idleFn = (window as any).requestIdleCallback || ((cb: () => void) => setTimeout(cb, 5000)); + const handle = idleFn(() => { + void scanTerminalClient.getTerminal({ + forceRefresh: false, + signal: new AbortController().signal, + tradingRegion: region, + }).then((data) => { writeScanCache(data, region); }); + }); + return handle; + }; + + const handles = neighbors.map(preloadOne).filter(Boolean); + return () => { + const cancelFn = (window as any).cancelIdleCallback || clearTimeout; + handles.forEach((h) => { try { cancelFn(h); } catch { /* */ } }); + }; + }, [tradingRegion, isPro]); + return { refreshScanTerminalManually, scanError,