Initial commit
This commit is contained in:
163
lib/utils/notifications.ts
Normal file
163
lib/utils/notifications.ts
Normal file
@ -0,0 +1,163 @@
|
||||
// 通知类型
|
||||
export type NotificationType = "success" | "error" | "warning" | "info";
|
||||
|
||||
export interface AppNotification {
|
||||
id: string;
|
||||
type: NotificationType;
|
||||
title: string;
|
||||
message: string;
|
||||
duration?: number;
|
||||
timestamp: Date;
|
||||
}
|
||||
|
||||
// 通知管理器
|
||||
class NotificationManager {
|
||||
private notifications: AppNotification[] = [];
|
||||
private listeners: ((notifications: AppNotification[]) => void)[] = [];
|
||||
|
||||
// 添加通知
|
||||
addNotification(
|
||||
type: NotificationType,
|
||||
title: string,
|
||||
message: string,
|
||||
duration: number = 5000
|
||||
): string {
|
||||
const id = `notification-${Date.now()}-${Math.random()}`;
|
||||
const notification: AppNotification = {
|
||||
id,
|
||||
type,
|
||||
title,
|
||||
message,
|
||||
duration,
|
||||
timestamp: new Date(),
|
||||
};
|
||||
|
||||
this.notifications.push(notification);
|
||||
this.notifyListeners();
|
||||
|
||||
// 自动移除通知
|
||||
if (duration > 0) {
|
||||
setTimeout(() => {
|
||||
this.removeNotification(id);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
// 移除通知
|
||||
removeNotification(id: string): void {
|
||||
this.notifications = this.notifications.filter((n) => n.id !== id);
|
||||
this.notifyListeners();
|
||||
}
|
||||
|
||||
// 清空所有通知
|
||||
clearAll(): void {
|
||||
this.notifications = [];
|
||||
this.notifyListeners();
|
||||
}
|
||||
|
||||
// 获取所有通知
|
||||
getNotifications(): AppNotification[] {
|
||||
return [...this.notifications];
|
||||
}
|
||||
|
||||
// 添加监听器
|
||||
addListener(listener: (notifications: AppNotification[]) => void): void {
|
||||
this.listeners.push(listener);
|
||||
}
|
||||
|
||||
// 移除监听器
|
||||
removeListener(listener: (notifications: AppNotification[]) => void): void {
|
||||
this.listeners = this.listeners.filter((l) => l !== listener);
|
||||
}
|
||||
|
||||
// 通知所有监听器
|
||||
private notifyListeners(): void {
|
||||
this.listeners.forEach((listener) => listener(this.notifications));
|
||||
}
|
||||
|
||||
// 便捷方法
|
||||
success(title: string, message: string, duration?: number): string {
|
||||
return this.addNotification("success", title, message, duration);
|
||||
}
|
||||
|
||||
error(title: string, message: string, duration?: number): string {
|
||||
return this.addNotification("error", title, message, duration);
|
||||
}
|
||||
|
||||
warning(title: string, message: string, duration?: number): string {
|
||||
return this.addNotification("warning", title, message, duration);
|
||||
}
|
||||
|
||||
info(title: string, message: string, duration?: number): string {
|
||||
return this.addNotification("info", title, message, duration);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建全局通知管理器实例
|
||||
export const notificationManager = new NotificationManager();
|
||||
|
||||
// 浏览器通知 API
|
||||
export class BrowserNotifications {
|
||||
static async requestPermission(): Promise<boolean> {
|
||||
if (!("Notification" in window)) {
|
||||
console.warn("此浏览器不支持通知");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Notification.permission === "granted") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Notification.permission === "denied") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const permission = await Notification.requestPermission();
|
||||
return permission === "granted";
|
||||
}
|
||||
|
||||
static async showNotification(
|
||||
title: string,
|
||||
options?: NotificationOptions
|
||||
): Promise<globalThis.Notification | null> {
|
||||
if (!("Notification" in window)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Notification.permission !== "granted") {
|
||||
const granted = await this.requestPermission();
|
||||
if (!granted) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new globalThis.Notification(title, {
|
||||
icon: "/favicon.ico",
|
||||
badge: "/favicon.ico",
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
static async showRecordingComplete(): Promise<void> {
|
||||
await this.showNotification("录音完成", {
|
||||
body: "您的录音已成功保存",
|
||||
tag: "recording-complete",
|
||||
});
|
||||
}
|
||||
|
||||
static async showUploadComplete(): Promise<void> {
|
||||
await this.showNotification("上传完成", {
|
||||
body: "录音文件已成功上传到服务器",
|
||||
tag: "upload-complete",
|
||||
});
|
||||
}
|
||||
|
||||
static async showUploadError(): Promise<void> {
|
||||
await this.showNotification("上传失败", {
|
||||
body: "录音文件上传失败,请重试",
|
||||
tag: "upload-error",
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user