nixos-configs/modules/ags/config/ts/notifications/base.ts

285 lines
8.6 KiB
TypeScript
Raw Normal View History

const Applications = await Service.import('applications');
const Hyprland = await Service.import('hyprland');
const Notifications = await Service.import('notifications');
const { Box, Icon, Label, Button } = Widget;
const { lookUpIcon } = Utils;
2023-12-20 03:45:05 -05:00
const { GLib } = imports.gi;
import Gesture from './gesture.ts';
import CursorBox from '../misc/cursorbox.ts';
2024-01-13 11:15:08 -05:00
// Types
import { Notification as NotifObj } from 'types/service/notifications.ts';
import { Client } from 'types/service/hyprland.ts';
2024-01-13 11:15:08 -05:00
type NotificationWidget = {
notif: NotifObj
slideIn?: 'Left' | 'Right'
command?(): void
};
import {
CursorBox as CBox,
2024-01-29 20:56:56 -05:00
EventBoxGeneric,
NotifGesture,
} from 'global-types';
2023-12-20 17:14:07 -05:00
2024-01-13 11:15:08 -05:00
const setTime = (time: number) => {
return GLib.DateTime
.new_from_unix_local(time)
.format('%H:%M');
};
const getDragState = (box: EventBoxGeneric) => (box
.get_parent()
?.get_parent()
?.get_parent()
?.get_parent()
2024-01-29 20:56:56 -05:00
?.get_parent() as NotifGesture)
2024-01-13 11:15:08 -05:00
?.attribute.dragging;
2024-01-13 11:15:08 -05:00
const NotificationIcon = (notif: NotifObj) => {
let iconCmd = (box: CBox):void => {
if (!box) {
console.log();
}
2024-01-13 11:15:08 -05:00
};
2024-01-14 20:52:30 -05:00
if (notif.app_entry && Applications.query(notif.app_entry).length > 0) {
const app = Applications.query(notif.app_entry)[0];
let wmClass = app.app.get_string('StartupWMClass');
2023-12-20 17:14:07 -05:00
if (app.app?.get_filename()?.includes('discord')) {
wmClass = 'discord';
}
if (wmClass != null) {
iconCmd = (box) => {
if (!getDragState(box)) {
if (wmClass === 'thunderbird') {
Hyprland.sendMessage('dispatch ' +
'togglespecialworkspace thunder');
}
else if (wmClass === 'Spotify') {
Hyprland.sendMessage('dispatch ' +
'togglespecialworkspace spot');
}
else {
2023-12-20 17:14:07 -05:00
Hyprland.sendMessage('j/clients').then((msg) => {
2024-01-13 11:15:08 -05:00
const clients = JSON.parse(msg) as Array<Client>;
const classes = [] as Array<string>;
2023-12-20 17:14:07 -05:00
for (const key of clients) {
if (key.class) {
classes.push(key.class);
}
}
2023-12-20 17:14:07 -05:00
if (wmClass && classes.includes(wmClass)) {
Hyprland.sendMessage('dispatch ' +
`focuswindow ^(${wmClass})`);
}
else {
2023-12-21 01:25:59 -05:00
Hyprland.sendMessage('dispatch workspace empty')
.then(() => {
app.launch();
});
}
});
}
globalThis.closeAll();
}
};
}
}
if (notif.image) {
return CursorBox({
on_primary_click_release: (self) => {
iconCmd(self);
},
child: Box({
vpack: 'start',
hexpand: false,
2023-12-20 17:14:07 -05:00
class_name: 'icon img',
css: `
background-image: url("${notif.image}");
background-size: contain;
background-repeat: no-repeat;
background-position: center;
min-width: 78px;
min-height: 78px;
`,
}),
});
}
let icon = 'dialog-information-symbolic';
2024-01-14 20:52:30 -05:00
if (lookUpIcon(notif.app_icon)) {
icon = notif.app_icon;
}
2024-01-14 20:52:30 -05:00
if (notif.app_entry && lookUpIcon(notif.app_entry)) {
icon = notif.app_entry;
}
return CursorBox({
on_primary_click_release: (self) => {
iconCmd(self);
},
child: Box({
vpack: 'start',
hexpand: false,
2023-12-20 17:14:07 -05:00
class_name: 'icon',
css: `
min-width: 78px;
min-height: 78px;
`,
children: [Icon({
2024-01-22 10:23:32 -05:00
icon,
size: 58,
hpack: 'center',
hexpand: true,
vpack: 'center',
vexpand: true,
})],
}),
});
};
// Make a variable to connect to for Widgets
// to know when there are notifs or not
export const HasNotifs = Variable(false);
export const Notification = ({
notif,
slideIn = 'Left',
2024-01-13 11:15:08 -05:00
command = () => {/**/},
}: NotificationWidget) => {
if (!notif) {
return;
}
const BlockedApps = [
'Spotify',
];
2024-01-14 20:52:30 -05:00
if (BlockedApps.find((app) => app === notif.app_name)) {
notif.close();
return;
}
HasNotifs.value = Notifications.notifications.length > 0;
// Init notif
const notifWidget = Gesture({
command,
slideIn,
id: notif.id,
});
// Add body to notif
(notifWidget.child as EventBoxGeneric).add(Box({
2023-12-20 17:14:07 -05:00
class_name: `notification ${notif.urgency}`,
vexpand: false,
// Notification
child: Box({
vertical: true,
children: [
// Content
Box({
children: [
NotificationIcon(notif),
2023-12-20 17:14:07 -05:00
Box({
hexpand: true,
vertical: true,
children: [
// Top of Content
Box({
children: [
// Title
Label({
2023-12-20 17:14:07 -05:00
class_name: 'title',
xalign: 0,
justification: 'left',
hexpand: true,
2023-12-20 17:14:07 -05:00
max_width_chars: 24,
truncate: 'end',
wrap: true,
label: notif.summary,
2023-12-20 17:14:07 -05:00
use_markup: notif.summary
.startsWith('<'),
}),
// Time
Label({
2023-12-20 17:14:07 -05:00
class_name: 'time',
vpack: 'start',
label: setTime(notif.time),
}),
// Close button
CursorBox({
child: Button({
2023-12-20 17:14:07 -05:00
class_name: 'close-button',
vpack: 'start',
2023-12-20 17:14:07 -05:00
on_primary_click_release: () =>
notif.close(),
child: Icon('window-close' +
'-symbolic'),
}),
}),
],
}),
// Description
Label({
2023-12-20 17:14:07 -05:00
class_name: 'description',
hexpand: true,
2023-12-20 17:14:07 -05:00
use_markup: true,
xalign: 0,
justification: 'left',
label: notif.body,
wrap: true,
}),
],
}),
],
}),
// Actions
Box({
2023-12-20 17:14:07 -05:00
class_name: 'actions',
children: notif.actions.map((action) => Button({
2023-12-20 17:14:07 -05:00
class_name: 'action-button',
hexpand: true,
2023-12-20 17:14:07 -05:00
on_primary_click_release: () => notif.invoke(action.id),
child: Label(action.label),
})),
}),
],
}),
}));
return notifWidget;
};