summaryrefslogtreecommitdiff
path: root/pkgs/astal/src/widget/deck/notifications.lua
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-06-18 11:34:06 -0400
committerFreya Murphy <freya@freyacat.org>2025-06-18 11:34:06 -0400
commitf11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672 (patch)
treea3b4425f1e87b1aef2f0e93d6570b1d3f3c69d8d /pkgs/astal/src/widget/deck/notifications.lua
parentupdate hyprland config (diff)
downloaddotfiles-nix-f11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672.tar.gz
dotfiles-nix-f11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672.tar.bz2
dotfiles-nix-f11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672.zip
add notifications to astal
Diffstat (limited to '')
-rw-r--r--pkgs/astal/src/widget/deck/notifications.lua136
1 files changed, 136 insertions, 0 deletions
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