Restructure, prepare launcher
This commit is contained in:
		
							
								
								
									
										184
									
								
								config/ags/notifications/handler.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								config/ags/notifications/handler.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| /* | ||||
| *               dotfiles - handler.ts | ||||
| * | ||||
| *   Created by Janis Hutz 03/21/2025, Licensed under the GPL V3 License | ||||
| *           https://janishutz.com, development@janishutz.com | ||||
| * | ||||
| * | ||||
| */ | ||||
|  | ||||
| import { Astal, Gtk, Gdk } from "astal/gtk3" | ||||
| import Notifd from "gi://AstalNotifd"; | ||||
| import Notification from "./notifications/notifications"; | ||||
| import { type Subscribable } from "astal/binding"; | ||||
| import { Variable, bind, timeout } from "astal" | ||||
|  | ||||
| // Config | ||||
| const TIMEOUT_DELAY = 5000; | ||||
|  | ||||
| class Notifier implements Subscribable { | ||||
|     private display: Map<number, Gtk.Widget> = new Map(); | ||||
|     private notifications: Map<number, Notifd.Notification> = new Map(); | ||||
|  | ||||
|     private notifd: Notifd.Notifd; | ||||
|     private subscriberData: Variable<Gtk.Widget[]> = Variable( [] ); | ||||
|     private instanceID: number; | ||||
|     private menuOpen: boolean; | ||||
|  | ||||
|     /** | ||||
|      * Sets up the notifier | ||||
|      */ | ||||
|     constructor( id: number ) { | ||||
|         this.instanceID = id; | ||||
|         this.menuOpen = false; | ||||
|         this.notifd = Notifd.get_default(); | ||||
|         this.notifd.ignoreTimeout = true; | ||||
|  | ||||
|         this.notifd.connect( 'notified', ( _, id ) => { | ||||
|             this.add( id ); | ||||
|         } ); | ||||
|  | ||||
|         this.notifd.connect( 'resolved', ( _, id ) => { | ||||
|             this.hide( id ); | ||||
|         } ); | ||||
|     } | ||||
|  | ||||
|     private notify () { | ||||
|         this.subscriberData.set( [ ...this.display.values() ].reverse() ); | ||||
|     } | ||||
|  | ||||
|     private add ( id: number ) { | ||||
|         this.notifications.set( id, this.notifd.get_notification( id )! ); | ||||
|         this.show( id ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show an element on screen | ||||
|      * @param id - The id of the element to be shown | ||||
|      */ | ||||
|     private show ( id: number ) { | ||||
|         this.set( id, Notification( { | ||||
|             notification: this.notifications.get( id )!, | ||||
|             onHoverLost: () => this.hide( id ), | ||||
|             setup: () => timeout( TIMEOUT_DELAY, () => { | ||||
|                 if ( !this.menuOpen ) { | ||||
|                     this.hide( id ); | ||||
|                 } | ||||
|             } ), | ||||
|             id: id, | ||||
|             delete: deleteHelper, | ||||
|             instanceID: this.instanceID | ||||
|         } ) ) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set a selected widget to be shown | ||||
|      * @param id - The id of the element to be referenced for later | ||||
|      * @param widget - A GTK widget instance | ||||
|      */ | ||||
|     private set ( id: number, widget: Gtk.Widget ) { | ||||
|         this.display.get( id )?.destroy(); | ||||
|         this.display.set( id, widget ); | ||||
|         this.notify(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Hide, not delete notification (= send to notification centre) | ||||
|      * @param id - The id of the notification to hide | ||||
|      */ | ||||
|     private hide ( id: number ) { | ||||
|         this.display.get( id )?.destroy(); | ||||
|         this.display.delete( id ); | ||||
|         this.notify(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Delete a notification (from notification centre too) | ||||
|      * @param id - The id of the notification to hide | ||||
|      */ | ||||
|     delete ( id: number ) { | ||||
|         this.hide( id ); | ||||
|         this.notifications.get( id )?.dismiss(); | ||||
|         this.notifications.delete( id ); | ||||
|     } | ||||
|  | ||||
|     openNotificationMenu () { | ||||
|         // Show all notifications that have not been cleared | ||||
|         this.menuOpen = true; | ||||
|         this.notifications.forEach( ( _, id ) => { | ||||
|             this.show( id ); | ||||
|         } ) | ||||
|     } | ||||
|  | ||||
|     hideNotifications () { | ||||
|         this.menuOpen = false; | ||||
|         this.notifications.forEach( ( _, id ) => { | ||||
|             this.hide( id ); | ||||
|         } ) | ||||
|     } | ||||
|  | ||||
|     clearAllNotifications () { | ||||
|         this.menuOpen = false; | ||||
|         this.notifications.forEach( ( _, id ) => { | ||||
|             this.delete( id ); | ||||
|         } ) | ||||
|     } | ||||
|  | ||||
|     clearNewestNotification () { | ||||
|         this.delete( [ ...this.notifications.keys() ][0] ); | ||||
|     } | ||||
|  | ||||
|     subscribe(callback: (value: unknown) => void): () => void { | ||||
|         return this.subscriberData.subscribe( callback ); | ||||
|     } | ||||
|  | ||||
|     get() { | ||||
|         return this.subscriberData.get(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| const notifiers: Map<number, Notifier> = new Map(); | ||||
| const deleteHelper = ( id: number, instanceID: number ) => { | ||||
|     notifiers.get( instanceID )?.delete( id ); | ||||
| } | ||||
|  | ||||
| const openNotificationMenu = ( id: number ) => { | ||||
|     notifiers.get( id )?.openNotificationMenu(); | ||||
| } | ||||
|  | ||||
| const closeNotificationMenu = ( id: number ) => { | ||||
|     notifiers.get( id )?.hideNotifications(); | ||||
| } | ||||
|  | ||||
| const clearAllNotifications = ( id: number ) => { | ||||
|     notifiers.get( id )?.clearAllNotifications(); | ||||
| } | ||||
|  | ||||
| const clearNewestNotifications = ( id: number ) => { | ||||
|     notifiers.get( id )?.clearNewestNotification(); | ||||
| } | ||||
|  | ||||
| const startNotificationHandler = (id: number, gdkmonitor: Gdk.Monitor) => { | ||||
|     const { TOP, RIGHT } = Astal.WindowAnchor | ||||
|     const notifier: Notifier = new Notifier( id ); | ||||
|     notifiers.set( id, notifier ); | ||||
|  | ||||
|     return <window | ||||
|         className="NotificationHandler" | ||||
|         gdkmonitor={gdkmonitor} | ||||
|         exclusivity={Astal.Exclusivity.EXCLUSIVE} | ||||
|         anchor={TOP | RIGHT}> | ||||
|         <box vertical noImplicitDestroy> | ||||
|             {bind(notifier)} | ||||
|         </box> | ||||
|     </window> | ||||
| } | ||||
|  | ||||
|  | ||||
| export default { | ||||
|     startNotificationHandler, | ||||
|     openNotificationMenu, | ||||
|     closeNotificationMenu, | ||||
|     clearAllNotifications, | ||||
|     clearNewestNotifications | ||||
| } | ||||
		Reference in New Issue
	
	Block a user