Files
z-bar-qt/Daemons/NotifServer.qml
T
zach 11e7aac195
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 11s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 12s
JS/TS / lint (pull_request) Successful in 10s
Python / static (pull_request) Failing after 27s
Rust / build (pull_request) Successful in 54s
Python / verify (pull_request) Failing after 1m26s
Rust / fmt (pull_request) Successful in 46s
Rust / clippy (pull_request) Successful in 1m6s
feat: better notification storage and image caching + blobs
2026-11-02 19:00:43 +01:00

108 lines
2.1 KiB
QML

pragma Singleton
pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Io
import Quickshell.Services.Notifications
import ZShell.Services
import qs.Components
import qs.Helpers
import qs.Paths
import qs.Services
import ZShell.Config
Singleton {
id: root
readonly property var appCooldownMap: new Map()
property alias dnd: props.dnd
readonly property alias groups: store.groups
property alias list: store.rows
readonly property alias popupGroups: store.popupGroups
readonly property list<NotificationRow> notClosed: store.rows.filter(n => !n.closed)
readonly property list<NotificationRow> popups: store.rows.filter(n => n.popup)
function shouldThrottle(appName: string): bool {
if (props.dnd || ShellState.anySidebarOpen())
return false;
const key = (appName || "unknown").trim().toLowerCase();
const cooldownSec = Config.notifs.appNotifCooldown;
const cooldownMs = Math.max(0, cooldownSec * 1000);
if (cooldownMs <= 0)
return true;
const now = Date.now();
const until = appCooldownMap.get(key) ?? 0;
if (now < until)
return false;
appCooldownMap.set(key, now + cooldownMs);
return true;
}
PersistentProperties {
id: props
property bool dnd
reloadableId: "notifs"
}
NotificationStore {
id: store
path: `${Paths.state}/notifs.sqlite`
}
NotificationServer {
id: server
actionsSupported: true
bodyHyperlinksSupported: true
bodyImagesSupported: true
bodyMarkupSupported: true
imageSupported: true
keepOnReload: true
persistenceSupported: true
onNotification: notif => {
notif.tracked = true;
store.insert(notif, root.shouldThrottle(notif.appName));
}
}
CustomShortcut {
description: "Clear all notifications"
name: "clearnotifs"
onPressed: store.clear()
}
IpcHandler {
function clear(): void {
store.clear();
}
function disableDnd(): void {
props.dnd = false;
}
function enableDnd(): void {
props.dnd = true;
}
function isDndEnabled(): bool {
return props.dnd;
}
function toggleDnd(): void {
props.dnd = !props.dnd;
}
target: "notifs"
}
}