From 89d46c1b2fd1a35a3229511f745205ac4956bf9e Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Sat, 20 Sep 2025 15:47:44 +1000 Subject: sidebar/notifs: better anims + misc fixes --- modules/sidebar/NotifDockList.qml | 150 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 modules/sidebar/NotifDockList.qml (limited to 'modules/sidebar/NotifDockList.qml') diff --git a/modules/sidebar/NotifDockList.qml b/modules/sidebar/NotifDockList.qml new file mode 100644 index 0000000..0fd3464 --- /dev/null +++ b/modules/sidebar/NotifDockList.qml @@ -0,0 +1,150 @@ +pragma ComponentBehavior: Bound + +import qs.components +import qs.services +import qs.config +import Quickshell +import QtQuick + +Item { + id: root + + required property Props props + + readonly property alias repeater: repeater + readonly property int spacing: Appearance.spacing.small + property bool flag + + anchors.left: parent.left + anchors.right: parent.right + implicitHeight: { + const item = repeater.itemAt(repeater.count - 1); + return item ? item.y + item.implicitHeight : 0; + } + + Repeater { + id: repeater + + model: ScriptModel { + values: { + const list = Notifs.list.map(n => [n.appName, null]); + return [...new Map(list).keys()]; + } + onValuesChanged: root.flagChanged() + } + + MouseArea { + id: notif + + required property int index + required property string modelData + + readonly property bool closed: notifInner.notifCount === 0 + readonly property alias nonAnimHeight: notifInner.nonAnimHeight + property int startY + + function closeAll(): void { + for (const n of Notifs.notClosed.filter(n => n.appName === modelData)) + n.close(); + } + + y: { + root.flag; // Force update + let y = 0; + for (let i = 0; i < index; i++) { + const item = repeater.itemAt(i); + if (!item.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.RightButton | Qt.MiddleButton + preventStealing: true + + drag.target: this + drag.axis: Drag.XAxis + + onPressed: event => { + startY = event.y; + if (event.button === Qt.RightButton) + notifInner.toggleExpand(!notifInner.expanded); + else if (event.button === Qt.MiddleButton) + closeAll(); + } + onPositionChanged: event => { + if (pressed) { + const diffY = event.y - startY; + if (Math.abs(diffY) > Config.notifs.expandThreshold) + notifInner.toggleExpand(diffY > 0); + } + } + onReleased: event => { + if (Math.abs(x) < width * Config.notifs.clearThreshold) + x = 0; + else + closeAll(); + } + + ParallelAnimation { + running: true + + Anim { + target: notif + property: "opacity" + from: 0 + to: 1 + } + Anim { + target: notif + property: "scale" + from: 0 + to: 1 + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } + + ParallelAnimation { + running: notif.closed + + Anim { + target: notif + property: "opacity" + to: 0 + } + Anim { + target: notif + property: "scale" + to: 0.6 + } + } + + NotifGroup { + id: notifInner + + modelData: notif.modelData + props: root.props + } + + 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 + } + } + } + } +} -- cgit v1.2.3-freya