quickshell-toki-night/services/Notifs.qml

123 lines
3.5 KiB
QML

pragma Singleton
pragma ComponentBehavior: Bound
import qs.config
import qs.custom
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import Quickshell.Services.Notifications
import QtQuick
Singleton {
id: root
readonly property list<Notif> list: []
property bool dnd: false
function toggleDnd(): void {
dnd = !dnd
}
NotificationServer {
id: server
keepOnReload: false
actionsSupported: true
bodyHyperlinksSupported: true
bodyImagesSupported: true
bodyMarkupSupported: true
imageSupported: true
persistenceSupported: true
onNotification: notif => {
notif.tracked = true;
root.list.push(notifComp.createObject(root, {
popup: root.dnd ? null : Hypr.focusedMonitor,
notification: notif
}));
}
}
CustomShortcut {
name: "clearNotifs"
description: "Clear all notifications"
onPressed: {
for (const notif of root.list)
notif.popup = null;
}
}
CustomShortcut {
name: "dismissNotifs"
description: "Dismiss all notifications"
onPressed: {
for (const notif of root.list)
notif.notification.dismiss();
}
}
component Notif: QtObject {
id: notif
// Monitor to display popup in (typically the focused monitor when received)
property HyprlandMonitor popup: null
readonly property date time: new Date()
readonly property string timeStr: Qt.formatTime(time, "hh:mm:ss")
readonly property string timeSince: {
const diff = Time.date.getTime() - time.getTime();
const m = Math.floor(diff / 60000);
const h = Math.floor(m / 60);
const d = Math.floor(h / 24);
if (m < 1)
return "now";
if (h < 1)
return `${m}m`;
if (d < 1)
return `${h}h`;
return `${d}d`;
}
required property Notification notification
readonly property string summary: notification.summary
readonly property string appIcon: notification.appIcon
readonly property string appName: notification.appName
readonly property string image: notification.image
readonly property int urgency: notification.urgency
readonly property list<NotificationAction> actions: notification.actions
// Split body text into lines parseable by StyledText format
readonly property string body: notification.body.replace("\n", "<br/>")
// One-line version (for non-expanded notifications)
readonly property string bodyOneLine: notification.body.replace("\n", " ")
readonly property Timer timer: Timer {
running: true
interval: notif.notification.expireTimeout > 0 ? notif.notification.expireTimeout : Config.notifs.defaultExpireTimeout
onTriggered: {
if (Config.notifs.expire)
notif.popup = null;
}
}
readonly property Connections conn: Connections {
target: notif.notification.Retainable
function onDropped(): void {
root.list.splice(root.list.indexOf(notif), 1);
}
function onAboutToDestroy(): void {
notif.destroy();
}
}
}
Component {
id: notifComp
Notif {}
}
}