import Applications from 'resource:///com/github/Aylur/ags/service/applications.js'; import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js'; import Variable from 'resource:///com/github/Aylur/ags/variable.js'; import { Box, Icon, Label, Button } from 'resource:///com/github/Aylur/ags/widget.js'; import { lookUpIcon, execAsync, timeout } from 'resource:///com/github/Aylur/ags/utils.js'; import GLib from 'gi://GLib'; const setTime = time => { return GLib.DateTime .new_from_unix_local(time) .format('%H:%M'); }; const getDragState = box => box.get_parent().get_parent() .get_parent().get_parent().get_parent()._dragging; import Gesture from './gesture.js'; import EventBox from '../misc/cursorbox.js'; const NotificationIcon = notif => { let iconCmd = () => {}; if (Applications.query(notif.appEntry).length > 0) { const app = Applications.query(notif.appEntry)[0]; let wmClass = app.app.get_string('StartupWMClass'); if (app.app.get_filename().includes('discord')) wmClass = 'discord'; if (wmClass != null) { iconCmd = box => { if (!getDragState(box)) { execAsync(['bash', '-c', `$AGS_PATH/launch-app.sh ${wmClass} ${app.app.get_string('Exec')}`, ]).catch(print); globalThis.closeAll(); } }; } } if (notif.image) { return EventBox({ onPrimaryClickRelease: iconCmd, child: Box({ valign: 'start', hexpand: false, className: 'icon img', style: `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'; if (lookUpIcon(notif.appIcon)) icon = notif.appIcon; if (lookUpIcon(notif.appEntry)) icon = notif.appEntry; return EventBox({ onPrimaryClickRelease: iconCmd, child: Box({ valign: 'start', hexpand: false, className: 'icon', style: `min-width: 78px; min-height: 78px;`, children: [Icon({ icon, size: 58, halign: 'center', hexpand: true, valign: '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', command = () => {}, } = {}) => { if (!notif) return; HasNotifs.value = Notifications.notifications.length > 0; const BlockedApps = [ 'Spotify', ]; if (BlockedApps.find(app => app == notif.appName)) { notif.close(); return; } // Init notif const notifWidget = Gesture({ maxOffset: 200, command: () => command(), slideIn, properties: [ ['hovered', false], ['id', notif.id], ], onHover: w => { if (!w._hovered) w._hovered = true; }, onHoverLost: w => { if (w._hovered) w._hovered = false; }, }); // Notif methods notifWidget.slideAway = side => { notifWidget.child.setStyle(notifWidget.child[`_slide${side}`]); notifWidget.sensitive = false; timeout(400, () => { notifWidget.child.setStyle(notifWidget.child[`_squeeze${side}`]); timeout(500, () => { HasNotifs.value = Notifications.notifications.length > 0; notifWidget.get_parent().remove(notifWidget); notifWidget.destroy(); }); }); }; // Add body to notif notifWidget.child.add(Box({ className: `notification ${notif.urgency}`, vexpand: false, // Notification child: Box({ vertical: true, children: [ // Content Box({ children: [ NotificationIcon(notif), Box({ hexpand: true, vertical: true, children: [ // Top of Content Box({ children: [ Label({ className: 'title', xalign: 0, justification: 'left', hexpand: true, maxWidthChars: 24, truncate: 'end', wrap: true, label: notif.summary, useMarkup: notif.summary.startsWith('<'), }), Label({ className: 'time', valign: 'start', label: setTime(notif.time), }), EventBox({ reset: false, child: Button({ className: 'close-button', valign: 'start', onClicked: () => notif.close(), child: Icon('window-close-symbolic'), }), }), ], }), Label({ className: 'description', hexpand: true, useMarkup: true, xalign: 0, justification: 'left', label: notif.body, wrap: true, }), ], }), ], }), // Actions Box({ className: 'actions', children: notif.actions.map(action => Button({ className: 'action-button', onClicked: () => notif.invoke(action.id), hexpand: true, child: Label(action.label), })), }), ], }), })); return notifWidget; };