refactor: 引入 SWR 统一钱包余额查询与轮询逻辑
This commit is contained in:
@@ -2,8 +2,9 @@
|
||||
|
||||
import { Wallet } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useSWRConfig } from "swr";
|
||||
|
||||
import { getWalletBalance } from "@/api/wallet";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
@@ -12,76 +13,51 @@ import {
|
||||
TransferOutDialog,
|
||||
} from "@/features/wallet/wallet-transfer-dialogs";
|
||||
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
|
||||
import { useApiQuery } from "@/hooks/use-api-query";
|
||||
import { formatMinorAsCurrency } from "@/lib/money";
|
||||
import { PLAYER_CURRENCY_CHANGE_EVENT } from "@/lib/player-currency-preference";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useNetworkConnectionStore } from "@/stores/network-connection-store";
|
||||
import type { WalletBalanceData } from "@/types/api/wallet-balance";
|
||||
|
||||
const BALANCE_KEY = (currency: string) => ["wallet/balance", currency];
|
||||
|
||||
export function HallWalletStrip() {
|
||||
const mode = useNetworkConnectionStore((s) => s.mode);
|
||||
const { t } = useTranslation("player");
|
||||
const { activeCurrency } = useActivePlayerCurrency();
|
||||
const [balance, setBalance] = useState<WalletBalanceData | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { mutate } = useSWRConfig();
|
||||
const degradedWalletPollRef = useRef<number | null>(null);
|
||||
|
||||
const currency = activeCurrency;
|
||||
const isDegraded = mode === "polling" || mode === "offline";
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
const b = await getWalletBalance({ currency: activeCurrency });
|
||||
setBalance(b);
|
||||
}, [activeCurrency]);
|
||||
const { data: balance, isLoading: loading } = useApiQuery(
|
||||
BALANCE_KEY(currency),
|
||||
() => getWalletBalance({ currency }),
|
||||
{
|
||||
// 降级模式下 60 秒自动刷新,SWR 内置定时器代替手动 setInterval
|
||||
refreshInterval: isDegraded ? 60_000 : undefined,
|
||||
},
|
||||
);
|
||||
|
||||
// 全局事件触发刷新(下注后、币种切换等场景)
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
void (async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await refresh();
|
||||
} finally {
|
||||
if (!cancelled) setLoading(false);
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [refresh]);
|
||||
|
||||
useEffect(() => {
|
||||
const onRefresh = () => void refresh();
|
||||
const onRefresh = () => void mutate(BALANCE_KEY(currency));
|
||||
window.addEventListener("lottery-wallet-refresh", onRefresh);
|
||||
window.addEventListener(PLAYER_CURRENCY_CHANGE_EVENT, onRefresh);
|
||||
return () => {
|
||||
window.removeEventListener("lottery-wallet-refresh", onRefresh);
|
||||
window.removeEventListener(PLAYER_CURRENCY_CHANGE_EVENT, onRefresh);
|
||||
};
|
||||
}, [refresh]);
|
||||
}, [mutate, currency]);
|
||||
|
||||
// 非降级模式时清理遗留计时器(refreshInterval 已由 SWR 管理)
|
||||
useEffect(() => {
|
||||
if (mode !== "polling" && mode !== "offline") {
|
||||
if (degradedWalletPollRef.current !== null) {
|
||||
window.clearInterval(degradedWalletPollRef.current);
|
||||
degradedWalletPollRef.current = null;
|
||||
}
|
||||
return;
|
||||
if (!isDegraded && degradedWalletPollRef.current !== null) {
|
||||
window.clearInterval(degradedWalletPollRef.current);
|
||||
degradedWalletPollRef.current = null;
|
||||
}
|
||||
|
||||
if (degradedWalletPollRef.current !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
degradedWalletPollRef.current = window.setInterval(() => {
|
||||
void refresh();
|
||||
}, 60_000);
|
||||
|
||||
return () => {
|
||||
if (degradedWalletPollRef.current !== null) {
|
||||
window.clearInterval(degradedWalletPollRef.current);
|
||||
degradedWalletPollRef.current = null;
|
||||
}
|
||||
};
|
||||
}, [mode, refresh]);
|
||||
}, [isDegraded]);
|
||||
|
||||
const availableMinor = Number(balance?.available_balance ?? balance?.balance ?? 0);
|
||||
const isCreditPlayer =
|
||||
@@ -136,7 +112,7 @@ export function HallWalletStrip() {
|
||||
currency={currency}
|
||||
lotteryMinor={availableMinor}
|
||||
mainMinor={mainMinor}
|
||||
onSuccess={refresh}
|
||||
onSuccess={async () => { await mutate(BALANCE_KEY(currency)); }}
|
||||
/>
|
||||
<TransferOutDialog
|
||||
idPrefix="hall-"
|
||||
@@ -145,7 +121,7 @@ export function HallWalletStrip() {
|
||||
triggerClassName="h-12 rounded-lg text-base font-bold"
|
||||
currency={currency}
|
||||
availableMinor={availableMinor}
|
||||
onSuccess={refresh}
|
||||
onSuccess={async () => { await mutate(BALANCE_KEY(currency)); }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user