66 lines
2.5 KiB
TypeScript
66 lines
2.5 KiB
TypeScript
import app from "ags/gtk4/app"
|
|
import { Astal, Gtk } from "ags/gtk4"
|
|
import AstalNotifd from "gi://AstalNotifd"
|
|
import Notification from "./Notification"
|
|
import { createBinding, For, createState, onCleanup } from "ags"
|
|
|
|
export default function NotificationPopups() {
|
|
const monitors = createBinding(app, "monitors")
|
|
|
|
const notifd = AstalNotifd.get_default()
|
|
|
|
const [notifications, setNotifications] = createState(
|
|
new Array<AstalNotifd.Notification>(),
|
|
)
|
|
|
|
const notifiedHandler = notifd.connect("notified", (_, id, replaced) => {
|
|
const notification = notifd.get_notification(id)
|
|
|
|
if (replaced && notifications.get().some(n => n.id === id)) {
|
|
setNotifications((ns) => ns.map((n) => (n.id === id ? notification : n)))
|
|
} else {
|
|
setNotifications((ns) => [notification, ...ns])
|
|
}
|
|
})
|
|
|
|
const resolvedHandler = notifd.connect("resolved", (_, id) => {
|
|
setNotifications((ns) => ns.filter((n) => n.id !== id))
|
|
})
|
|
|
|
// technically, we don't need to cleanup because in this example this is a root component
|
|
// and this cleanup function is only called when the program exits, but exiting will cleanup either way
|
|
// but it's here to remind you that you should not forget to cleanup signal connections
|
|
onCleanup(() => {
|
|
notifd.disconnect(notifiedHandler)
|
|
notifd.disconnect(resolvedHandler)
|
|
})
|
|
|
|
return (
|
|
<For each={monitors} cleanup={(win) => (win as Gtk.Window).destroy()}>
|
|
{(monitor) => (
|
|
<window
|
|
class="NotificationPopups"
|
|
gdkmonitor={monitor}
|
|
visible={notifications((ns) => ns.length > 0)}
|
|
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT}
|
|
>
|
|
<box orientation={Gtk.Orientation.VERTICAL}>
|
|
<For each={notifications}>
|
|
{(notification) => (
|
|
<Notification
|
|
notification={notification}
|
|
onHoverLost={() =>
|
|
setNotifications((ns) =>
|
|
ns.filter((n) => n.id !== notification.id),
|
|
)
|
|
}
|
|
/>
|
|
)}
|
|
</For>
|
|
</box>
|
|
</window>
|
|
)}
|
|
</For>
|
|
)
|
|
}
|