nixos/quickshell/NotificationToast.qml
2026-04-15 10:38:34 -03:00

171 lines
6.5 KiB
QML

import Quickshell
import Quickshell.Wayland
import QtQuick
import QtQuick.Layouts
PanelWindow {
anchors.top: true
anchors.right: true
margins.top: Theme.padding
margins.right: Theme.padding
exclusiveZone: 0
visible: NotificationsState.toasts.count > 0 && !root.zenMode
width: 320
height: toastCol.implicitHeight
color: "transparent"
Column {
id: toastCol
width: parent.width
spacing: 4
Repeater {
model: NotificationsState.toasts
delegate: Rectangle {
required property var model
required property int index
width: toastCol.width
height: toastInner.implicitHeight + Theme.padding * 2 + 3
radius: Theme.radius
color: Theme.bg
border.color: model.urgency === 2 ? Theme.red : Theme.bg2
border.width: 1
RowLayout {
id: toastInner
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: Theme.padding
anchors.leftMargin: Theme.padding
anchors.rightMargin: Theme.padding
spacing: Theme.spacing
Rectangle {
width: 34
height: 34
radius: 17
color: model.urgency === 2 ? Theme.redN
: model.urgency === 0 ? Theme.bg3
: Theme.blueN
Layout.alignment: Qt.AlignTop
Image {
id: tIcon
anchors.fill: parent
anchors.margins: 5
source: model.appIcon
fillMode: Image.PreserveAspectFit
visible: status === Image.Ready
smooth: true
}
Text {
anchors.centerIn: parent
visible: !tIcon.visible
text: model.appName.charAt(0).toUpperCase()
color: Theme.fg
font.pixelSize: Theme.fontSize
font.family: Theme.font
font.bold: true
}
}
ColumnLayout {
Layout.fillWidth: true
spacing: 3
RowLayout {
Layout.fillWidth: true
Text {
text: model.summary.length > 0 ? model.summary : model.appName
color: Theme.text
font.pixelSize: Theme.fontSize
font.family: Theme.font
font.bold: true
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
visible: model.summary.length > 0
text: model.appName
color: Theme.subtle
font.pixelSize: Theme.fontSizeSmall
font.family: Theme.font
}
}
Text {
visible: model.body.length > 0
text: model.body
color: Theme.fg2
font.pixelSize: Theme.fontSizeSmall
font.family: Theme.font
wrapMode: Text.WordWrap
maximumLineCount: 3
elide: Text.ElideRight
Layout.fillWidth: true
}
}
Rectangle {
width: 22
height: 22
radius: 11
color: closeBtn.containsMouse ? Theme.bg3 : "transparent"
Layout.alignment: Qt.AlignTop
Behavior on color { ColorAnimation { duration: 100 } }
Text {
anchors.centerIn: parent
text: "✕"
color: closeBtn.containsMouse ? Theme.fg : Theme.subtle
font.pixelSize: 11
opacity: closeBtn.containsMouse ? 1.0 : 0.5
Behavior on color { ColorAnimation { duration: 100 } }
Behavior on opacity { NumberAnimation { duration: 100 } }
}
MouseArea {
id: closeBtn
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: NotificationsState.dismissToast(model.tid)
}
}
}
Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
height: 3
radius: 2
width: parent.width * model.progress
color: model.urgency === 2 ? Theme.red : Theme.accent
}
// Does not extend to the right edge to avoid overlapping the close button
MouseArea {
anchors.fill: parent
anchors.rightMargin: 34
cursorShape: Qt.PointingHandCursor
onClicked: {
NotificationsState.invokeDefault(model.tid)
NotificationsState.dismissToast(model.tid)
}
}
}
}
}
}