import { TranslatedString } from "@gnu-taler/taler-util"; import { useEffect, useState } from "preact/hooks"; import { memoryMap } from "../index.browser.js"; export type NotificationMessage = ErrorNotification | InfoNotification; export interface ErrorNotification { type: "error"; title: TranslatedString; description?: TranslatedString; debug?: string; } export interface InfoNotification { type: "info"; title: TranslatedString; } const storage = memoryMap>(); const NOTIFICATION_KEY = "notification"; export function notify(notif: NotificationMessage): void { const currentState: Map = storage.get(NOTIFICATION_KEY) ?? new Map(); const newState = currentState.set(hash(notif), notif); storage.set(NOTIFICATION_KEY, newState); } export function notifyError( title: TranslatedString, description: TranslatedString | undefined, debug?: any, ) { notify({ type: "error" as const, title, description, debug, }); } export function notifyInfo(title: TranslatedString) { notify({ type: "info" as const, title, }); } type Notification = { message: NotificationMessage; remove: () => void; }; export function useNotifications(): Notification[] { const [value, setter] = useState>(new Map()); useEffect(() => { return storage.onUpdate(NOTIFICATION_KEY, () => { const mem = storage.get(NOTIFICATION_KEY) ?? new Map(); setter(mem); }); }); return Array.from(value.values()).map((message, idx) => { return { message, remove: () => { const mem = storage.get(NOTIFICATION_KEY) ?? new Map(); const newState = new Map(mem); newState.delete(hash(message)); storage.set(NOTIFICATION_KEY, newState); }, }; }); } function hashCode(str: string): string { if (str.length === 0) return "0"; let hash = 0; let chr; for (let i = 0; i < str.length; i++) { chr = str.charCodeAt(i); hash = (hash << 5) - hash + chr; hash |= 0; // Convert to 32bit integer } return hash.toString(16); } function hash(msg: NotificationMessage): string { let str = (msg.type + ":" + msg.title) as string; if (msg.type === "error") { if (msg.description) { str += ":" + msg.description; } if (msg.debug) { str += ":" + msg.debug; } } return hashCode(str); }