From 407b909aab452baacadb6417bc51f237dfc2ce15 Mon Sep 17 00:00:00 2001 From: biscuit Date: Thu, 15 May 2025 13:44:34 -0500 Subject: [PATCH] astal: removed notif module --- .../ags/custom/notification/Notification.scss | 125 ------------------ .../ags/custom/notification/Notification.tsx | 107 --------------- .../notification/NotificationPopups.tsx | 105 --------------- 3 files changed, 337 deletions(-) delete mode 100644 packages/ags/custom/notification/Notification.scss delete mode 100644 packages/ags/custom/notification/Notification.tsx delete mode 100644 packages/ags/custom/notification/NotificationPopups.tsx diff --git a/packages/ags/custom/notification/Notification.scss b/packages/ags/custom/notification/Notification.scss deleted file mode 100644 index a32f08b..0000000 --- a/packages/ags/custom/notification/Notification.scss +++ /dev/null @@ -1,125 +0,0 @@ -@use "sass:string"; - -@function gtkalpha($c, $a) { - @return string.unquote("alpha(#{$c},#{$a})"); -} - -// https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gtk/theme/Adwaita/_colors-public.scss -$fg-color: #{"@theme_fg_color"}; -$bg-color: #{"@theme_bg_color"}; -$error: red; - -window.NotificationPopups { - all: unset; -} - -eventbox.Notification { - - &:first-child>box { - margin-top: 1rem; - } - - &:last-child>box { - margin-bottom: 1rem; - } - - // eventboxes can not take margins so we style its inner box instead - >box { - min-width: 400px; - border-radius: 13px; - background-color: $bg-color; - margin: .5rem 1rem .5rem 1rem; - box-shadow: 2px 3px 8px 0 gtkalpha(black, .4); - border: 1pt solid gtkalpha($fg-color, .03); - } - - &.critical>box { - border: 1pt solid gtkalpha($error, .4); - - .header { - - .app-name { - color: gtkalpha($error, .8); - - } - - .app-icon { - color: gtkalpha($error, .6); - } - } - } - - .header { - padding: .5rem; - color: gtkalpha($fg-color, 0.5); - - .app-icon { - margin: 0 .4rem; - } - - .app-name { - margin-right: .3rem; - font-weight: bold; - - &:first-child { - margin-left: .4rem; - } - } - - .time { - margin: 0 .4rem; - } - - button { - padding: .2rem; - min-width: 0; - min-height: 0; - } - } - - separator { - margin: 0 .4rem; - background-color: gtkalpha($fg-color, .1); - } - - .content { - margin: 1rem; - margin-top: .5rem; - - .summary { - font-size: 1.2em; - color: $fg-color; - } - - .body { - color: gtkalpha($fg-color, 0.8); - } - - .image { - border: 1px solid gtkalpha($fg-color, .02); - margin-right: .5rem; - border-radius: 9px; - min-width: 100px; - min-height: 100px; - background-size: cover; - background-position: center; - } - } - - .actions { - margin: 1rem; - margin-top: 0; - - button { - margin: 0 .3rem; - - &:first-child { - margin-left: 0; - } - - &:last-child { - margin-right: 0; - } - } - } -} diff --git a/packages/ags/custom/notification/Notification.tsx b/packages/ags/custom/notification/Notification.tsx deleted file mode 100644 index 5149d5b..0000000 --- a/packages/ags/custom/notification/Notification.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { GLib } from "astal" -import { Gtk, Astal } from "astal/gtk3" -import { type EventBox } from "astal/gtk3/widget" -import Notifd from "gi://AstalNotifd" - -const isIcon = (icon: string) => - !!Astal.Icon.lookup_icon(icon) - -const fileExists = (path: string) => - GLib.file_test(path, GLib.FileTest.EXISTS) - -const time = (time: number, format = "%H:%M") => GLib.DateTime - .new_from_unix_local(time) - .format(format)! - -const urgency = (n: Notifd.Notification) => { - const { LOW, NORMAL, CRITICAL } = Notifd.Urgency - // match operator when? - switch (n.urgency) { - case LOW: return "low" - case CRITICAL: return "critical" - case NORMAL: - default: return "normal" - } -} - -type Props = { - setup(self: EventBox): void - onHoverLost(self: EventBox): void - notification: Notifd.Notification -} - -export default function Notification(props: Props) { - const { notification: n, onHoverLost, setup } = props - const { START, CENTER, END } = Gtk.Align - - return - - - {(n.appIcon || n.desktopEntry) && } - - - - {n.image && fileExists(n.image) && } - {n.image && isIcon(n.image) && - - } - - - - {n.get_actions().length > 0 && - {n.get_actions().map(({ label, id }) => ( - - ))} - } - - -} diff --git a/packages/ags/custom/notification/NotificationPopups.tsx b/packages/ags/custom/notification/NotificationPopups.tsx deleted file mode 100644 index 13fdd88..0000000 --- a/packages/ags/custom/notification/NotificationPopups.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { Astal, Gtk, Gdk } from "astal/gtk3" -import Notifd from "gi://AstalNotifd" -import Notification from "./Notification" -import { type Subscribable } from "astal/binding" -import { Variable, bind, timeout } from "astal" - -// see comment below in constructor -const TIMEOUT_DELAY = 5000 - -// The purpose if this class is to replace Variable> -// with a Map type in order to track notification widgets -// by their id, while making it conviniently bindable as an array -class NotifiationMap implements Subscribable { - // the underlying map to keep track of id widget pairs - private map: Map = new Map() - - // it makes sense to use a Variable under the hood and use its - // reactivity implementation instead of keeping track of subscribers ourselves - private var: Variable> = Variable([]) - - // notify subscribers to rerender when state changes - private notifiy() { - this.var.set([...this.map.values()].reverse()) - } - - constructor() { - const notifd = Notifd.get_default() - - /** - * uncomment this if you want to - * ignore timeout by senders and enforce our own timeout - * note that if the notification has any actions - * they might not work, since the sender already treats them as resolved - */ - // notifd.ignoreTimeout = true - - notifd.connect("notified", (_, id) => { - this.set(id, Notification({ - notification: notifd.get_notification(id)!, - - // once hovering over the notification is done - // destroy the widget without calling notification.dismiss() - // so that it acts as a "popup" and we can still display it - // in a notification center like widget - // but clicking on the close button will close it - onHoverLost: () => this.delete(id), - - // notifd by default does not close notifications - // until user input or the timeout specified by sender - // which we set to ignore above - setup: () => timeout(TIMEOUT_DELAY, () => { - /** - * uncomment this if you want to "hide" the notifications - * after TIMEOUT_DELAY - */ - // this.delete(id) - }) - })) - }) - - // notifications can be closed by the outside before - // any user input, which have to be handled too - notifd.connect("resolved", (_, id) => { - this.delete(id) - }) - } - - private set(key: number, value: Gtk.Widget) { - // in case of replacecment destroy previous widget - this.map.get(key)?.destroy() - this.map.set(key, value) - this.notifiy() - } - - private delete(key: number) { - this.map.get(key)?.destroy() - this.map.delete(key) - this.notifiy() - } - - // needed by the Subscribable interface - get() { - return this.var.get() - } - - // needed by the Subscribable interface - subscribe(callback: (list: Array) => void) { - return this.var.subscribe(callback) - } -} - -export default function NotificationPopups(gdkmonitor: Gdk.Monitor) { - const { TOP, RIGHT } = Astal.WindowAnchor - const notifs = new NotifiationMap() - - return - - {bind(notifs)} - - -}