873801262e
Kill pure-black crust (->Void #070709) and add the figure/ground tokens focusActive/focusField/emberField. Move active/selection states to violet (calendar Today, keybinds active tab, battery + power profiles); stop spending danger-red on non-danger states (mic + audio-default -> cyan); make the notif bell state-driven (neutral/focus/danger); give critical notifications an ember ground; bluetooth scanning -> cyan; k8s MEM -> blue (free the special violet).
164 lines
5.0 KiB
QML
164 lines
5.0 KiB
QML
import Quickshell
|
|
import Quickshell.Services.Notifications
|
|
import Quickshell.Widgets
|
|
import QtQuick
|
|
import QtQuick.Layouts
|
|
import "../shared" as Shared
|
|
|
|
// Single notification card
|
|
Rectangle {
|
|
id: root
|
|
|
|
required property var notification
|
|
|
|
implicitWidth: 360
|
|
implicitHeight: content.implicitHeight + 20
|
|
radius: Shared.Theme.radiusNormal
|
|
color: notification.urgency === NotificationUrgency.Critical ? Shared.Theme.emberField : Shared.Theme.popoutBackground
|
|
border.width: 1
|
|
border.color: notification.urgency === NotificationUrgency.Critical ? Qt.alpha(Shared.Theme.danger, Shared.Theme.opacityMedium) : Shared.Theme.borderSubtle
|
|
|
|
// Entrance animation
|
|
opacity: 0
|
|
scale: 0.95
|
|
Component.onCompleted: { opacity = 1; scale = 1; }
|
|
|
|
Behavior on opacity { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }
|
|
Behavior on scale { NumberAnimation { duration: 180; easing.type: Easing.OutCubic } }
|
|
|
|
// Dismiss on click
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: root.notification.dismiss()
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: content
|
|
anchors.fill: parent
|
|
anchors.margins: 10
|
|
spacing: 6
|
|
|
|
// Header: icon + app name + close
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 8
|
|
|
|
IconImage {
|
|
source: root.notification.appIcon
|
|
implicitSize: 18
|
|
visible: root.notification.appIcon !== ""
|
|
}
|
|
|
|
Text {
|
|
text: root.notification.appName || "Notification"
|
|
color: Shared.Theme.overlay0
|
|
font.pixelSize: Shared.Theme.fontSmall
|
|
font.family: Shared.Theme.fontFamily
|
|
Layout.fillWidth: true
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
Text {
|
|
text: "\u{f0156}"
|
|
color: closeMouse.containsMouse ? Shared.Theme.danger : Shared.Theme.overlay0
|
|
font.pixelSize: 14
|
|
font.family: Shared.Theme.iconFont
|
|
MouseArea {
|
|
id: closeMouse
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
onClicked: root.notification.dismiss()
|
|
}
|
|
}
|
|
}
|
|
|
|
// Summary (title)
|
|
Text {
|
|
visible: text !== ""
|
|
text: root.notification.summary
|
|
color: Shared.Theme.text
|
|
font.pixelSize: Shared.Theme.fontSize
|
|
font.family: Shared.Theme.fontFamily
|
|
font.bold: true
|
|
Layout.fillWidth: true
|
|
wrapMode: Text.WordWrap
|
|
maximumLineCount: 2
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
// Body
|
|
Text {
|
|
visible: text !== ""
|
|
text: root.notification.body
|
|
textFormat: Text.PlainText
|
|
color: Shared.Theme.subtext0
|
|
font.pixelSize: Shared.Theme.fontSmall
|
|
font.family: Shared.Theme.fontFamily
|
|
Layout.fillWidth: true
|
|
wrapMode: Text.WordWrap
|
|
maximumLineCount: 4
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
// Image
|
|
Image {
|
|
visible: root.notification.image !== ""
|
|
source: root.notification.image
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 120
|
|
fillMode: Image.PreserveAspectCrop
|
|
Layout.topMargin: 2
|
|
}
|
|
|
|
// Actions
|
|
RowLayout {
|
|
visible: root.notification.actions.length > 0
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: 2
|
|
spacing: 6
|
|
|
|
Repeater {
|
|
model: root.notification.actions
|
|
|
|
Rectangle {
|
|
required property var modelData
|
|
Layout.fillWidth: true
|
|
implicitHeight: 28
|
|
radius: 6
|
|
color: actMouse.containsMouse ? Shared.Theme.surface1 : Shared.Theme.surface0
|
|
|
|
Behavior on color { ColorAnimation { duration: 100 } }
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: modelData.text
|
|
color: Shared.Theme.text
|
|
font.pixelSize: Shared.Theme.fontSmall
|
|
font.family: Shared.Theme.fontFamily
|
|
}
|
|
|
|
MouseArea {
|
|
id: actMouse
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
onClicked: modelData.invoke()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Urgency accent bar on left edge
|
|
Rectangle {
|
|
visible: root.notification.urgency === NotificationUrgency.Critical
|
|
anchors.left: parent.left
|
|
anchors.top: parent.top
|
|
anchors.bottom: parent.bottom
|
|
anchors.leftMargin: 1
|
|
anchors.topMargin: root.radius
|
|
anchors.bottomMargin: root.radius
|
|
width: 3
|
|
color: Shared.Theme.danger
|
|
}
|
|
}
|