summaryrefslogtreecommitdiff
path: root/pkgs/astal/src/widget/deck/notifications.lua
blob: e40a815b9f9b500fe7b493458a31dba31c5d284c (plain)
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