pragma ComponentBehavior: Bound // NoSignal Notifications popout (off the bell). Header (count + DND + Clear), // scrollable cards (tinted icon, title, body, time), empty state. Uses Notifs. import QtQuick import QtQuick.Layouts import qs.services import qs.utils import qs.components NsPanel { id: root implicitWidth: 380 anchorMode: "right" RowLayout { Layout.fillWidth: true StyledText { text: "Notifications" color: Theme.text font.family: Theme.font.family font.pixelSize: Theme.font.panelTitle font.weight: Font.DemiBold } StyledText { text: "ยท " + Notifs.notClosed.length + " new" color: Theme.textFaint font.family: Theme.font.family font.pixelSize: Theme.font.bodySmall } Item { Layout.fillWidth: true } Rectangle { implicitWidth: 26 implicitHeight: 26 radius: 13 color: Notifs.dnd ? Theme.accentSoft : dndMa.containsMouse ? Theme.hover : "transparent" MaterialIcon { anchors.centerIn: parent text: Notifs.dnd ? "do_not_disturb_on" : "dark_mode" color: Notifs.dnd ? Theme.accent : Theme.textMuted } MouseArea { id: dndMa anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: Notifs.dnd = !Notifs.dnd } } StyledText { text: "Clear" color: clearMa.containsMouse ? Theme.accent : Theme.textMuted font.family: Theme.font.family font.pixelSize: Theme.font.bodySmall MouseArea { id: clearMa anchors.fill: parent anchors.margins: -6 hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { for (const n of Notifs.notClosed) n.notification?.dismiss(); } } } } // cards ColumnLayout { Layout.fillWidth: true spacing: 6 Repeater { model: Notifs.notClosed delegate: Rectangle { id: card required property var modelData Layout.fillWidth: true implicitHeight: cardRow.implicitHeight + 20 radius: Theme.radius.button color: Theme.fillSubtle RowLayout { id: cardRow anchors.left: parent.left anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: 12 anchors.rightMargin: 12 spacing: 10 Rectangle { Layout.alignment: Qt.AlignTop implicitWidth: 30 implicitHeight: 30 radius: 0 color: Theme.accentSoft MaterialIcon { anchors.centerIn: parent text: Icons.getNotifIcon(card.modelData?.summary ?? "", card.modelData?.urgency ?? 1) color: Theme.accent } } ColumnLayout { Layout.fillWidth: true spacing: 2 RowLayout { Layout.fillWidth: true StyledText { Layout.fillWidth: true text: card.modelData?.summary ?? "" color: Theme.text elide: Text.ElideRight font.family: Theme.font.family font.pixelSize: Theme.font.bodySmall font.weight: Font.Medium } StyledText { text: card.modelData?.timeStr ?? "" color: Theme.textFaint font.family: Theme.font.family font.pixelSize: Theme.font.meta } } StyledText { Layout.fillWidth: true visible: text !== "" text: card.modelData?.body ?? "" color: Theme.textMuted wrapMode: Text.Wrap maximumLineCount: 3 elide: Text.ElideRight font.family: Theme.font.family font.pixelSize: Theme.font.meta } } } } } StyledText { visible: Notifs.notClosed.length === 0 Layout.topMargin: 6 text: "No notifications" color: Theme.textMuted font.family: Theme.font.family font.pixelSize: Theme.font.bodySmall } } }