summaryrefslogtreecommitdiff
path: root/modules/sidebar/NotifDockList.qml
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-09-20 15:47:44 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-09-20 15:47:44 +1000
commit89d46c1b2fd1a35a3229511f745205ac4956bf9e (patch)
treeaa5c7faed9c627b6933cdc533b540eb695af9dd9 /modules/sidebar/NotifDockList.qml
parentsidebar/notifs: sort groups by latest notif (diff)
downloadcaelestia-shell-89d46c1b2fd1a35a3229511f745205ac4956bf9e.tar.gz
caelestia-shell-89d46c1b2fd1a35a3229511f745205ac4956bf9e.tar.bz2
caelestia-shell-89d46c1b2fd1a35a3229511f745205ac4956bf9e.zip
sidebar/notifs: better anims + misc fixes
Diffstat (limited to 'modules/sidebar/NotifDockList.qml')
-rw-r--r--modules/sidebar/NotifDockList.qml150
1 files changed, 150 insertions, 0 deletions
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
+ }
+ }
+ }
+ }
+}