Krolyxon
Commit 4b1d495

Branches

Refs →

aurora.configquickshellauroraNotifCard.qml

149 lines · 4.8 KB · QML

1import QtQuick
2import QtQuick.Layouts
3import QtQuick.Effects
4import Quickshell
5import Quickshell.Services.Notifications
6
7// A notification (panel history, toasts): the app icon in a circle (dots / mono / colour, Settings.appIcons),
8// APP · 3 MIN, summary, body, other actions as pills. Click = the default action, if the app sent one.
9// Critical = accent border. Ported from glyph-rice (github.com/Nebelung-cloud/glyph-rice, GPL-3.0), quick/Quick.qml.
10Rectangle {
11 id: card
12 required property var n // Notification
13 property bool popup: false
14 readonly property bool critical: n.urgency === NotificationUrgency.Critical
15
16 Layout.fillWidth: true
17 implicitHeight: Math.max(74, body.implicitHeight + 32)
18 radius: 26
19 color: popup ? Theme.s1 : Theme.s2
20 border.width: critical || popup ? 1 : 0
21 border.color: critical ? Theme.err : Theme.mute
22
23 readonly property bool photo: !!n.image && n.image !== "" // avatars, covers: fill the circle
24 readonly property string imgSource: {
25 if (photo) return n.image
26 if (n.appIcon && n.appIcon !== "") return Quickshell.iconPath(n.appIcon, true)
27 return ""
28 }
29 readonly property var defaultAction: {
30 var a = n.actions
31 for (var i = 0; i < a.length; i++) if (a[i].identifier === "default") return a[i]
32 return null
33 }
34 readonly property var buttons: {
35 var a = n.actions, out = []
36 for (var i = 0; i < a.length; i++) if (a[i].identifier !== "default" && a[i].text !== "") out.push(a[i])
37 return out
38 }
39
40 function close() {
41 if (popup) Notifs.dropPopup(n)
42 else n.dismiss()
43 }
44 // invoke() can close the notification and destroy this card: read everything first
45 function run(action) {
46 var nn = n, p = popup
47 if (action) action.invoke()
48 if (p) Notifs.dropPopup(nn)
49 }
50
51 MouseArea {
52 anchors.fill: parent
53 cursorShape: card.defaultAction ? Qt.PointingHandCursor : Qt.ArrowCursor
54 onClicked: card.run(card.defaultAction)
55 }
56
57 Rectangle {
58 id: ic
59 x: 16
60 y: 16
61 width: 42
62 height: 42
63 radius: 21
64 color: Theme.s3
65 Icon { anchors.centerIn: parent; visible: !img.visible; text: Theme.iBell; font.pixelSize: 18 }
66 Image {
67 id: img
68 anchors.centerIn: parent
69 width: card.photo && Settings.appIcons === "dots" ? 42 : 26
70 height: width
71 visible: status === Image.Ready
72 source: card.imgSource
73 sourceSize: Qt.size(width * 2, height * 2)
74 fillMode: Image.PreserveAspectCrop
75 asynchronous: true
76 layer.enabled: Settings.appIcons !== "colour"
77 layer.effect: Settings.appIcons === "mono" ? monoFx : dotFx
78 }
79 Component { id: dotFx; DotMask { step: card.photo ? 3 : 2; circle: card.photo } }
80 Component { id: monoFx; MultiEffect { saturation: -1 } }
81 }
82
83 ColumnLayout {
84 id: body
85 anchors.left: ic.right
86 anchors.leftMargin: 14
87 anchors.right: closeBtn.left
88 anchors.rightMargin: 8
89 y: 16
90 spacing: 2
91 Lb {
92 Layout.fillWidth: true
93 elide: Text.ElideRight
94 px: 10
95 text: (card.n.appName || "app") + (Notifs.ago(card.n) !== "" ? " · " + Notifs.ago(card.n) : "")
96 }
97 Text {
98 Layout.fillWidth: true
99 text: card.n.summary
100 wrapMode: Text.Wrap
101 maximumLineCount: 2
102 elide: Text.ElideRight
103 font.family: Theme.ui
104 font.pixelSize: 15
105 font.weight: Font.DemiBold
106 color: Theme.fg
107 }
108 Text {
109 visible: card.n.body !== ""
110 Layout.fillWidth: true
111 text: card.n.body
112 textFormat: Text.StyledText
113 wrapMode: Text.Wrap
114 maximumLineCount: card.popup ? 4 : 6
115 elide: Text.ElideRight
116 font.family: Theme.ui
117 font.pixelSize: 14
118 color: Theme.fgDim
119 linkColor: Theme.fill
120 }
121 Flow {
122 visible: card.buttons.length > 0
123 Layout.fillWidth: true
124 Layout.topMargin: 8
125 spacing: 6
126 Repeater {
127 model: card.buttons
128 delegate: Chip {
129 required property var modelData
130 text: modelData.text
131 filled: true
132 px: 10
133 onClicked: card.run(modelData)
134 }
135 }
136 }
137 }
138
139 IconBtn {
140 id: closeBtn
141 anchors.right: parent.right
142 anchors.rightMargin: 12
143 y: 14
144 implicitHeight: 28
145 icon: Theme.iClose
146 iconSize: 13
147 onClicked: card.close()
148 }
149}