扫描终端加 localStorage 缓存,二次进入城市列表瞬间加载
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useCallback, useEffect, useRef } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import {
|
import {
|
||||||
scanTerminalQueryPolicy,
|
scanTerminalQueryPolicy,
|
||||||
scanTerminalClient,
|
scanTerminalClient,
|
||||||
@@ -10,6 +10,25 @@ import {
|
|||||||
import { useRemoteDataQuery } from "@/components/dashboard/scan-terminal/use-remote-data-query";
|
import { useRemoteDataQuery } from "@/components/dashboard/scan-terminal/use-remote-data-query";
|
||||||
import type { ScanTerminalResponse } from "@/lib/dashboard-types";
|
import type { ScanTerminalResponse } from "@/lib/dashboard-types";
|
||||||
|
|
||||||
|
const SCAN_CACHE_KEY = "polyweather_scan_v1";
|
||||||
|
const SCAN_CACHE_TTL_MS = 2 * 60 * 1000; // 2 min — cities list instant on revisit
|
||||||
|
|
||||||
|
function readScanCache(): ScanTerminalResponse | null {
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(SCAN_CACHE_KEY);
|
||||||
|
if (!raw) return null;
|
||||||
|
const cached = JSON.parse(raw);
|
||||||
|
if (cached.ts && Date.now() - cached.ts < SCAN_CACHE_TTL_MS && cached.data?.rows) {
|
||||||
|
return cached.data;
|
||||||
|
}
|
||||||
|
} catch { /* ignore */ }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeScanCache(data: ScanTerminalResponse) {
|
||||||
|
try { localStorage.setItem(SCAN_CACHE_KEY, JSON.stringify({ ts: Date.now(), data })); } catch { /* ignore */ }
|
||||||
|
}
|
||||||
|
|
||||||
export function useScanTerminalQuery({
|
export function useScanTerminalQuery({
|
||||||
isPro,
|
isPro,
|
||||||
proAccessLoading,
|
proAccessLoading,
|
||||||
@@ -30,7 +49,12 @@ export function useScanTerminalQuery({
|
|||||||
reset,
|
reset,
|
||||||
run,
|
run,
|
||||||
} = useRemoteDataQuery<ScanTerminalResponse>();
|
} = useRemoteDataQuery<ScanTerminalResponse>();
|
||||||
|
|
||||||
const lastForcedScanRefreshAtRef = useRef(0);
|
const lastForcedScanRefreshAtRef = useRef(0);
|
||||||
|
const [cachedRows, setCachedRows] = useState<ScanTerminalResponse | null>(() => {
|
||||||
|
if (typeof window !== "undefined") return readScanCache();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
const fetchScanTerminal = useCallback(
|
const fetchScanTerminal = useCallback(
|
||||||
async ({
|
async ({
|
||||||
@@ -56,6 +80,7 @@ export function useScanTerminalQuery({
|
|||||||
tradingRegion,
|
tradingRegion,
|
||||||
}),
|
}),
|
||||||
showLoading,
|
showLoading,
|
||||||
|
onSuccess: (data) => { writeScanCache(data); setCachedRows(data); },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[isPro, proAccessLoading, run, timezoneOffsetSeconds, tradingRegion],
|
[isPro, proAccessLoading, run, timezoneOffsetSeconds, tradingRegion],
|
||||||
@@ -70,6 +95,8 @@ export function useScanTerminalQuery({
|
|||||||
void fetchScanTerminal({ forceRefresh: false, showLoading: true });
|
void fetchScanTerminal({ forceRefresh: false, showLoading: true });
|
||||||
}, [fetchScanTerminal, isPro, proAccessLoading, reset, timezoneOffsetSeconds, tradingRegion]);
|
}, [fetchScanTerminal, isPro, proAccessLoading, reset, timezoneOffsetSeconds, tradingRegion]);
|
||||||
|
|
||||||
|
const effectiveData = terminalData || cachedRows;
|
||||||
|
|
||||||
const refreshScanTerminalManually = useCallback(() => {
|
const refreshScanTerminalManually = useCallback(() => {
|
||||||
if (
|
if (
|
||||||
shouldSkipManualTerminalRefresh({
|
shouldSkipManualTerminalRefresh({
|
||||||
@@ -110,6 +137,6 @@ export function useScanTerminalQuery({
|
|||||||
scanError,
|
scanError,
|
||||||
scanLoading,
|
scanLoading,
|
||||||
scanRemote,
|
scanRemote,
|
||||||
terminalData,
|
terminalData: effectiveData,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user