51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
|
|
/**
|
||
|
|
* Browser notification + in-app toast for generation task completions.
|
||
|
|
* Falls back gracefully when Notification API is unavailable.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { toast } from "../components/toast/toastStore";
|
||
|
|
|
||
|
|
let permissionGranted = false;
|
||
|
|
|
||
|
|
async function requestPermission(): Promise<boolean> {
|
||
|
|
if (permissionGranted) return true;
|
||
|
|
if (typeof Notification === "undefined") return false;
|
||
|
|
if (Notification.permission === "granted") { permissionGranted = true; return true; }
|
||
|
|
if (Notification.permission === "denied") return false;
|
||
|
|
try {
|
||
|
|
const result = await Notification.requestPermission();
|
||
|
|
permissionGranted = result === "granted";
|
||
|
|
return permissionGranted;
|
||
|
|
} catch {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function notifyTaskCompleted(label: string, mode: "image" | "video" = "image") {
|
||
|
|
const emoji = mode === "video" ? "🎬" : "🖼️";
|
||
|
|
const title = `${emoji} ${label}生成完成`;
|
||
|
|
const body = "点击返回查看生成结果";
|
||
|
|
|
||
|
|
// Browser notification (background tab)
|
||
|
|
if (typeof Notification !== "undefined" && Notification.permission === "granted") {
|
||
|
|
try { new Notification(title, { body, icon: "/favicon.ico", tag: "gen-complete" }); } catch { /* */ }
|
||
|
|
}
|
||
|
|
|
||
|
|
// In-app toast
|
||
|
|
dispatchGenToast(title);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Use the existing toast system for in-app notifications
|
||
|
|
function dispatchGenToast(msg: string) {
|
||
|
|
toast(msg, "success");
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Call once on app init to pre-warm permission. */
|
||
|
|
export async function initNotificationPermission() {
|
||
|
|
if (typeof Notification === "undefined") return;
|
||
|
|
if (Notification.permission === "default") {
|
||
|
|
// Don't prompt immediately — wait for first user interaction
|
||
|
|
document.addEventListener("click", () => requestPermission(), { once: true });
|
||
|
|
}
|
||
|
|
}
|