waffles: notif center: drag to dismiss

This commit is contained in:
end-4
2025-12-13 23:07:26 +01:00
parent f0926b6ce3
commit 93bc4d935c
6 changed files with 132 additions and 20 deletions
@@ -100,7 +100,7 @@ ListView {
to: 1,
}),
] : []
}
}
move: Transition {
animations: root.animateMovement ? [
@@ -7,6 +7,20 @@ ListView {
id: root
boundsBehavior: Flickable.DragOverBounds
ScrollBar.vertical: WScrollBar {}
displaced: Transition {
animations: [Looks.transition.enter.createObject(this, {
property: "y"
})]
}
remove: Transition {
ParallelAnimation {
NumberAnimation { property: "opacity"; to: 0; duration: 1000 }
NumberAnimation { properties: "x,y"; to: 100; duration: 1000 }
}
}
}
@@ -53,10 +53,9 @@ BodyRectangle {
}
}
StyledListView {
WListView {
Layout.fillWidth: true
Layout.fillHeight: true
animateAppearance: false
clip: true
model: Notifications.appNameList
@@ -0,0 +1,32 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
import qs.modules.waffle.looks
SequentialAnimation {
id: root
required property var target
PropertyAction {
target: root.target
property: "ListView.delayRemove"
value: true
}
NumberAnimation {
target: root.target
property: "x"
to: root.target.width
duration: 250
easing.type: Easing.BezierSpline
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
}
PropertyAction {
target: root.target
property: "ListView.delayRemove"
value: false
}
}
@@ -1,3 +1,4 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import Quickshell
@@ -18,10 +19,44 @@ MouseArea {
implicitWidth: contentLayout.implicitWidth
implicitHeight: contentLayout.implicitHeight
function dismissAll() {
root.notifications.forEach(notif => {
Qt.callLater(() => {
Notifications.discardNotification(notif.notificationId);
});
});
removeAnimation.start();
}
WNotificationDismissAnim {
id: removeAnimation
target: root
}
property real dragDismissThreshold: 100
drag {
axis: Drag.XAxis
target: contentLayout
minimumX: 0
onActiveChanged: {
if (drag.active)
return;
if (contentLayout.x > root.dragDismissThreshold) {
root.dismissAll();
} else {
contentLayout.x = 0;
}
}
}
ColumnLayout {
id: contentLayout
anchors.fill: parent
spacing: 4
width: root.width
Behavior on x {
animation: Looks.transition.enter.createObject(this)
}
GroupHeader {
id: notifHeader
@@ -29,7 +64,9 @@ MouseArea {
Layout.margins: 11
}
ListView {
WListView {
Layout.leftMargin: -Math.min(35, contentLayout.x)
Layout.rightMargin: -Layout.leftMargin
Layout.fillWidth: true
implicitWidth: notifHeader.implicitWidth
implicitHeight: contentHeight
@@ -40,14 +77,20 @@ MouseArea {
objectProp: "notificationId"
}
delegate: WSingleNotification {
id: singleNotif
required property int index
required property var modelData
width: ListView.view.width
notification: modelData
groupExpandControlMessage: {
if (root.notifications.length <= 1) return "";
if (!root.expanded) return Translation.tr("+%1 notifications").arg(root.notifications.length - 1);
if (index === root.notifications.length - 1) return Translation.tr("See fewer");
if (root.notifications.length <= 1)
return "";
if (!root.expanded)
return Translation.tr("+%1 notifications").arg(root.notifications.length - 1);
if (index === root.notifications.length - 1)
return Translation.tr("See fewer");
return "";
}
onGroupExpandToggle: {
@@ -94,11 +137,7 @@ MouseArea {
Layout.rightMargin: 3
icon.name: "dismiss"
onClicked: {
root.notifications.forEach(notif => {
Qt.callLater(() => {
Notifications.discardNotification(notif.notificationId);
});
});
root.dismissAll();
}
}
}
@@ -18,6 +18,18 @@ MouseArea {
signal groupExpandToggle
hoverEnabled: true
function dismiss() {
Qt.callLater(() => {
Notifications.discardNotification(root.notification?.notificationId);
});
removeAnimation.start();
}
WNotificationDismissAnim {
id: removeAnimation
target: root
}
implicitHeight: contentItem.implicitHeight
implicitWidth: contentItem.implicitWidth
@@ -25,9 +37,25 @@ MouseArea {
animation: Looks.transition.enter.createObject(this)
}
property real dragDismissThreshold: 100
drag {
axis: Drag.XAxis
target: contentItem
minimumX: 0
onActiveChanged: {
if (drag.active)
return;
if (contentItem.x > root.dragDismissThreshold) {
root.dismiss();
} else {
contentItem.x = 0;
}
}
}
Rectangle {
id: contentItem
anchors.fill: parent
width: parent.width
color: Looks.colors.bgPanelBody
radius: Looks.radius.medium
property real padding: 12
@@ -36,6 +64,10 @@ MouseArea {
border.width: 1
border.color: ColorUtils.applyAlpha(Looks.colors.ambientShadow, 0.1)
Behavior on x {
animation: Looks.transition.enter.createObject(this)
}
ColumnLayout {
id: notificationContent
anchors.fill: parent
@@ -128,11 +160,7 @@ MouseArea {
opacity: root.containsMouse ? 1 : 0
icon.name: "dismiss"
implicitSize: 12
onClicked: {
Qt.callLater(() => {
Notifications.discardNotification(root.notification?.notificationId);
});
}
onClicked: root.dismiss()
}
}