summaryrefslogtreecommitdiff
path: root/modules/sidebar/NotifGroupList.qml
diff options
context:
space:
mode:
Diffstat (limited to 'modules/sidebar/NotifGroupList.qml')
-rw-r--r--modules/sidebar/NotifGroupList.qml136
1 files changed, 136 insertions, 0 deletions
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
+ }
+ }
+ }
+ }
+}