fix: use ref-wrapped handler for delete selected items
Move delete logic into handleDeleteSelectedItemsRef to ensure setSelectedItemIds, updateActiveTracks, showToast are always up-to-date despite empty useEffect deps in keyboard handler. Keyboard handler reads selectedItemIdsRef.current (live ref), calls handleDeleteSelectedItemsRef.current(idsToDelete).
This commit is contained in:
+33
-29
@@ -7717,6 +7717,38 @@ const App = () => {
|
|||||||
const handleRedoRef = useRef(handleRedo);
|
const handleRedoRef = useRef(handleRedo);
|
||||||
handleUndoRef.current = handleUndo;
|
handleUndoRef.current = handleUndo;
|
||||||
handleRedoRef.current = handleRedo;
|
handleRedoRef.current = handleRedo;
|
||||||
|
const handleDeleteSelectedItemsRef = useRef(() => {});
|
||||||
|
handleDeleteSelectedItemsRef.current = (idsToDelete) => {
|
||||||
|
const count = idsToDelete.size;
|
||||||
|
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
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
showToast(count === 1 ? 'Đã xóa 1 item.' : `Đã xóa ${count} items.`, 'info');
|
||||||
|
};
|
||||||
const selectedClipIdRef = useRef(null);
|
const selectedClipIdRef = useRef(null);
|
||||||
selectedClipIdRef.current = selectedClipId;
|
selectedClipIdRef.current = selectedClipId;
|
||||||
const activeTabRef = useRef(activeTab);
|
const activeTabRef = useRef(activeTab);
|
||||||
@@ -8164,35 +8196,7 @@ const App = () => {
|
|||||||
if (selItems.size > 0) {
|
if (selItems.size > 0) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const idsToDelete = new Set(selItems);
|
const idsToDelete = new Set(selItems);
|
||||||
setSelectedItemIds(new Set());
|
handleDeleteSelectedItemsRef.current(idsToDelete);
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
const selClip = selectedClipIdRef.current;
|
const selClip = selectedClipIdRef.current;
|
||||||
|
|||||||
Reference in New Issue
Block a user