import type { Message } from "../chat/types"; export async function registerNotificationServiceWorker(): Promise { if (typeof window === "undefined" || !("serviceWorker" in navigator)) { return; } try { await navigator.serviceWorker.register("/notifications-sw.js"); } catch { return; } } export async function showNotificationViaServiceWorker(params: { chatId: number; messageId: number; title: string; body: string; image?: string; }): Promise { if (typeof window === "undefined" || !("serviceWorker" in navigator)) { return false; } try { const registration = await navigator.serviceWorker.getRegistration(); if (!registration) { return false; } const url = `/?chat=${params.chatId}&message=${params.messageId}`; await registration.showNotification(params.title, { body: params.body, icon: params.image, tag: `chat-${params.chatId}`, data: { chatId: params.chatId, messageId: params.messageId, url, }, }); return true; } catch { return false; } } export function messagePreviewByType(type: Message["type"]): string { if (type === "image") return "Photo"; if (type === "video") return "Video"; if (type === "audio") return "Audio"; if (type === "voice") return "Voice message"; if (type === "file") return "File"; if (type === "circle_video") return "Video message"; return "New message"; } export function buildNotificationPreview( message: Message, withPreview: boolean ): { body: string; image?: string } { if (!withPreview) { return { body: "New message" }; } if (message.type !== "text") { if (message.type === "image") { const imageUrl = typeof message.text === "string" && isLikelyUrl(message.text) ? message.text : undefined; return { body: "🖼 Photo", image: imageUrl }; } return { body: messagePreviewByType(message.type) }; } const text = message.text?.trim(); if (!text) { return { body: "New message" }; } return { body: text }; } function isLikelyUrl(value: string): boolean { try { const parsed = new URL(value); return parsed.protocol === "http:" || parsed.protocol === "https:"; } catch { return false; } }