fix cascade dismiss: animate all visually first, bulk-dismiss after last

This commit is contained in:
Damocles 2026-04-13 15:54:08 +02:00
parent 0c89b570ac
commit 03c545c9d1

View file

@ -66,25 +66,58 @@ M.PopupPanel {
property var _delegates: [] property var _delegates: []
property var _pendingDismissIds: []
function _cascadeDismiss() { function _cascadeDismiss() {
const dels = _delegates.filter(d => d && d.modelData && !d.modelData.closed); const dels = _delegates.filter(d => d && d.modelData && !d.modelData.closed);
if (dels.length === 0)
return;
_pendingDismissIds = dels.map(d => d.modelData.id);
for (let i = 0; i < dels.length; i++) { for (let i = 0; i < dels.length; i++) {
const d = dels[i];
const isLast = (i === dels.length - 1);
_cascadeTimer.createObject(menuWindow, { _cascadeTimer.createObject(menuWindow, {
_target: dels[i], _target: d,
_delay: i * 60 _delay: i * 60,
_isLast: isLast
}); });
} }
} }
function _finishCascade() {
const ids = _pendingDismissIds;
_pendingDismissIds = [];
for (const id of ids)
M.NotifService.dismiss(id);
}
property Component _cascadeTimer: Component { property Component _cascadeTimer: Component {
Timer { Timer {
property var _target property var _target
property int _delay property int _delay
property bool _isLast
interval: _delay interval: _delay
running: true running: true
onTriggered: { onTriggered: {
if (_target && _target.dismiss) if (_target && _target.dismissVisualOnly)
_target.dismiss(); _target.dismissVisualOnly();
if (_isLast) {
// Wait for the last animation to finish, then bulk dismiss
_bulkTimer.createObject(menuWindow, {});
}
destroy();
}
}
}
property Component _bulkTimer: Component {
Timer {
interval: 400 // swipe (200) + collapse (150) + margin
running: true
onTriggered: {
menuWindow._finishCascade();
destroy(); destroy();
} }
} }
@ -114,11 +147,17 @@ M.PopupPanel {
readonly property real _targetHeight: notifContent.height + 12 readonly property real _targetHeight: notifContent.height + 12
property real _heightScale: 1 property real _heightScale: 1
property bool _skipDismiss: false
function dismiss() { function dismiss() {
_dismissAnim.start(); _dismissAnim.start();
} }
function dismissVisualOnly() {
_skipDismiss = true;
_dismissAnim.start();
}
Component.onCompleted: { Component.onCompleted: {
menuWindow._delegates.push(notifItem); menuWindow._delegates.push(notifItem);
fadeIn.start(); fadeIn.start();
@ -309,7 +348,10 @@ M.PopupPanel {
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
ScriptAction { ScriptAction {
script: M.NotifService.dismiss(notifItem.modelData.id) script: {
if (!notifItem._skipDismiss)
M.NotifService.dismiss(notifItem.modelData.id);
}
} }
} }