feat(delete): shorten undo window to 20s and make undo toast dismissible

This commit is contained in:
Will Miao
2026-08-12 19:15:03 +08:00
parent 680f0a57f5
commit 1ca99294c9
15 changed files with 150 additions and 90 deletions
+18
View File
@@ -107,6 +107,24 @@
white-space: nowrap;
}
.toast-close-btn {
flex-shrink: 0;
padding: 0 4px;
background: transparent;
color: var(--text-color);
border: none;
border-radius: 4px;
font-size: 1.1em;
line-height: 1;
opacity: 0.5;
cursor: pointer;
transition: opacity 0.2s ease;
}
.toast-close-btn:hover {
opacity: 1;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.toast {
+16 -2
View File
@@ -236,11 +236,11 @@ export function showToast(key, params = {}, type = 'info', fallback = null) {
* @param {Object} [options]
* @param {string} [options.actionText] - Label for the action button (button omitted when empty)
* @param {Function} [options.onAction] - Callback invoked at most once on button click
* @param {number} [options.durationMs=30000] - How long the toast stays visible
* @param {number} [options.durationMs=20000] - How long the toast stays visible
* @param {boolean} [options.countdown=true] - Show a ticking `(N)s` countdown
*/
export function showActionToast(key, params = {}, type = 'info', options = {}) {
const { actionText, onAction, durationMs = 30000, countdown = true } = options;
const { actionText, onAction, durationMs = 20000, countdown = true } = options;
const isPlainMessage = typeof key === 'string' && /\s/.test(key);
const message = isPlainMessage ? key : translate(key, params);
@@ -295,6 +295,20 @@ export function showActionToast(key, params = {}, type = 'info', options = {}) {
}
}, 1000);
}
// Manual close button: hides the toast early without firing onAction. The
// backend undo window keeps running and the batch is purged when it expires.
const closeBtn = document.createElement('button');
closeBtn.type = 'button';
closeBtn.className = 'toast-close-btn';
closeBtn.textContent = '×';
closeBtn.setAttribute('aria-label', translate('common.actions.close'));
closeBtn.addEventListener('click', (event) => {
event.preventDefault();
clearCountdown();
dismiss();
});
toast.append(closeBtn);
}
export function restoreFolderFilter() {