Files
dotfiles/.config/quickshell/nucleus-shell/modules/interface/notifications/Notifications.qml

155 lines
4.7 KiB
QML

import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.Notifications
import Quickshell.Wayland
import Quickshell.Widgets
import qs.services
import qs.config
import qs.modules.components
Scope {
id: root
property int innerSpacing: Metrics.spacing(10)
PanelWindow {
id: window
implicitWidth: 520
visible: true
color: "transparent"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.exclusionMode: ExclusionMode.Normal
WlrLayershell.namespace: "nucleus:notification"
anchors {
top: true
left: Config.runtime.notifications.position.endsWith("left")
bottom: true
right: Config.runtime.notifications.position.endsWith("right")
}
Item {
id: notificationList
anchors.leftMargin: 0
anchors.topMargin: Metrics.margin(10)
anchors.rightMargin: 0
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
Rectangle {
id: bgRectangle
layer.enabled: true
anchors.top: parent.top
anchors.left: parent.left
anchors.leftMargin: Metrics.margin(20)
anchors.rightMargin: Metrics.margin(20)
anchors.right: parent.right
height: window.mask.height > 0 ? window.mask.height + 40 : 0
color: Appearance.m3colors.m3background
radius: Metrics.radius("large")
layer.effect: MultiEffect {
shadowEnabled: true
shadowOpacity: 1
shadowColor: Appearance.m3colors.m3shadow
shadowBlur: 1
shadowScale: 1
}
Behavior on height {
enabled: Config.runtime.appearance.animations.enabled
NumberAnimation {
duration: Metrics.chronoDuration("small")
easing.type: Easing.InOutExpo
}
}
}
Item {
id: notificationColumn
anchors.left: parent.left
anchors.right: parent.right
Repeater {
id: rep
model: (!Config.runtime.notifications.doNotDisturb && Config.runtime.notifications.enabled) ? NotifServer.popups : []
NotificationChild {
id: child
width: notificationColumn.width - 80
anchors.horizontalCenter: notificationColumn.horizontalCenter
y: {
var pos = 0;
for (let i = 0; i < index; i++) {
var prev = rep.itemAt(i);
if (prev)
pos += prev.height + root.innerSpacing;
}
return pos + 20;
}
Component.onCompleted: {
if (!modelData.shown)
modelData.shown = true;
}
title: modelData.summary
body: modelData.body
image: modelData.image || modelData.appIcon
rawNotif: modelData
tracked: modelData.shown
buttons: modelData.actions.map((action) => {
return ({
"label": action.text,
"onClick": () => {
return action.invoke();
}
});
})
Behavior on y {
enabled: Config.runtime.appearance.animations.enabled
NumberAnimation {
duration: Metrics.chronoDuration("normal")
easing.type: Easing.InOutExpo
}
}
}
}
}
}
mask: Region {
width: window.width
height: {
var total = 0;
for (let i = 0; i < rep.count; i++) {
var child = rep.itemAt(i);
if (child)
total += child.height + (i < rep.count - 1 ? root.innerSpacing : 0);
}
return total;
}
}
}
}