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>
 | 
						|
    );
 | 
						|
}
 |