fix: sửa lỗi xóa track khi nhấn phím Del, đúng là phải xóa items được chọn
This commit is contained in:
+45
-12
@@ -531,7 +531,7 @@ const WaveformLane = ({
|
||||
|
||||
// 1. Draw Clip Layer Background & Border
|
||||
const clipIdentifier = clip.id === 'default' ? 'default_' + track.id : clip.id;
|
||||
const isClipSelected = selectedClipId && selectedClipId.trackId === track.id && selectedClipId.clipId === clipIdentifier;
|
||||
const isClipSelected = (selectedClipId && selectedClipId.trackId === track.id && selectedClipId.clipId === clipIdentifier) || (selectedItemIds && selectedItemIds.has(clipIdentifier));
|
||||
ctx.fillStyle = clip.isTemp ? 'rgba(239, 68, 68, 0.25)' : isClipSelected ? track.color ? track.color + '44' : 'rgba(6, 182, 212, 0.30)' : track.color ? track.color + '22' : 'rgba(6, 182, 212, 0.12)';
|
||||
ctx.strokeStyle = clip.isTemp ? '#ef4444' : isClipSelected ? '#fbbf24' : track.color || '#06b6d4';
|
||||
ctx.lineWidth = isClipSelected ? 1 : 1.5;
|
||||
@@ -7731,26 +7731,49 @@ const App = () => {
|
||||
if (idsToDelete.has(m.id)) { changed = true; return false; }
|
||||
return true;
|
||||
});
|
||||
const clips = (t.clips || []).filter(c => {
|
||||
let clips = t.clips || [];
|
||||
const hasVirtualClip = !t.clips || t.clips.length === 0;
|
||||
if (hasVirtualClip && t.buffer) {
|
||||
const canonical = 'default_' + t.id;
|
||||
if (idsToDelete.has(canonical)) {
|
||||
changed = true;
|
||||
return {
|
||||
...t,
|
||||
sections,
|
||||
midiItems,
|
||||
clips: [],
|
||||
buffer: null,
|
||||
startTime: 0
|
||||
};
|
||||
}
|
||||
}
|
||||
const updatedClips = 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;
|
||||
if (!changed && sections.length === (t.sections || []).length && midiItems.length === (t.midiItems || []).length) {
|
||||
return t;
|
||||
}
|
||||
return {
|
||||
...t,
|
||||
sections,
|
||||
midiItems,
|
||||
clips,
|
||||
buffer: clips[0]?.buffer || null,
|
||||
startTime: clips[0]?.startTime || 0,
|
||||
name: clips[0]?.name || t.name
|
||||
clips: updatedClips,
|
||||
buffer: updatedClips.length > 0 ? updatedClips[0].buffer : null,
|
||||
startTime: updatedClips.length > 0 ? updatedClips[0].startTime : 0,
|
||||
name: updatedClips.length > 0 ? updatedClips[0].name : t.name
|
||||
};
|
||||
}));
|
||||
showToast(count === 1 ? 'Đã xóa 1 item.' : `Đã xóa ${count} items.`, 'info');
|
||||
};
|
||||
const selectedClipIdRef = useRef(null);
|
||||
selectedClipIdRef.current = selectedClipId;
|
||||
const selectedTrackIdRef = useRef(selectedTrackId);
|
||||
selectedTrackIdRef.current = selectedTrackId;
|
||||
const handleDeleteTrackRef = useRef(() => {});
|
||||
const handleSplitTrackRef = useRef(() => {});
|
||||
const handleRecordClickRef = useRef(() => {});
|
||||
const activeTabRef = useRef(activeTab);
|
||||
activeTabRef.current = activeTab;
|
||||
const activePlaybackSpeedRef = useRef(1.0);
|
||||
@@ -8009,8 +8032,8 @@ const App = () => {
|
||||
// Global space play/pause shortcut for transport
|
||||
if (e.key === ' ' || e.code === 'Space') {
|
||||
e.preventDefault();
|
||||
if (recordingState === 'RECORDING' || recordingState === 'COUNT_IN') {
|
||||
handleRecordClick();
|
||||
if (recordingStateRef.current === 'RECORDING' || recordingStateRef.current === 'COUNT_IN') {
|
||||
handleRecordClickRef.current();
|
||||
return;
|
||||
}
|
||||
if (handlePlayPauseRef.current) handlePlayPauseRef.current();
|
||||
@@ -8135,7 +8158,14 @@ const App = () => {
|
||||
(activeTracksRef.current || []).forEach(t => {
|
||||
(t.sections || []).forEach(s => allIds.add(s.id));
|
||||
(t.midiItems || []).forEach(m => allIds.add(m.id));
|
||||
(t.clips || []).forEach(c => allIds.add(c.id === 'default' ? 'default_' + t.id : c.id));
|
||||
const clips = t.clips && t.clips.length > 0 ? t.clips : t.buffer ? [{
|
||||
id: 'default',
|
||||
buffer: t.buffer,
|
||||
startTime: t.startTime || 0,
|
||||
name: t.name,
|
||||
speed: t.speed || 1.0
|
||||
}] : [];
|
||||
clips.forEach(c => allIds.add(c.id === 'default' ? 'default_' + t.id : c.id));
|
||||
});
|
||||
setSelectedItemIds(allIds);
|
||||
return;
|
||||
@@ -8234,7 +8264,7 @@ const App = () => {
|
||||
return;
|
||||
} else {
|
||||
e.preventDefault();
|
||||
handleDeleteTrack();
|
||||
handleDeleteTrackRef.current();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -8285,7 +8315,7 @@ const App = () => {
|
||||
}
|
||||
if (!ctrl && !alt && e.key === 's') {
|
||||
e.preventDefault();
|
||||
handleSplitTrack(selectedTrackId);
|
||||
handleSplitTrackRef.current(selectedTrackIdRef.current);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -9705,6 +9735,7 @@ const App = () => {
|
||||
}
|
||||
showToast('Deleted track.', 'info');
|
||||
};
|
||||
handleDeleteTrackRef.current = handleDeleteTrack;
|
||||
|
||||
// ── Server Health Check ──
|
||||
const [viewportWidth, setViewportWidth] = useState(1200);
|
||||
@@ -10943,6 +10974,7 @@ const App = () => {
|
||||
setRecordingState('IDLE');
|
||||
}
|
||||
};
|
||||
handleRecordClickRef.current = handleRecordClick;
|
||||
|
||||
const startRecordingTake = async (armedTracks) => {
|
||||
const context = getAudioContext();
|
||||
@@ -14120,6 +14152,7 @@ const App = () => {
|
||||
const handleSplitTrack = trackId => {
|
||||
handleSplitTrackAtTime(trackId, null, currentTime);
|
||||
};
|
||||
handleSplitTrackRef.current = handleSplitTrack;
|
||||
|
||||
// ── Glue (Merge) Clips on Selected Track ──
|
||||
const handleGlueTracks = () => {
|
||||
|
||||
Reference in New Issue
Block a user