// Copyright (C) 2026 Danilo M. // // 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) } } }