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:
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
|
||||
import { getDrawCurrent } from "@/api/draw";
|
||||
import { isHallSealedCountdownUi } from "@/features/draw/draw-status-meta";
|
||||
import { getLotteryEcho } from "@/lib/lottery-echo";
|
||||
import { useNetworkConnectionStore } from "@/stores/network-connection-store";
|
||||
import type { DrawCurrentPayload, DrawCurrentResponse } from "@/types/api/draw-current";
|
||||
@@ -105,6 +106,15 @@ export function useHallDrawLive(): HallDrawLiveSnapshot {
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [load]);
|
||||
|
||||
// 爆池等场景:刷新大厅快照(含奖池余额)
|
||||
useEffect(() => {
|
||||
const onHallRefresh = () => {
|
||||
void load();
|
||||
};
|
||||
window.addEventListener("lottery-hall-refresh", onHallRefresh);
|
||||
return () => window.removeEventListener("lottery-hall-refresh", onHallRefresh);
|
||||
}, [load]);
|
||||
|
||||
// 本地倒计时计时器(用于 UI 更新)
|
||||
useEffect(() => {
|
||||
const bump = () => setNowMs(Date.now());
|
||||
@@ -242,5 +252,53 @@ export function useHallDrawLive(): HallDrawLiveSnapshot {
|
||||
|
||||
const isBettable = display != null && display.status === "open";
|
||||
|
||||
const zeroRefreshKeyRef = useRef<string | null>(null);
|
||||
|
||||
// 本地倒计时归零时主动拉取(冷静期结束、封盘切下一期等;避免只靠手动刷新)
|
||||
useEffect(() => {
|
||||
if (!display) return;
|
||||
|
||||
const coolingEndMs = display.cooling_end_time
|
||||
? Date.parse(display.cooling_end_time)
|
||||
: null;
|
||||
const coolingDone =
|
||||
display.status === "cooldown" &&
|
||||
((display.seconds_remaining_in_cooldown ?? 1) === 0 ||
|
||||
(coolingEndMs !== null && !Number.isNaN(coolingEndMs) && coolingEndMs <= nowMs));
|
||||
|
||||
const sealedDone =
|
||||
isHallSealedCountdownUi(display.status) && (display.seconds_to_draw ?? 1) === 0;
|
||||
|
||||
const closeDone =
|
||||
display.status === "open" && (display.seconds_to_close ?? 1) === 0;
|
||||
|
||||
const trigger = coolingDone
|
||||
? `${display.draw_no}:cooldown-end`
|
||||
: sealedDone
|
||||
? `${display.draw_no}:sealed-end`
|
||||
: closeDone
|
||||
? `${display.draw_no}:close-end`
|
||||
: null;
|
||||
|
||||
if (trigger && zeroRefreshKeyRef.current !== trigger) {
|
||||
zeroRefreshKeyRef.current = trigger;
|
||||
void load();
|
||||
}
|
||||
}, [display, nowMs, load]);
|
||||
|
||||
useEffect(() => {
|
||||
if (display?.draw_no) {
|
||||
zeroRefreshKeyRef.current = null;
|
||||
}
|
||||
}, [display?.draw_no, display?.status]);
|
||||
|
||||
// WebSocket 已连接时的兜底轮询(tick 最多 1 分钟延迟时的保险)
|
||||
useEffect(() => {
|
||||
const intervalId = window.setInterval(() => {
|
||||
void load();
|
||||
}, 45_000);
|
||||
return () => window.clearInterval(intervalId);
|
||||
}, [load]);
|
||||
|
||||
return { raw, display, serverNowMs, error, reload: load, isBettable };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user