fix(v2): inventory no longer flickers — debounced re-fetch, no loading flash
inventory_delta WS messages were triggering immediate full re-fetch with setLoading(true), causing content to flash blank. Now: - Initial load shows loading state (once) - Subsequent deltas debounced to 2s (batches rapid changes) - Re-fetch runs silently without clearing existing items Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0112c59514
commit
4638e60043
1 changed files with 18 additions and 4 deletions
|
|
@ -163,19 +163,33 @@ export const InventoryWindow: React.FC<Props> = ({ id, charName, zIndex, invento
|
||||||
const [activePack, setActivePack] = useState<number | null>(null);
|
const [activePack, setActivePack] = useState<number | null>(null);
|
||||||
const [tooltip, setTooltip] = useState<{ item: any; x: number; y: number } | null>(null);
|
const [tooltip, setTooltip] = useState<{ item: any; x: number; y: number } | null>(null);
|
||||||
const [charStats, setCharStats] = useState<any>(null);
|
const [charStats, setCharStats] = useState<any>(null);
|
||||||
const [cantripState, setCantripState] = useState<any>(null);
|
const debounceRef = useRef<number>(0);
|
||||||
|
const initialLoadDone = useRef(false);
|
||||||
|
|
||||||
|
// Initial fetch
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
Promise.all([
|
Promise.all([
|
||||||
apiFetch<any>(`/inventory/${encodeURIComponent(charName)}?limit=1000`).catch(() => ({ items: [] })),
|
apiFetch<any>(`/inventory/${encodeURIComponent(charName)}?limit=1000`).catch(() => ({ items: [] })),
|
||||||
apiFetch<any>(`/character-stats/${encodeURIComponent(charName)}`).catch(() => null),
|
apiFetch<any>(`/character-stats/${encodeURIComponent(charName)}`).catch(() => null),
|
||||||
]).then(([inv, stats]) => {
|
]).then(([inv, stats]) => {
|
||||||
const rawItems = inv.items ?? [];
|
setItems((inv.items ?? []).map(normalizeItem));
|
||||||
setItems(rawItems.map(normalizeItem));
|
|
||||||
setCharStats(stats);
|
setCharStats(stats);
|
||||||
|
initialLoadDone.current = true;
|
||||||
}).finally(() => setLoading(false));
|
}).finally(() => setLoading(false));
|
||||||
}, [charName, inventoryVersion]); // re-fetch when inventory_delta arrives
|
}, [charName]);
|
||||||
|
|
||||||
|
// Debounced re-fetch on inventory_delta (no loading flash)
|
||||||
|
useEffect(() => {
|
||||||
|
if (!initialLoadDone.current || !inventoryVersion) return;
|
||||||
|
clearTimeout(debounceRef.current);
|
||||||
|
debounceRef.current = window.setTimeout(() => {
|
||||||
|
apiFetch<any>(`/inventory/${encodeURIComponent(charName)}?limit=1000`)
|
||||||
|
.then(inv => setItems((inv.items ?? []).map(normalizeItem)))
|
||||||
|
.catch(() => {});
|
||||||
|
}, 2000); // 2s debounce — batch rapid deltas
|
||||||
|
return () => clearTimeout(debounceRef.current);
|
||||||
|
}, [charName, inventoryVersion]);
|
||||||
|
|
||||||
const handleHover = useCallback((item: any | null, e?: React.MouseEvent) => {
|
const handleHover = useCallback((item: any | null, e?: React.MouseEvent) => {
|
||||||
if (item && e) setTooltip({ item, x: e.clientX, y: e.clientY });
|
if (item && e) setTooltip({ item, x: e.clientX, y: e.clientY });
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue