From f11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Wed, 18 Jun 2025 11:34:06 -0400 Subject: add notifications to astal --- pkgs/astal/src/widget/deck/notifications.lua | 136 +++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 pkgs/astal/src/widget/deck/notifications.lua (limited to 'pkgs/astal/src/widget/deck/notifications.lua') diff --git a/pkgs/astal/src/widget/deck/notifications.lua b/pkgs/astal/src/widget/deck/notifications.lua new file mode 100644 index 0000000..e40a815 --- /dev/null +++ b/pkgs/astal/src/widget/deck/notifications.lua @@ -0,0 +1,136 @@ +local astal = require("astal") +local Widget = require("astal.gtk3").Widget +local Gtk = require("astal.gtk3").Gtk +local Variable = require("astal").Variable +local Notifd = astal.require("AstalNotifd") +local lib = require("lib") +local bind = astal.bind +local timeout = astal.timeout + +local TIMEOUT_DELAY = 5000 + +local notifd = Notifd.get_default() +local notifs = Variable({}) +local map = {} + +function update() + local arr = {} + for id,_ in pairs(map) do + table.insert(arr, id) + end + notifs:set(arr) +end + +function set(_, id) + map[id] = true + update() +end + +function delete(id) + map[id] = nil + update() +end + +notifd.on_notified = set + +function Header(notif) + local show_icon = lib.is_true(notif.app_icon) or + lib.is_true(notif.desktop_entry) + + return Widget.Box({ + class_name = "header", + show_icon and Widget.Icon({ + class_name = "app-icon", + icon = notif.app_icon or notif.desktop_entry, + }), + Widget.Label({ + class_name = "app-name", + halign = "START", + ellipsize = "END", + label = notif.app_name or "", + }), + Widget.Label({ + class_name = "time", + hexpand = true, + halign = "END", + label = lib.time(notif.time), + }), + Widget.Button({ + on_clicked = function() delete(notif.id) end, + Widget.Icon({ icon = "window-close-symbolic" }), + }), + }) +end + +function Content(notif) + return Widget.Box({ + class_name = "content", + (notif.image and lib.file_exists(notif.image)) and Widget.Box({ + valign = "START", + class_name = "image", + css = string.format("background-image: url('%s')", notif.image), + }), + (notif.image and lib.is_icon(notif.image)) and Widget.Box({ + valign = "START", + class_name = "icon-image", + Widget.Icon({ + icon = notif.image, + hexpand = true, + vexpand = true, + halign = "CENTER", + valign = "CENTER", + }), + }), + Widget.Box({ + vertical = true, + Widget.Label({ + class_name = "summary", + halign = "START", + xalign = 0, + ellipsize = "END", + label = notif.summary, + }), + Widget.Label({ + class_name = "body", + wrap = true, + use_markup = true, + halign = "START", + xalign = 0, + justify = "FILL", + label = notif.body, + }), + }), + }) +end + +function Notification(id) + local notif = notifd:get_notification(id) + + local function destroy() + delete(id) + end + + local function setup() + timeout(TIMEOUT_DELAY, destroy) + end + + return Widget.EventBox({ + class_name = "notification", + setup = setup, + on_hover_lost = destroy, + Widget.Box({ + vertical = true, + Header(notif), + Gtk.Separator({ visible = true }), + Content(notif), + }), + }) +end + +function Notifications(ids) + return lib.map(ids, Notification) +end + +return function() + return bind(notifs):as(Notifications) +end -- cgit v1.2.3-freya