import app from "ags/gtk3/app" import { Astal, Gtk } from "ags/gtk3" import { createPoll } from "ags/time" import { For } from "ags" import { sh, shell } from "../lib/utils" export const NOTIFICATION_WINDOW = "notification-center" type Notification = { file: string appName: string summary: string body: string timestamp: number } const NOTIFICATION_DIR = "$HOME/.local/state/omarchy/notifications" const listCommand = `for file in "${NOTIFICATION_DIR}"/*.json "${NOTIFICATION_DIR}"/history/*.json; do ` + "[ -f \"$file\" ] || continue; " + "printf '%s\\t%s\\n' \"$file\" \"$(head -n 1 \"$file\")\"; " + "done" function parseNotifications(stdout: string): Notification[] { return stdout .split("\n") .filter((line) => line.includes("\t")) .map((line) => { const separator = line.indexOf("\t") const file = line.slice(0, separator) try { const entry = JSON.parse(line.slice(separator + 1)) return { file, appName: String(entry.app ?? ""), summary: String(entry.summary ?? ""), body: String(entry.body ?? ""), timestamp: Number(entry.timestamp ?? 0), } } catch { return null } }) .filter((item): item is Notification => item !== null) .sort((left, right) => right.timestamp - left.timestamp) } const notifications = createPoll( [], 1000, shell(listCommand), (stdout) => parseNotifications(stdout), ) const doNotDisturb = createPoll( false, 1000, shell("omarchy-shell notifications dndState 2>/dev/null"), (stdout) => stdout.trim() === "on", ) const dismiss = (file: string) => sh(`rm -f '${file.replace(/'/g, "'\\''")}'`) const clearAll = () => sh("omarchy-shell notifications dismissAll; omarchy-shell notifications clear") const toggleDoNotDisturb = () => sh("omarchy-shell notifications toggleDnd") function NotificationItem({ item }: { item: Notification }) { return ( ) } export default function NotificationCenter() { const { TOP, RIGHT } = Astal.WindowAnchor const hasNotifications = notifications.as((list) => list.length > 0) const isEmpty = notifications.as((list) => list.length === 0) return ( item.file}> {(item: Notification) => } ) }