[AGS] GTK 4 Migration: Done, Start adding QuickActions
Probably gonna abandon the QuickActions, as that is just way too much effort for what it does. Will be providing keybinds for doing what I wanted to do there in Hyprland
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { Astal, Gdk } from "astal/gtk4"
|
||||
import { App, Astal, Gdk } from "astal/gtk4"
|
||||
import Notifd from "gi://AstalNotifd";
|
||||
import Notification from "./notifications";
|
||||
import { timeout, Variable } from "astal"
|
||||
@@ -31,8 +31,7 @@ interface NotificationDetails {
|
||||
// │ Handler │
|
||||
// ╰───────────────────────────────────────────────╯
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
let ShownNotifications: number[] = [];
|
||||
const ShownNotificationsCount: Variable<number> = Variable( 0 );
|
||||
let ShownNotifications: Variable<number[]> = Variable( [] );
|
||||
let Notifications: NotificationDetails[] = [];
|
||||
|
||||
const notifd = Notifd.get_default();
|
||||
@@ -46,6 +45,9 @@ notifd.ignoreTimeout = true;
|
||||
const deleteNotification = ( index: number ): void => {
|
||||
hideNotification( index );
|
||||
Notifications.splice( index, 1 );
|
||||
if ( Notifications.length === 0 ) {
|
||||
notificationMenuOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
@@ -133,9 +135,9 @@ const hookToNotificationDaemon = (): void => {
|
||||
*/
|
||||
const showNotification = ( id: number, removeAgain: boolean = true ) => {
|
||||
// Add notification to UI for display
|
||||
ShownNotifications.reverse().push( id );
|
||||
ShownNotifications.reverse();
|
||||
ShownNotificationsCount.set( ShownNotifications.length );
|
||||
const not = [...ShownNotifications.get()].reverse();
|
||||
not.push( id );
|
||||
ShownNotifications.set( not.reverse() );
|
||||
|
||||
// Set delay to remove the notification again
|
||||
if ( removeAgain && Notifications[ id ].notification.get_urgency() !== Notifd.Urgency.CRITICAL ) {
|
||||
@@ -154,7 +156,9 @@ const showNotification = ( id: number, removeAgain: boolean = true ) => {
|
||||
*/
|
||||
const hideNotification = ( id: number ) => {
|
||||
if ( !notificationMenuOpen ) {
|
||||
ShownNotifications.splice( ShownNotifications.indexOf( id ), 1 );
|
||||
const not = [...ShownNotifications.get()];
|
||||
not.splice( not.indexOf( id ), 1 );
|
||||
ShownNotifications.set( not );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,10 +171,11 @@ const hideNotification = ( id: number ) => {
|
||||
const openNotificationMenu = () => {
|
||||
// Simply show all notifications
|
||||
notificationMenuOpen = true;
|
||||
const ShownNotifications = [];
|
||||
const not = [];
|
||||
for (let index = 0; index < Notifications.length; index++) {
|
||||
ShownNotifications.push( index );
|
||||
not.push( index );
|
||||
}
|
||||
ShownNotifications.set( not.reverse() );
|
||||
}
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
@@ -182,9 +187,7 @@ const openNotificationMenu = () => {
|
||||
const closeNotificationMenu = () => {
|
||||
// Hide all notifications
|
||||
notificationMenuOpen = true;
|
||||
|
||||
ShownNotifications = [];
|
||||
ShownNotificationsCount.set( 0 );
|
||||
ShownNotifications.set( [] );
|
||||
}
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
@@ -193,11 +196,13 @@ const closeNotificationMenu = () => {
|
||||
/**
|
||||
* Toggle the notification menu (i.e. show all notifications)
|
||||
*/
|
||||
const toggleNotificationMenu = () => {
|
||||
const toggleNotificationMenu = (): string => {
|
||||
if ( notificationMenuOpen ) {
|
||||
closeNotificationMenu();
|
||||
return 'Toggle notification menu closed';
|
||||
} else {
|
||||
openNotificationMenu();
|
||||
return 'Toggled notification menu open';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,8 +214,9 @@ const toggleNotificationMenu = () => {
|
||||
*/
|
||||
const clearAllNotifications = () => {
|
||||
Notifications = [];
|
||||
ShownNotifications = [];
|
||||
ShownNotificationsCount.set( 0 );
|
||||
ShownNotifications.set( [] );
|
||||
// TODO: Hiding for each individual deleteNotification
|
||||
notificationMenuOpen = false;
|
||||
}
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
@@ -220,7 +226,9 @@ const clearAllNotifications = () => {
|
||||
* Delete the newest notifications
|
||||
*/
|
||||
const clearNewestNotifications = () => {
|
||||
ShownNotifications.splice( 0, 1 );
|
||||
const not = [...ShownNotifications.get()];
|
||||
not.splice( 0, 1 );
|
||||
ShownNotifications.set( not );
|
||||
|
||||
Notifications.splice( Notifications.length - 1, 1 );
|
||||
}
|
||||
@@ -236,16 +244,16 @@ const startNotificationHandler = (gdkmonitor: Gdk.Monitor) => {
|
||||
const { TOP, RIGHT } = Astal.WindowAnchor
|
||||
|
||||
hookToNotificationDaemon();
|
||||
const range = (n: number) => [...Array(n).keys()];
|
||||
|
||||
return <window
|
||||
cssClasses={["NotificationHandler"]}
|
||||
gdkmonitor={gdkmonitor}
|
||||
exclusivity={Astal.Exclusivity.EXCLUSIVE}
|
||||
anchor={TOP | RIGHT}>
|
||||
<box vertical noImplicitDestroy>
|
||||
{ShownNotificationsCount( n => range( n ).map( i => {
|
||||
print( 'Rendering' );
|
||||
anchor={TOP | RIGHT}
|
||||
visible={ShownNotifications( list => list.length > 0 )}
|
||||
application={App}>
|
||||
<box vertical>
|
||||
{ShownNotifications( list => list.map( i => {
|
||||
// i is index in ShownNotifications array
|
||||
return <Notification id={i} delete={deleteNotification} notification={Notifications[ i ].notification}></Notification>
|
||||
} ) ) }
|
||||
@@ -267,8 +275,19 @@ const cliHandler = ( args: string[] ): string => {
|
||||
clearNewestNotifications();
|
||||
return 'Cleared newest notification';
|
||||
} else if ( args[ 1 ] == 'toggle' ) {
|
||||
toggleNotificationMenu();
|
||||
return 'Toggled notifications';
|
||||
return toggleNotificationMenu();
|
||||
} else if ( args[ 1 ] == 'list' ){
|
||||
if ( Notifications.length > 0 ) {
|
||||
let list = 'Currently unviewed notifications: ';
|
||||
for (let index = 0; index < Notifications.length; index++) {
|
||||
const element = Notifications[index];
|
||||
|
||||
list += `\n - (${element.notifdID}) ${element.notification.get_app_name()}: ${element.notification.get_summary()}`;
|
||||
}
|
||||
return list;
|
||||
} else {
|
||||
return 'No currently unviewed notifications'
|
||||
}
|
||||
} else {
|
||||
return 'Unknown command!';
|
||||
}
|
||||
|
@@ -14,22 +14,25 @@ window.NotificationHandler {
|
||||
}
|
||||
|
||||
box.Notification {
|
||||
min-width: 400px;
|
||||
border-radius: 13px;
|
||||
background-color: $bg-color;
|
||||
margin: .5rem 1rem .5rem 1rem;
|
||||
box-shadow: 2px 3px 8px 0 gtkalpha(black, .4);
|
||||
border: 1pt solid gtkalpha($fg-color, .03);
|
||||
|
||||
&:first-child>box {
|
||||
&:first-child {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
&:last-child>box {
|
||||
&:last-child {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
&.critical>box {
|
||||
& {
|
||||
min-width: 400px;
|
||||
border-radius: 13px;
|
||||
background-color: $bg-color;
|
||||
margin: .5rem 1rem .5rem 1rem;
|
||||
box-shadow: 2px 3px 8px 0 gtkalpha(black, .4);
|
||||
border: 1pt solid gtkalpha($fg-color, .03);
|
||||
}
|
||||
|
||||
&.critical {
|
||||
border: 1pt solid gtkalpha($error, .4);
|
||||
|
||||
.header {
|
||||
|
@@ -24,9 +24,9 @@ const urgency = (n: Notifd.Notification) => {
|
||||
}
|
||||
|
||||
type Props = {
|
||||
delete( id: number ): void
|
||||
delete: ( id: number ) => void;
|
||||
notification: Notifd.Notification
|
||||
id: number
|
||||
id: number,
|
||||
}
|
||||
|
||||
export default function Notification(props: Props) {
|
||||
@@ -34,54 +34,54 @@ export default function Notification(props: Props) {
|
||||
const { START, CENTER, END } = Gtk.Align
|
||||
|
||||
return <box vertical
|
||||
cssClasses={['Notification', urgency(n)]}>
|
||||
<box cssName="header">
|
||||
cssClasses={['Notification', `${urgency(n)}`]}>
|
||||
<box cssClasses={["header"]}>
|
||||
{(n.appIcon || n.desktopEntry) ? <Gtk.Image
|
||||
cssName="app-icon"
|
||||
cssClasses={["app-icon"]}
|
||||
visible={Boolean(n.appIcon || n.desktopEntry)}
|
||||
iconName={n.appIcon || n.desktopEntry}
|
||||
/> : <Gtk.Image iconName={'window-close-symbolic'}></Gtk.Image>}
|
||||
/> : <image iconName={'window-close-symbolic'}></image>}
|
||||
<label
|
||||
cssName="app-name"
|
||||
cssClasses={["app-name"]}
|
||||
halign={START}
|
||||
// ellipsize={Pango.EllipsizeMode.END}
|
||||
label={n.appName || "Unknown"}
|
||||
/>
|
||||
<label
|
||||
cssName="time"
|
||||
cssClasses={["time"]}
|
||||
hexpand
|
||||
halign={END}
|
||||
label={time(n.time)}
|
||||
/>
|
||||
<button onClicked={() => del( id )}>
|
||||
<Gtk.Image iconName="window-close-symbolic" />
|
||||
<button onClicked={() => { del( id ) }}>
|
||||
<image iconName="window-close-symbolic" />
|
||||
</button>
|
||||
</box>
|
||||
<Gtk.Separator visible />
|
||||
<box cssName="content">
|
||||
<box cssClasses={["content"]}>
|
||||
{n.image && fileExists(n.image) ? <box
|
||||
valign={START}
|
||||
cssName="image">
|
||||
<Gtk.Image file={n.image}></Gtk.Image>
|
||||
cssClasses={["image"]}>
|
||||
<image file={n.image}></image>
|
||||
</box>
|
||||
: <box></box>}
|
||||
{n.image ? <box
|
||||
expand={false}
|
||||
valign={START}
|
||||
className="icon-image">
|
||||
<Gtk.Image iconName={n.image} expand halign={CENTER} valign={CENTER} />
|
||||
cssClasses={["icon-image"]}>
|
||||
<image iconName={n.image} expand halign={CENTER} valign={CENTER} />
|
||||
</box>
|
||||
: <box></box>}
|
||||
<box vertical>
|
||||
<Gtk.Label
|
||||
cssName="summary"
|
||||
<label
|
||||
cssClasses={["summary"]}
|
||||
halign={START}
|
||||
xalign={0}
|
||||
label={n.summary}
|
||||
// ellipsize={Pango.EllipsizeMode.END}
|
||||
/>
|
||||
{n.body ? <label
|
||||
cssName="body"
|
||||
cssClasses={["body"]}
|
||||
wrap
|
||||
useMarkup
|
||||
halign={START}
|
||||
@@ -90,7 +90,7 @@ export default function Notification(props: Props) {
|
||||
/> : <label></label>}
|
||||
</box>
|
||||
</box>
|
||||
{n.get_actions().length > 0 ? <box cssName="actions">
|
||||
{n.get_actions().length > 0 ? <box cssClasses={["actions"]}>
|
||||
{n.get_actions().map(({ label, id }) => (
|
||||
<button
|
||||
hexpand
|
||||
|
Reference in New Issue
Block a user