1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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
|