feat: 增加 Jackpot 爆池实时弹层与奖池信息展示
This commit is contained in:
76
src/features/hall/use-jackpot-burst-live.ts
Normal file
76
src/features/hall/use-jackpot-burst-live.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
"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", {
|
||||
defaultValue: "Jackpot 爆池",
|
||||
});
|
||||
const body = t("hall.jackpotBurst.notificationBody", {
|
||||
defaultValue: "期号 {{drawNo}} 派发 {{amount}}",
|
||||
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"));
|
||||
},
|
||||
[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),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user