integrated notification center: replace swaync with built-in NotificationServer
This commit is contained in:
parent
4276434cd2
commit
c973bd8163
7 changed files with 643 additions and 43 deletions
142
modules/NotifService.qml
Normal file
142
modules/NotifService.qml
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.Notifications
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property var list: []
|
||||
property bool dnd: false
|
||||
|
||||
readonly property var active: list.filter(n => !n.closed)
|
||||
readonly property var popups: list.filter(n => n.popup && !n.closed)
|
||||
readonly property int count: active.length
|
||||
|
||||
function dismiss(notifId) {
|
||||
const n = list.find(n => n.id === notifId);
|
||||
if (n) {
|
||||
n.popup = false;
|
||||
n.closed = true;
|
||||
n.notification?.dismiss();
|
||||
_changed();
|
||||
}
|
||||
}
|
||||
|
||||
function dismissAll() {
|
||||
for (const n of list.slice()) {
|
||||
n.popup = false;
|
||||
n.closed = true;
|
||||
n.notification?.dismiss();
|
||||
}
|
||||
_changed();
|
||||
}
|
||||
|
||||
function dismissPopup(notifId) {
|
||||
const n = list.find(n => n.id === notifId);
|
||||
if (n) {
|
||||
n.popup = false;
|
||||
_changed();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleDnd() {
|
||||
dnd = !dnd;
|
||||
}
|
||||
|
||||
function _changed() {
|
||||
list = list.slice();
|
||||
_saveTimer.restart();
|
||||
}
|
||||
|
||||
property NotificationServer _server: NotificationServer {
|
||||
actionsSupported: true
|
||||
bodyMarkupSupported: true
|
||||
imageSupported: true
|
||||
persistenceSupported: true
|
||||
keepOnReload: false
|
||||
|
||||
onNotification: notif => {
|
||||
notif.tracked = true;
|
||||
|
||||
const data = {
|
||||
id: notif.id,
|
||||
summary: notif.summary,
|
||||
body: notif.body,
|
||||
appName: notif.appName,
|
||||
appIcon: notif.appIcon,
|
||||
image: notif.image,
|
||||
urgency: notif.urgency,
|
||||
actions: notif.actions ? notif.actions.map(a => ({
|
||||
identifier: a.identifier,
|
||||
text: a.text,
|
||||
invoke: () => a.invoke()
|
||||
})) : [],
|
||||
time: Date.now(),
|
||||
popup: !root.dnd,
|
||||
closed: false,
|
||||
notification: notif
|
||||
};
|
||||
|
||||
root.list = [data, ...root.list];
|
||||
|
||||
// Auto-expire popup
|
||||
if (data.popup) {
|
||||
const timeout = notif.expireTimeout > 0 ? notif.expireTimeout : 5000;
|
||||
Qt.callLater(() => {
|
||||
_expireTimer.createObject(root, {
|
||||
_notifId: data.id,
|
||||
interval: timeout
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Component _expireTimer: Component {
|
||||
Timer {
|
||||
property string _notifId
|
||||
running: true
|
||||
onTriggered: {
|
||||
root.dismissPopup(_notifId);
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Persistence
|
||||
property Timer _saveTimer: Timer {
|
||||
interval: 1000
|
||||
onTriggered: {
|
||||
const data = root.active.map(n => ({
|
||||
id: n.id,
|
||||
summary: n.summary,
|
||||
body: n.body,
|
||||
appName: n.appName,
|
||||
appIcon: n.appIcon,
|
||||
image: n.image,
|
||||
urgency: n.urgency,
|
||||
time: n.time
|
||||
}));
|
||||
_storage.setText(JSON.stringify(data));
|
||||
}
|
||||
}
|
||||
|
||||
property FileView _storage: FileView {
|
||||
path: (Quickshell.env("XDG_STATE_HOME") || (Quickshell.env("HOME") + "/.local/state")) + "/nova-shell/notifs.json"
|
||||
onLoaded: {
|
||||
try {
|
||||
const data = JSON.parse(text());
|
||||
for (const n of data) {
|
||||
n.popup = false;
|
||||
n.closed = false;
|
||||
n.notification = null;
|
||||
n.actions = [];
|
||||
}
|
||||
root.list = data.concat(root.list);
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue