import { Gdk, Gtk } from "ags/gtk4"; import { Separator } from "./Separator"; import { HistoryNotification, Notifications } from "../scripts/notifications"; import { getAppIcon, getSymbolicIcon } from "../scripts/apps"; import AstalNotifd from "gi://AstalNotifd"; import Pango from "gi://Pango?version=1.0"; import GLib from "gi://GLib?version=2.0"; import GObject from "gi://GObject?version=2.0"; function getNotificationImage(notif: AstalNotifd.Notification|HistoryNotification): (string|undefined) { const img = notif.image || notif.appIcon; if(!img || !img.includes('/')) return undefined; switch(true) { case /^[/]/.test(img): return `file://${img}`; case /^[~]/.test(img): case /^file:\/\/[~]/i.test(img): return `file://${GLib.get_home_dir()}/${img.replace(/^(file\:\/\/|[~]|file\:\/\[~])/i, "")}`; } return img; } export function NotificationWidget({ notification, actionClicked, holdOnHover, showTime, actionClose }: { notification: AstalNotifd.Notification|number|HistoryNotification; actionClicked?: (notif: AstalNotifd.Notification|HistoryNotification) => void; actionClose?: (notif: AstalNotifd.Notification|HistoryNotification) => void; holdOnHover?: boolean; showTime?: boolean; // It's showTime :speaking_head: :boom: :bangbang: }): Gtk.Widget { notification = (typeof notification === "number") ? AstalNotifd.get_default().get_notification(notification) : notification; const conns: Map> = new Map(); return { const eventControllerMotion = Gtk.EventControllerMotion.new(), gestureClick = Gtk.GestureClick.new(); self.add_controller(eventControllerMotion); self.add_controller(gestureClick); conns.set(eventControllerMotion, [ eventControllerMotion.connect("enter", () => holdOnHover && Notifications.getDefault().holdNotification(notification.id)), eventControllerMotion.connect("leave", () => holdOnHover && Notifications.getDefault().removeNotification(notification.id)) ]); conns.set(gestureClick, [ gestureClick.connect("released", (gesture) => { gesture.get_current_button() === Gdk.BUTTON_PRIMARY && actionClicked?.(notification); }) ]); }} onDestroy={(_) => { conns.forEach((ids, obj) => ids.forEach(id => obj.disconnect(id))); }}> { const icon = getSymbolicIcon(notification.appIcon ?? notification.appName) ?? getSymbolicIcon(notification.appName) ?? getAppIcon(notification.appName); if(icon) { self.set_from_icon_name(icon); return; } self.set_visible(false); }} /> { const image = getNotificationImage(notification); image && self.prepend(Gtk.Picture.new_for_filename(image)); }}> action.label.toLowerCase() !== "view").length > 0) }> { (notification instanceof AstalNotifd.Notification) && notification.actions.filter(a => a.label.toLowerCase() !== "view").map(action => { notification.invoke(action.id); actionClose?.(notification); }} />) } as Gtk.Widget; }