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:
41
src/lib/player-currency-options.ts
Normal file
41
src/lib/player-currency-options.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import type { PublicCurrencyRow } from "@/types/api/currency";
|
||||
import type { PlayerMeData } from "@/types/api/player-me";
|
||||
|
||||
import { resolvePlayerCurrency } from "@/lib/player-currency";
|
||||
|
||||
export function normalizeCurrencyCode(code: string | null | undefined): string | null {
|
||||
const trimmed = code?.trim();
|
||||
return trimmed ? trimmed.toUpperCase() : null;
|
||||
}
|
||||
|
||||
export function listBettableCurrencies(currencies: PublicCurrencyRow[]): PublicCurrencyRow[] {
|
||||
return currencies.filter((row) => row.is_bettable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析玩家当前应使用的业务币种:持久化选择 → 玩家默认 → 首个可下注币种 → NPR 兜底。
|
||||
*/
|
||||
export function pickActivePlayerCurrency(
|
||||
profile: Pick<PlayerMeData, "default_currency"> | null | undefined,
|
||||
currencies: PublicCurrencyRow[],
|
||||
persistedCode: string | null,
|
||||
): string {
|
||||
const bettable = listBettableCurrencies(currencies);
|
||||
const bettableCodes = bettable.map((row) => row.code);
|
||||
|
||||
const persisted = normalizeCurrencyCode(persistedCode);
|
||||
if (persisted && bettableCodes.includes(persisted)) {
|
||||
return persisted;
|
||||
}
|
||||
|
||||
const fromProfile = normalizeCurrencyCode(profile?.default_currency);
|
||||
if (fromProfile && bettableCodes.includes(fromProfile)) {
|
||||
return fromProfile;
|
||||
}
|
||||
|
||||
if (bettable.length > 0) {
|
||||
return bettable[0].code;
|
||||
}
|
||||
|
||||
return resolvePlayerCurrency(profile);
|
||||
}
|
||||
38
src/lib/player-currency-preference.ts
Normal file
38
src/lib/player-currency-preference.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
const STORAGE_KEY = "lottery.player.selected_currency";
|
||||
|
||||
export function persistPlayerSelectedCurrency(code: string): void {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, code.trim().toUpperCase());
|
||||
} catch {
|
||||
/* ignore quota / private mode */
|
||||
}
|
||||
}
|
||||
|
||||
export function readPersistedPlayerSelectedCurrency(): string | null {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
return raw?.trim() ? raw.trim().toUpperCase() : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function clearPersistedPlayerSelectedCurrency(): void {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
/** 切换币种后通知各业务模块重新拉取玩法/钱包等数据 */
|
||||
export const PLAYER_CURRENCY_CHANGE_EVENT = "lottery-currency-change";
|
||||
|
||||
export function dispatchPlayerCurrencyChange(code: string): void {
|
||||
if (typeof window === "undefined") return;
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(PLAYER_CURRENCY_CHANGE_EVENT, {
|
||||
detail: { currency: code.trim().toUpperCase() },
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { pickActivePlayerCurrency } from "@/lib/player-currency-options";
|
||||
import { usePlayerSessionStore } from "@/stores/player-session-store";
|
||||
import type { PlayerMeData } from "@/types/api/player-me";
|
||||
import type { WalletBalanceData } from "@/types/api/wallet-balance";
|
||||
|
||||
@@ -5,8 +7,7 @@ type CurrencyProfile = Pick<PlayerMeData, "default_currency"> | null | undefined
|
||||
type CurrencyBalance = Pick<WalletBalanceData, "currency_code"> | null | undefined;
|
||||
|
||||
/**
|
||||
* 玩家端当前业务币种:
|
||||
* 优先钱包接口返回币种,再回退玩家默认币种,环境变量仅作联调兜底。
|
||||
* 玩家档案/环境变量层面的默认币种(不含用户在大厅的切换选择)。
|
||||
*/
|
||||
export function resolvePlayerCurrency(
|
||||
profile: CurrencyProfile,
|
||||
@@ -29,3 +30,15 @@ export function resolvePlayerCurrency(
|
||||
|
||||
return "NPR";
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前业务币种(含玩家在大厅切换的可下注币种)。
|
||||
* 可在非 React 上下文(轮询、WS 刷新)中调用。
|
||||
*/
|
||||
export function getActivePlayerCurrencyFromStore(): string {
|
||||
const { selectedCurrency, profile, currencies } = usePlayerSessionStore.getState();
|
||||
if (selectedCurrency) {
|
||||
return selectedCurrency;
|
||||
}
|
||||
return pickActivePlayerCurrency(profile, currencies, null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user