Files
dotfiles/fedora/quickshell/control-center/Notifications.qml
2026-07-26 16:51:25 +03:00

236 lines
8.0 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.Notifications
import Quickshell.Wayland
Item {
id: root
UiTokens { id: theme }
property bool open: false
property bool dnd: false
property bool toastOpen: false
property var latest: null
property var settings
readonly property int count: server.trackedNotifications ? server.trackedNotifications.values.length : 0
signal dismissed()
NotificationServer {
id: server
keepOnReload: true
onNotification: function(notification) {
notification.tracked = true;
root.latest = notification;
if (!root.dnd) {
root.toastOpen = true;
toastTimer.restart();
}
}
}
Timer {
id: toastTimer
interval: root.settings ? root.settings.notificationPopupDuration : 5000
repeat: false
onTriggered: root.toastOpen = false
}
PanelWindow {
visible: root.toastOpen && !root.open && root.latest !== null
color: "transparent"
anchors { top: true; bottom: true; left: true; right: true }
exclusionMode: ExclusionMode.Ignore
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
WlrLayershell.namespace: "quickshell-notification-toast"
Rectangle {
width: Math.min(390, parent.width - 32)
height: 112
anchors.top: parent.top
x: root.settings && root.settings.notificationPosition === "top-left" ? 16 : parent.width - width - 16
radius: 16
color: "#181825"
border.color: "#313244"
border.width: 1
MouseArea {
anchors.fill: parent
onClicked: {
root.toastOpen = false;
root.open = true;
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 14
spacing: 3
RowLayout {
Layout.fillWidth: true
spacing: 8
Label {
text: root.latest ? root.latest.appName : ""
color: "#9399b2"
font.pixelSize: 11
Layout.fillWidth: true
elide: Text.ElideRight
}
CCButton {
theme: theme
text: "Close"
onClicked: root.toastOpen = false
}
}
Label {
text: root.latest ? root.latest.summary : ""
color: "#cdd6f4"
font.pixelSize: 16
font.bold: true
Layout.fillWidth: true
elide: Text.ElideRight
}
Label {
text: root.latest ? root.latest.body : ""
color: "#9399b2"
Layout.fillWidth: true
elide: Text.ElideRight
}
}
}
}
PanelWindow {
visible: root.open
color: "transparent"
anchors { top: true; bottom: true; left: true; right: true }
exclusionMode: ExclusionMode.Ignore
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: root.open ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
WlrLayershell.namespace: "quickshell-notification-center"
MouseArea {
anchors.fill: parent
onClicked: root.dismissed()
}
Rectangle {
width: Math.min(430, parent.width - 32)
height: Math.min(parent.height - 32, 700)
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: 16
radius: 20
color: "#11111b"
border.color: "#313244"
border.width: 1
z: 1
MouseArea {
anchors.fill: parent
onClicked: function(mouse) { mouse.accepted = true }
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 18
spacing: 10
RowLayout {
Layout.fillWidth: true
Label {
text: "Notifications"
color: "#cdd6f4"
font.pixelSize: 22
font.bold: true
Layout.fillWidth: true
}
CCButton {
theme: theme
text: root.dnd ? "DND on" : "DND off"
onClicked: root.dnd = !root.dnd
}
CCButton {
theme: theme
text: "Close"
onClicked: root.dismissed()
}
}
Label {
visible: root.count === 0
text: "No notifications"
color: "#9399b2"
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 18
}
ScrollView {
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
ColumnLayout {
width: parent.width
spacing: 8
Repeater {
model: server.trackedNotifications
delegate: Rectangle {
required property var modelData
Layout.fillWidth: true
implicitHeight: notificationColumn.implicitHeight + 22
radius: 14
color: "#181825"
ColumnLayout {
id: notificationColumn
anchors.fill: parent
anchors.margins: 11
spacing: 3
RowLayout {
Layout.fillWidth: true
Label {
text: modelData.appName
color: "#9399b2"
font.pixelSize: 11
Layout.fillWidth: true
elide: Text.ElideRight
}
CCButton {
theme: theme
text: "x"
onClicked: modelData.dismiss()
}
}
Label {
text: modelData.summary
color: "#cdd6f4"
font.pixelSize: 15
font.bold: true
Layout.fillWidth: true
wrapMode: Text.Wrap
}
Label {
text: modelData.body
color: "#9399b2"
Layout.fillWidth: true
wrapMode: Text.Wrap
}
}
}
}
}
}
}
}
}
}