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 _pendingDismissIds: []
function _cascadeDismiss() {
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++) {
const d = dels[i];
const isLast = (i === dels.length - 1);
_cascadeTimer.createObject(menuWindow, {
_target: dels[i],
_delay: i * 60
_target: d,
_delay: i * 60,
_isLast: isLast
});
}
}
function _finishCascade() {
const ids = _pendingDismissIds;
_pendingDismissIds = [];
for (const id of ids)
M.NotifService.dismiss(id);
}
property Component _cascadeTimer: Component {
Timer {
property var _target
property int _delay
property bool _isLast
interval: _delay
running: true
onTriggered: {
if (_target && _target.dismiss)
_target.dismiss();
if (_target && _target.dismissVisualOnly)
_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();
}
}
@ -114,11 +147,17 @@ M.PopupPanel {
readonly property real _targetHeight: notifContent.height + 12
property real _heightScale: 1
property bool _skipDismiss: false
function dismiss() {
_dismissAnim.start();
}
function dismissVisualOnly() {
_skipDismiss = true;
_dismissAnim.start();
}
Component.onCompleted: {
menuWindow._delegates.push(notifItem);
fadeIn.start();
@ -309,7 +348,10 @@ M.PopupPanel {
easing.type: Easing.OutCubic
}
ScriptAction {
script: M.NotifService.dismiss(notifItem.modelData.id)
script: {
if (!notifItem._skipDismiss)
M.NotifService.dismiss(notifItem.modelData.id);
}
}
}