- 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.
75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import type { TFunction } from "i18next";
|
|
|
|
import { getLotteryEcho } from "@/lib/lottery-echo";
|
|
import { formatMinorAsCurrency } from "@/lib/money";
|
|
import type { JackpotBurstEvent } from "@/features/hall/jackpot-burst-overlay";
|
|
|
|
function notifyBrowser(event: JackpotBurstEvent, t: TFunction<"player">): void {
|
|
if (typeof window === "undefined" || !("Notification" in window)) {
|
|
return;
|
|
}
|
|
|
|
const currency = event.currency_code.toUpperCase();
|
|
const amount = formatMinorAsCurrency(event.total_payout_amount, currency);
|
|
const title = t("hall.jackpotBurst.notificationTitle");
|
|
const body = t("hall.jackpotBurst.notificationBody", {
|
|
drawNo: event.draw_no,
|
|
amount,
|
|
});
|
|
|
|
const push = () => {
|
|
try {
|
|
new Notification(title, { body, tag: `jackpot-burst-${event.draw_id}` });
|
|
} catch {
|
|
// 浏览器通知失败不影响页面内爆池动画。
|
|
}
|
|
};
|
|
|
|
if (Notification.permission === "granted") {
|
|
push();
|
|
return;
|
|
}
|
|
|
|
if (Notification.permission === "default") {
|
|
void Notification.requestPermission().then((permission) => {
|
|
if (permission === "granted") {
|
|
push();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
export function useJackpotBurstLive(t: TFunction<"player">) {
|
|
const [event, setEvent] = useState<JackpotBurstEvent | null>(null);
|
|
|
|
const handleBurst = useCallback(
|
|
(payload: JackpotBurstEvent) => {
|
|
setEvent(payload);
|
|
notifyBrowser(payload, t);
|
|
window.dispatchEvent(new Event("lottery-wallet-refresh"));
|
|
window.dispatchEvent(new Event("lottery-hall-refresh"));
|
|
},
|
|
[t],
|
|
);
|
|
|
|
useEffect(() => {
|
|
const echo = getLotteryEcho();
|
|
if (!echo) return;
|
|
|
|
const channel = echo.channel("lottery-hall");
|
|
channel.listen(".jackpot.burst", handleBurst);
|
|
|
|
return () => {
|
|
channel.stopListening(".jackpot.burst");
|
|
};
|
|
}, [handleBurst]);
|
|
|
|
return {
|
|
burstEvent: event,
|
|
clearBurstEvent: () => setEvent(null),
|
|
};
|
|
}
|