feat: add jackpot animations and enhance currency handling across components
- Introduced new CSS animations for jackpot effects to improve visual engagement. - Integrated CurrencySwitcher into PlayerPanel and HallScreen for better currency management. - Updated various components to utilize active player currency for consistent display. - Enhanced event handling for currency changes to ensure real-time updates across the application.
This commit is contained in:
@@ -6,6 +6,12 @@ import {
|
||||
persistPlayerBearerToken,
|
||||
readPersistedPlayerBearerToken,
|
||||
} from "@/lib/player-session";
|
||||
import {
|
||||
dispatchPlayerCurrencyChange,
|
||||
persistPlayerSelectedCurrency,
|
||||
readPersistedPlayerSelectedCurrency,
|
||||
} from "@/lib/player-currency-preference";
|
||||
import { pickActivePlayerCurrency } from "@/lib/player-currency-options";
|
||||
import type { PublicCurrencyRow } from "@/types/api/currency";
|
||||
import type { PlayerMeData } from "@/types/api/player-me";
|
||||
|
||||
@@ -23,6 +29,8 @@ type PlayerSessionState = {
|
||||
bearerToken: string | null;
|
||||
profile: PlayerMeData | null;
|
||||
currencies: PublicCurrencyRow[];
|
||||
/** 玩家在大厅选择的可下注币种(localStorage 持久化) */
|
||||
selectedCurrency: string | null;
|
||||
phase: PlayerEntryPhase;
|
||||
progress: number;
|
||||
errorMessage: string | null;
|
||||
@@ -32,6 +40,9 @@ type PlayerSessionState = {
|
||||
clearBearerToken: () => void;
|
||||
setProfile: (profile: PlayerMeData | null) => void;
|
||||
setCurrencies: (currencies: PublicCurrencyRow[]) => void;
|
||||
/** 根据档案与币种目录校准当前选中币种 */
|
||||
reconcileSelectedCurrency: () => void;
|
||||
setSelectedCurrency: (code: string) => void;
|
||||
setPhase: (phase: PlayerEntryPhase) => void;
|
||||
setProgress: (progress: number) => void;
|
||||
setErrorMessage: (message: string | null) => void;
|
||||
@@ -47,10 +58,11 @@ function initialSteps(): PlayerEntryStep[] {
|
||||
];
|
||||
}
|
||||
|
||||
export const usePlayerSessionStore = create<PlayerSessionState>((set) => ({
|
||||
export const usePlayerSessionStore = create<PlayerSessionState>((set, get) => ({
|
||||
bearerToken: null,
|
||||
profile: null,
|
||||
currencies: [],
|
||||
selectedCurrency: null,
|
||||
phase: "loading",
|
||||
progress: 0,
|
||||
errorMessage: null,
|
||||
@@ -83,11 +95,46 @@ export const usePlayerSessionStore = create<PlayerSessionState>((set) => ({
|
||||
clearBearerToken: () => {
|
||||
setPlayerBearerToken(null);
|
||||
clearPersistedPlayerBearerToken();
|
||||
set({ bearerToken: null, profile: null });
|
||||
set({ bearerToken: null, profile: null, selectedCurrency: null });
|
||||
},
|
||||
|
||||
setProfile: (profile) => set({ profile }),
|
||||
setCurrencies: (currencies) => set({ currencies }),
|
||||
setProfile: (profile) => {
|
||||
set({ profile });
|
||||
get().reconcileSelectedCurrency();
|
||||
},
|
||||
|
||||
setCurrencies: (currencies) => {
|
||||
set({ currencies });
|
||||
get().reconcileSelectedCurrency();
|
||||
},
|
||||
|
||||
reconcileSelectedCurrency: () => {
|
||||
const { profile, currencies } = get();
|
||||
const next = pickActivePlayerCurrency(
|
||||
profile,
|
||||
currencies,
|
||||
readPersistedPlayerSelectedCurrency(),
|
||||
);
|
||||
const prev = get().selectedCurrency;
|
||||
if (prev === next) {
|
||||
return;
|
||||
}
|
||||
persistPlayerSelectedCurrency(next);
|
||||
set({ selectedCurrency: next });
|
||||
},
|
||||
|
||||
setSelectedCurrency: (code) => {
|
||||
const normalized = code.trim().toUpperCase();
|
||||
const allowed = get().currencies.some(
|
||||
(row) => row.is_bettable && row.code === normalized,
|
||||
);
|
||||
if (!allowed) {
|
||||
return;
|
||||
}
|
||||
persistPlayerSelectedCurrency(normalized);
|
||||
set({ selectedCurrency: normalized });
|
||||
dispatchPlayerCurrencyChange(normalized);
|
||||
},
|
||||
setPhase: (phase) => set({ phase }),
|
||||
setProgress: (progress) => set({ progress: Math.max(0, Math.min(100, progress)) }),
|
||||
setErrorMessage: (errorMessage) => set({ errorMessage }),
|
||||
|
||||
Reference in New Issue
Block a user