diff options
| author | srdusr <trevorgray@srdusr.com> | 2024-06-13 13:11:05 +0200 |
|---|---|---|
| committer | srdusr <trevorgray@srdusr.com> | 2024-06-13 13:11:05 +0200 |
| commit | d0fbb19623e4fb6097e1ff3ee49c6a76a0928d0e (patch) | |
| tree | 937531ddf423d3935c6e20c8a9227e39ce782241 /.config/ags/widget/datemenu/NotificationColumn.ts | |
| parent | 4ccbe0270c25ecab492508b5b0209ae53b9c35bd (diff) | |
| download | dotfiles-d0fbb19623e4fb6097e1ff3ee49c6a76a0928d0e.tar.gz dotfiles-d0fbb19623e4fb6097e1ff3ee49c6a76a0928d0e.zip | |
Add ags
Diffstat (limited to '.config/ags/widget/datemenu/NotificationColumn.ts')
| -rw-r--r-- | .config/ags/widget/datemenu/NotificationColumn.ts | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/.config/ags/widget/datemenu/NotificationColumn.ts b/.config/ags/widget/datemenu/NotificationColumn.ts new file mode 100644 index 0000000..07d6829 --- /dev/null +++ b/.config/ags/widget/datemenu/NotificationColumn.ts @@ -0,0 +1,113 @@ +import { type Notification as Notif } from "types/service/notifications" +import Notification from "widget/notifications/Notification" +import options from "options" +import icons from "lib/icons" + +const notifications = await Service.import("notifications") +const notifs = notifications.bind("notifications") + +const Animated = (n: Notif) => Widget.Revealer({ + transition_duration: options.transition.value, + transition: "slide_down", + child: Notification(n), + setup: self => Utils.timeout(options.transition.value, () => { + if (!self.is_destroyed) + self.reveal_child = true + }), +}) + +const ClearButton = () => Widget.Button({ + on_clicked: notifications.clear, + sensitive: notifs.as(n => n.length > 0), + child: Widget.Box({ + children: [ + Widget.Label("Clear "), + Widget.Icon({ + icon: notifs.as(n => icons.trash[n.length > 0 ? "full" : "empty"]), + }), + ], + }), +}) + +const Header = () => Widget.Box({ + class_name: "header", + children: [ + Widget.Label({ label: "Notifications", hexpand: true, xalign: 0 }), + ClearButton(), + ], +}) + +const NotificationList = () => { + const map: Map<number, ReturnType<typeof Animated>> = new Map + const box = Widget.Box({ + vertical: true, + children: notifications.notifications.map(n => { + const w = Animated(n) + map.set(n.id, w) + return w + }), + visible: notifs.as(n => n.length > 0), + }) + + function remove(_: unknown, id: number) { + const n = map.get(id) + if (n) { + n.reveal_child = false + Utils.timeout(options.transition.value, () => { + n.destroy() + map.delete(id) + }) + } + } + + return box + .hook(notifications, remove, "closed") + .hook(notifications, (_, id: number) => { + if (id !== undefined) { + if (map.has(id)) + remove(null, id) + + const n = notifications.getNotification(id)! + + const w = Animated(n) + map.set(id, w) + box.children = [w, ...box.children] + } + }, "notified") +} + +const Placeholder = () => Widget.Box({ + class_name: "placeholder", + vertical: true, + vpack: "center", + hpack: "center", + vexpand: true, + hexpand: true, + visible: notifs.as(n => n.length === 0), + children: [ + Widget.Icon(icons.notifications.silent), + Widget.Label("Your inbox is empty"), + ], +}) + +export default () => Widget.Box({ + class_name: "notifications", + css: options.notifications.width.bind().as(w => `min-width: ${w}px`), + vertical: true, + children: [ + Header(), + Widget.Scrollable({ + vexpand: true, + hscroll: "never", + class_name: "notification-scrollable", + child: Widget.Box({ + class_name: "notification-list vertical", + vertical: true, + children: [ + NotificationList(), + Placeholder(), + ], + }), + }), + ], +}) |
