diff options
| author | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-09-18 23:39:23 +1000 |
|---|---|---|
| committer | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-09-18 23:39:23 +1000 |
| commit | ef5936d0ab58b79d55d79da0c77627f09676691d (patch) | |
| tree | 04a21d49d00d912b23a1665dc5ac1fc4492c6aee /modules | |
| parent | sidebar: add notifs (diff) | |
| download | caelestia-shell-ef5936d0ab58b79d55d79da0c77627f09676691d.tar.gz caelestia-shell-ef5936d0ab58b79d55d79da0c77627f09676691d.tar.bz2 caelestia-shell-ef5936d0ab58b79d55d79da0c77627f09676691d.zip | |
notifs: persistent notifs + better sidebar notifs
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/lock/NotifGroup.qml | 32 | ||||
| -rw-r--r-- | modules/notifications/Content.qml | 2 | ||||
| -rw-r--r-- | modules/notifications/Notification.qml | 19 | ||||
| -rw-r--r-- | modules/sidebar/Notif.qml | 38 | ||||
| -rw-r--r-- | modules/sidebar/NotifDock.qml | 5 | ||||
| -rw-r--r-- | modules/sidebar/NotifGroup.qml | 37 | ||||
| -rw-r--r-- | modules/sidebar/NotifGroupList.qml | 136 |
7 files changed, 189 insertions, 80 deletions
diff --git a/modules/lock/NotifGroup.qml b/modules/lock/NotifGroup.qml index 3669e5e..15342d4 100644 --- a/modules/lock/NotifGroup.qml +++ b/modules/lock/NotifGroup.qml @@ -31,11 +31,6 @@ StyledRect { radius: Appearance.rounding.normal color: root.urgency === "critical" ? Colours.palette.m3secondaryContainer : Colours.layer(Colours.palette.m3surfaceContainerHigh, 2) - RetainableLock { - object: root.notifs[0]?.notification ?? null - locked: true - } - RowLayout { id: content @@ -229,6 +224,27 @@ StyledRect { to: notif.implicitHeight } } + + ParallelAnimation { + running: notif.modelData.closed + onFinished: notif.modelData.lock(notif) + + Anim { + target: notif + property: "opacity" + to: 0 + } + Anim { + target: notif + property: "scale" + to: 0.7 + } + Anim { + target: notif.Layout + property: "preferredHeight" + to: 0 + } + } } } @@ -287,10 +303,8 @@ StyledRect { } color: root.urgency === "critical" ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - RetainableLock { - object: notifLine.modelData.notification - locked: true - } + Component.onCompleted: modelData.lock(this) + Component.onDestruction: modelData.unlock(this) TextMetrics { id: metrics diff --git a/modules/notifications/Content.qml b/modules/notifications/Content.qml index 828c3a8..019e922 100644 --- a/modules/notifications/Content.qml +++ b/modules/notifications/Content.qml @@ -55,7 +55,7 @@ Item { id: list model: ScriptModel { - values: [...Notifs.popups].reverse() + values: Notifs.popups.filter(n => !n.closed).reverse() } anchors.fill: parent diff --git a/modules/notifications/Notification.qml b/modules/notifications/Notification.qml index 2d56ef6..95507fc 100644 --- a/modules/notifications/Notification.qml +++ b/modules/notifications/Notification.qml @@ -26,7 +26,11 @@ StyledRect { implicitHeight: inner.implicitHeight x: Config.notifs.sizes.width - Component.onCompleted: x = 0 + Component.onCompleted: { + x = 0; + modelData.lock(this); + } + Component.onDestruction: modelData.unlock(this) Behavior on x { Anim { @@ -34,11 +38,6 @@ StyledRect { } } - RetainableLock { - object: root.modelData.notification - locked: true - } - MouseArea { property int startY @@ -61,7 +60,7 @@ StyledRect { root.modelData.timer.stop(); startY = event.y; if (event.button === Qt.MiddleButton) - root.modelData.notification.dismiss(); + root.modelData.close(); } onReleased: event => { if (!containsMouse) @@ -70,7 +69,7 @@ StyledRect { if (Math.abs(root.x) < Config.notifs.sizes.width * Config.notifs.clearThreshold) root.x = 0; else - root.modelData.notification.dismiss(); // TODO: change back to popup when notif dock impled + root.modelData.popup = false; } onPositionChanged: event => { if (pressed) { @@ -393,7 +392,7 @@ StyledRect { return; Quickshell.execDetached(["app2unit", "-O", "--", link]); - root.modelData.notification.dismiss(); // TODO: change back to popup when notif dock impled + root.modelData.popup = false; } opacity: root.expanded ? 1 : 0 @@ -422,7 +421,7 @@ StyledRect { modelData: QtObject { readonly property string text: qsTr("Close") function invoke(): void { - root.modelData.notification.dismiss(); + root.modelData.close(); } } } diff --git a/modules/sidebar/Notif.qml b/modules/sidebar/Notif.qml index 8b96792..3aecc59 100644 --- a/modules/sidebar/Notif.qml +++ b/modules/sidebar/Notif.qml @@ -1,10 +1,8 @@ pragma ComponentBehavior: Bound import qs.components -import qs.components.controls import qs.services import qs.config -import Quickshell import QtQuick import QtQuick.Layouts @@ -15,8 +13,9 @@ StyledRect { required property Props props required property bool expanded - Layout.fillWidth: true - implicitHeight: expanded ? summary.implicitHeight + expandedContent.implicitHeight + expandedContent.anchors.topMargin + Appearance.padding.normal * 2 : summary.implicitHeight + readonly property real nonAnimHeight: expanded ? summary.implicitHeight + expandedContent.implicitHeight + expandedContent.anchors.topMargin + Appearance.padding.normal * 2 : summary.implicitHeight + + implicitHeight: nonAnimHeight radius: Appearance.rounding.small color: { @@ -44,34 +43,6 @@ StyledRect { } } - ParallelAnimation { - running: true - - Anim { - target: root - property: "opacity" - from: 0 - to: 1 - } - Anim { - target: root - property: "scale" - from: 0.7 - to: 1 - } - // Anim { - // target: root.Layout - // property: "preferredHeight" - // from: 0 - // to: root.implicitHeight - // } - } - - RetainableLock { - object: root.modelData.notification - locked: true - } - StyledText { id: summary @@ -139,7 +110,8 @@ StyledRect { StyledText { Layout.fillWidth: true - text: root.modelData.body || qsTr("No body here! :/") + textFormat: Text.MarkdownText + text: root.modelData.body.replace(/(.)\n(?!\n)/g, "$1\n\n") || qsTr("No body here! :/") color: root.modelData.urgency === "critical" ? Colours.palette.m3secondary : Colours.palette.m3outline wrapMode: Text.WordWrap } diff --git a/modules/sidebar/NotifDock.qml b/modules/sidebar/NotifDock.qml index 36b6665..490eeb8 100644 --- a/modules/sidebar/NotifDock.qml +++ b/modules/sidebar/NotifDock.qml @@ -160,8 +160,9 @@ Item { repeat: true interval: 50 onTriggered: { - Notifs.list[0]?.notification.dismiss(); - if (Notifs.list.length === 0) + if (Notifs.list.length > 0) + Notifs.list[0].close(); + else stop(); } } diff --git a/modules/sidebar/NotifGroup.qml b/modules/sidebar/NotifGroup.qml index 154b530..4476bf9 100644 --- a/modules/sidebar/NotifGroup.qml +++ b/modules/sidebar/NotifGroup.qml @@ -1,7 +1,6 @@ pragma ComponentBehavior: Bound import qs.components -import qs.components.controls import qs.components.effects import qs.services import qs.config @@ -119,13 +118,15 @@ StyledRect { } ColumnLayout { + id: column + Layout.topMargin: -Appearance.padding.small Layout.bottomMargin: -Appearance.padding.small / 2 Layout.fillWidth: true - spacing: Math.round(Appearance.spacing.small / 2) + spacing: 0 RowLayout { - Layout.bottomMargin: -parent.spacing + Layout.bottomMargin: root.expanded ? Math.round(Appearance.spacing.small / 2) : 0 Layout.fillWidth: true spacing: Appearance.spacing.smaller @@ -173,7 +174,7 @@ StyledRect { Layout.leftMargin: Appearance.padding.small / 2 animate: true - text: root.notifs.length + text: root.notifs.reduce((acc, n) => n.closed ? acc : acc + 1, 0) color: root.urgency === "critical" ? Colours.palette.m3onError : Colours.palette.m3onSurface font.pointSize: Appearance.font.size.small } @@ -186,31 +187,17 @@ StyledRect { } } } - } - - Repeater { - id: notifList - model: ScriptModel { - values: root.expanded ? root.notifs : root.notifs.slice(0, Config.notifs.groupPreviewNum) + Behavior on Layout.bottomMargin { + Anim {} } + } - Layout.fillWidth: true - - Notif { - id: notif - - props: root.props - expanded: root.expanded - } + NotifGroupList { + props: root.props + notifs: root.notifs + expanded: root.expanded } } } - - // Behavior on implicitHeight { - // Anim { - // duration: Appearance.anim.durations.expressiveDefaultSpatial - // easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - // } - // } } diff --git a/modules/sidebar/NotifGroupList.qml b/modules/sidebar/NotifGroupList.qml new file mode 100644 index 0000000..7def80f --- /dev/null +++ b/modules/sidebar/NotifGroupList.qml @@ -0,0 +1,136 @@ +pragma ComponentBehavior: Bound + +import qs.components +import qs.services +import qs.config +import Quickshell +import QtQuick +import QtQuick.Layouts + +Item { + id: root + + required property Props props + required property list<var> notifs + required property bool expanded + + readonly property int spacing: Math.round(Appearance.spacing.small / 2) + property bool flag + + Layout.fillWidth: true + implicitHeight: { + const item = repeater.itemAt(repeater.count - 1); + return item ? item.y + item.implicitHeight : 0; + } + + Repeater { + id: repeater + + model: ScriptModel { + values: root.expanded ? root.notifs : root.notifs.slice(0, Config.notifs.groupPreviewNum) + onValuesChanged: root.flagChanged() + } + + MouseArea { + id: notif + + required property int index + required property Notifs.Notif modelData + + readonly property alias nonAnimHeight: notifInner.nonAnimHeight + property int startY + + y: { + root.flag; // Force update + let y = 0; + for (let i = 0; i < index; i++) { + const item = repeater.itemAt(i); + if (!item.modelData.closed) + y += item.nonAnimHeight + root.spacing; + } + return y; + } + + implicitWidth: root.width + implicitHeight: notifInner.implicitHeight + + hoverEnabled: true + cursorShape: pressed ? Qt.ClosedHandCursor : undefined + acceptedButtons: Qt.LeftButton | Qt.MiddleButton + + drag.target: this + drag.axis: Drag.XAxis + + onPressed: event => { + startY = event.y; + if (event.button === Qt.MiddleButton) + modelData.close(); + } + onReleased: event => { + if (Math.abs(x) < width * Config.notifs.clearThreshold) + x = 0; + else + modelData.close(); + } + + Component.onCompleted: modelData.lock(this) + Component.onDestruction: modelData.unlock(this) + + ParallelAnimation { + running: true + + Anim { + target: notif + property: "opacity" + from: 0 + to: 1 + } + Anim { + target: notif + property: "scale" + from: 0.7 + to: 1 + } + } + + ParallelAnimation { + running: notif.modelData.closed + onFinished: notif.modelData.unlock(notif) + + Anim { + target: notif + property: "opacity" + to: 0 + } + Anim { + target: notif + property: "x" + to: notif.x >= 0 ? notif.width : -notif.width + } + } + + Notif { + id: notifInner + + anchors.fill: parent + modelData: notif.modelData + props: root.props + expanded: root.expanded + } + + Behavior on x { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } + + Behavior on y { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } + } + } +} |