1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

notifications: add swipe to dismiss functionality

fixes #927
This commit is contained in:
bbedward
2025-12-12 14:39:51 -05:00
parent e95f7ce367
commit 0ff9fdb365
2 changed files with 335 additions and 159 deletions

View File

@@ -18,12 +18,12 @@ DankListView {
onIsUserScrollingChanged: {
if (isUserScrolling && keyboardController && keyboardController.keyboardNavigationActive) {
autoScrollDisabled = true
autoScrollDisabled = true;
}
}
function enableAutoScroll() {
autoScrollDisabled = false
autoScrollDisabled = false;
}
Timer {
@@ -33,7 +33,7 @@ DankListView {
repeat: true
onTriggered: {
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
keyboardController.ensureVisible()
keyboardController.ensureVisible();
}
}
}
@@ -46,48 +46,105 @@ DankListView {
onModelChanged: {
if (!keyboardController || !keyboardController.keyboardNavigationActive) {
return
return;
}
keyboardController.rebuildFlatNavigation()
keyboardController.rebuildFlatNavigation();
Qt.callLater(() => {
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
keyboardController.ensureVisible()
}
})
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
keyboardController.ensureVisible();
}
});
}
delegate: Item {
id: delegateRoot
required property var modelData
required property int index
readonly property bool isExpanded: (NotificationService.expandedGroups[modelData && modelData.key] || false)
property real swipeOffset: 0
property bool isDismissing: false
readonly property real dismissThreshold: width * 0.35
width: ListView.view.width
height: notificationCard.height
height: isDismissing ? 0 : notificationCard.height
clip: true
Behavior on height {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
NotificationCard {
id: notificationCard
width: parent.width
x: delegateRoot.swipeOffset
notificationGroup: modelData
keyboardNavigationActive: listView.keyboardActive
opacity: 1 - Math.abs(delegateRoot.swipeOffset) / (delegateRoot.width * 0.5)
isGroupSelected: {
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive) {
return false
}
keyboardController.selectionVersion
const selection = keyboardController.getCurrentSelection()
return selection.type === "group" && selection.groupIndex === index
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive)
return false;
keyboardController.selectionVersion;
const selection = keyboardController.getCurrentSelection();
return selection.type === "group" && selection.groupIndex === index;
}
selectedNotificationIndex: {
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive) {
return -1
}
keyboardController.selectionVersion
const selection = keyboardController.getCurrentSelection()
return (selection.type === "notification" && selection.groupIndex === index) ? selection.notificationIndex : -1
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive)
return -1;
keyboardController.selectionVersion;
const selection = keyboardController.getCurrentSelection();
return (selection.type === "notification" && selection.groupIndex === index) ? selection.notificationIndex : -1;
}
Behavior on x {
enabled: !swipeDragHandler.active
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
Behavior on opacity {
NumberAnimation {
duration: Theme.shortDuration
}
}
}
DragHandler {
id: swipeDragHandler
target: null
yAxis.enabled: false
xAxis.enabled: true
onActiveChanged: {
if (active || delegateRoot.isDismissing)
return;
if (Math.abs(delegateRoot.swipeOffset) > delegateRoot.dismissThreshold) {
delegateRoot.isDismissing = true;
delegateRoot.swipeOffset = delegateRoot.swipeOffset > 0 ? delegateRoot.width : -delegateRoot.width;
dismissTimer.start();
} else {
delegateRoot.swipeOffset = 0;
}
}
onTranslationChanged: {
if (delegateRoot.isDismissing)
return;
delegateRoot.swipeOffset = translation.x;
}
}
Timer {
id: dismissTimer
interval: Theme.shortDuration
onTriggered: NotificationService.dismissGroup(delegateRoot.modelData?.key || "")
}
}
@@ -96,42 +153,42 @@ DankListView {
function onGroupedNotificationsChanged() {
if (!keyboardController) {
return
return;
}
if (keyboardController.isTogglingGroup) {
keyboardController.rebuildFlatNavigation()
return
keyboardController.rebuildFlatNavigation();
return;
}
keyboardController.rebuildFlatNavigation()
keyboardController.rebuildFlatNavigation();
if (keyboardController.keyboardNavigationActive) {
Qt.callLater(() => {
if (!autoScrollDisabled) {
keyboardController.ensureVisible()
}
})
if (!autoScrollDisabled) {
keyboardController.ensureVisible();
}
});
}
}
function onExpandedGroupsChanged() {
if (keyboardController && keyboardController.keyboardNavigationActive) {
Qt.callLater(() => {
if (!autoScrollDisabled) {
keyboardController.ensureVisible()
}
})
if (!autoScrollDisabled) {
keyboardController.ensureVisible();
}
});
}
}
function onExpandedMessagesChanged() {
if (keyboardController && keyboardController.keyboardNavigationActive) {
Qt.callLater(() => {
if (!autoScrollDisabled) {
keyboardController.ensureVisible()
}
})
if (!autoScrollDisabled) {
keyboardController.ensureVisible();
}
});
}
}
}