feat(player): improve wallet activity and session handling
Some checks failed
lotteryfront CI / build (push) Has been cancelled

This commit is contained in:
wchino
2026-07-22 20:53:43 +08:00
parent 508b28df22
commit 827f369eb6
40 changed files with 925 additions and 349 deletions

View File

@@ -4,7 +4,11 @@ import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { getLotteryEcho } from "@/lib/lottery-echo";
import {
disconnectLotteryEcho,
getLotteryEcho,
} from "@/lib/lottery-echo";
import { parseJwtSessionVersion } from "@/lib/jwt-payload";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
import { usePlayerSessionStore } from "@/stores/player-session-store";
@@ -17,6 +21,11 @@ type BalanceUpdateWsEvent = {
reason?: string;
};
type SessionReplacedWsEvent = {
player_id?: number;
session_version?: number;
};
const REASON_I18N_KEY: Record<string, string> = {
transfer_in: "wallet.wsReason.transferIn",
transfer_out: "wallet.wsReason.transferOut",
@@ -71,10 +80,33 @@ export function usePlayerBalanceWs(): void {
toast.message(t("wallet.wsBalanceUpdated", { change: changeLabel, reason: reasonLabel }));
};
const onSessionReplaced = (evt: SessionReplacedWsEvent): void => {
const nextVersion = evt.session_version;
if (
evt.player_id !== playerId ||
typeof nextVersion !== "number" ||
!Number.isInteger(nextVersion)
) {
return;
}
const state = usePlayerSessionStore.getState();
const currentVersion = parseJwtSessionVersion(state.bearerToken) ?? 0;
if (nextVersion <= currentVersion) {
return;
}
disconnectLotteryEcho();
state.clearBearerToken();
window.location.replace("/login?session=replaced");
};
channel.listen(".balance.update", onBalanceUpdate);
channel.listen(".session.replaced", onSessionReplaced);
return () => {
channel.stopListening(".balance.update");
channel.stopListening(".session.replaced");
echo.leave(channelName);
};
}, [activeCurrency, bearerToken, playerId, t]);