diff options
Diffstat (limited to 'desktop/NotificationRow.qml')
| -rw-r--r-- | desktop/NotificationRow.qml | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/desktop/NotificationRow.qml b/desktop/NotificationRow.qml new file mode 100644 index 0000000..923cc9e --- /dev/null +++ b/desktop/NotificationRow.qml @@ -0,0 +1,126 @@ +// Copyright (C) 2026 Danilo M. <danix@danix.xyz> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +import QtQuick + +// One notification in the drawer: app, summary and body. Live rows close with +// the X and click through to their actions; a history row is inert. +Rectangle { + id: row + + radius: 8 + color: Qt.alpha(Theme.surface, 0.6) + border.width: 1 + border.color: Qt.alpha(Theme.text, 0.08) + + required property var notification + // A history row has no live client: no X, and a click does nothing. + property bool live: true + + readonly property bool inert: row.notification.expires !== 0 && Date.now() >= row.notification.expires + + implicitHeight: texts.implicitHeight + 24 + + // "Sep 15 14:32" from the notification's created epoch-ms, local time. No + // year: the history ring is only 20 entries, so everything here is recent. + function stamp(ms) { + const d = new Date(ms); + const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + function pad(n) { return (n < 10 ? "0" : "") + n; } + return months[d.getMonth()] + " " + d.getDate() + " " + + pad(d.getHours()) + ":" + pad(d.getMinutes()); + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + cursorShape: Qt.PointingHandCursor + onClicked: mouse => { + if (mouse.button === Qt.RightButton) { + Notify.closeAll(); + return; + } + if (!row.live) return; + const acts = row.notification.actions || []; + if (acts.length > 0 && !row.inert) Notify.actions(row.notification.id, acts); + else Notify.close(row.notification.id); + } + } + + Column { + id: texts + anchors { + left: parent.left + leftMargin: 12 + right: closeBtn.visible ? closeBtn.left : parent.right + rightMargin: 10 + verticalCenter: parent.verticalCenter + } + spacing: 2 + + Row { + id: head + width: parent.width + spacing: 8 + + Text { + width: head.width - (stamp.visible ? stamp.implicitWidth + head.spacing : 0) + text: (row.notification.app || "") + (row.notification.summary ? " " + row.notification.summary : "") + elide: Text.ElideRight + font { family: Theme.fontFamily; pixelSize: Theme.fontSize + 2 } + color: Theme.text + } + + Text { + id: stamp + visible: row.notification.created > 0 + text: visible ? row.stamp(row.notification.created) : "" + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } + color: Theme.overlay + } + } + + Text { + width: parent.width + visible: text !== "" + text: Notify.sanitize(row.notification.body) + textFormat: Text.RichText + wrapMode: Text.WordWrap + maximumLineCount: 2 + elide: Text.ElideRight + font { family: Theme.fontFamily; pixelSize: Theme.fontSize } + color: Theme.subtext + } + } + + Text { + id: closeBtn + visible: row.live + anchors { right: parent.right; rightMargin: 8; verticalCenter: parent.verticalCenter } + width: 20 + height: 20 + text: "\uf00d" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font { family: Theme.iconFamily; pixelSize: 13 } + color: closeArea.containsMouse ? Theme.red : Theme.subtext + + MouseArea { + id: closeArea + anchors.fill: parent + anchors.margins: -6 + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: Notify.close(row.notification.id) + } + } +} |
