From a41284ccf7ad0995e54907d1e617837be2fe2788 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Tue, 28 Jul 2026 18:22:31 +0700 Subject: [PATCH] feat: add Ctrl+A select all items and Del key delete selected items/groups - Ctrl+A already existed for selecting all timeline items across tracks - Added Del/Backspace key handler for selectedItemIds: deletes all selected sections, MIDI items, and audio clips from the selected track(s) - Clears selection after deletion and shows toast with count --- app/static/js/app.jsx | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index 00b677b..bef5991 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -8157,8 +8157,42 @@ const App = () => { handlePasteTrack(); return; } - if (e.key === 'Delete' || e.key === 'Backspace' || e.key === 'Del') { - const selClip = selectedClipIdRef.current; + if (e.key === 'Delete' || e.key === 'Backspace' || e.key === 'Del') { + if (selectedItemIds && selectedItemIds.size > 0) { + e.preventDefault(); + const idsToDelete = new Set(selectedItemIds); + setSelectedItemIds(new Set()); + updateActiveTracks(prev => prev.map(t => { + let changed = false; + const sections = (t.sections || []).filter(s => { + if (idsToDelete.has(s.id)) { changed = true; return false; } + return true; + }); + const midiItems = (t.midiItems || []).filter(m => { + if (idsToDelete.has(m.id)) { changed = true; return false; } + return true; + }); + const clips = (t.clips || []).filter(c => { + const canonical = c.id === 'default' ? 'default_' + t.id : c.id; + if (idsToDelete.has(canonical)) { changed = true; return false; } + return true; + }); + if (!changed) return t; + return { + ...t, + sections, + midiItems, + clips, + buffer: clips[0]?.buffer || null, + startTime: clips[0]?.startTime || 0, + name: clips[0]?.name || t.name + }; + })); + const count = idsToDelete.size; + showToast(count === 1 ? 'Đã xóa 1 item.' : `Đã xóa ${count} items.`, 'info'); + return; + } + const selClip = selectedClipIdRef.current; if (selClip) { e.preventDefault(); const {