From 6b7872c636eb609627498aeec6d05f8d8a296200 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Wed, 22 Jul 2026 17:52:00 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20=C4=91=E1=BB=93ng=20b=E1=BB=99=20h=C3=B3?= =?UTF-8?q?a=20tr=E1=BA=A1ng=20th=C3=A1i=20track=20l=E1=BB=B1a=20ch?= =?UTF-8?q?=E1=BB=8Dn=20th=E1=BB=9Di=20gian=20th=E1=BB=B1c=20cho=20chu?= =?UTF-8?q?=E1=BB=97i=20l=E1=BB=87nh=20AI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/js/app.jsx | 58 ++++++++++++++++++++++--------- app/static/js/app.precompiled.js | 58 ++++++++++++++++++++++--------- app/storage/sonicforge.db | Bin 45056 -> 45056 bytes 3 files changed, 82 insertions(+), 34 deletions(-) diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index 378a166..affcd2e 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -7136,6 +7136,10 @@ const App = () => { const handleAISend = async () => { const prompt = aiPrompt.trim(); if (!prompt) { showToast('Vui lòng nhập nội dung prompt.', 'warning'); return; } + if (window.DAWCommandDispatcher) { + window.DAWCommandDispatcher.currentSelectedTrackId = selectedTrackId; + window.DAWCommandDispatcher.currentTracks = tracks; + } setAiProcessing(true); setAiActionLog(prev => [...prev, { type: 'status', text: ` ⏳ Đang gửi prompt đến AI...`, time: Date.now() }]); try { @@ -7509,8 +7513,10 @@ const App = () => { return { success: true, start: parseFloat(start.toFixed(3)), end: parseFloat(end.toFixed(3)), length: parseFloat((end - start).toFixed(3)) }; }, cutAudio: (args) => { - const tid = args.track_id || selectedTrackId; - const track = tracks.find(t => t.id === tid); + const currentTracks = window.DAWCommandDispatcher?.currentTracks || tracks; + const currentSelTrackId = window.DAWCommandDispatcher?.currentSelectedTrackId || selectedTrackId; + const tid = args.track_id || currentSelTrackId; + const track = currentTracks.find(t => t.id === String(tid)); if (!track) return { success: false, error: 'Track not found' }; if (!track.buffer) return { success: false, error: 'Track has no audio buffer' }; const barDur = 60 / parseInt(bpm || 120) * 4; @@ -7545,7 +7551,7 @@ const App = () => { } const newId = 'track_cut_' + Date.now(); const colors = ['#0f766e', '#1d4ed8', '#701a75', '#a21caf', '#b45309']; - const color = colors[tracks.length % colors.length]; + const color = colors[currentTracks.length % colors.length]; const cutName = args.new_track_name || `Cut_${track.name}`; const newTrack = { id: newId, name: cutName, buffer: slicedBuffer, @@ -7554,12 +7560,18 @@ const App = () => { clips: [{ id: 'clip_' + newId, buffer: slicedBuffer, startTime: 0, name: cutName }], serverFileId: null }; - setTracks(prev => { - const idx = prev.findIndex(t => t.id === tid); - const updated = [...prev]; - updated.splice(idx + 1, 0, newTrack); - return updated; - }); + const idx = currentTracks.findIndex(t => t.id === tid); + const nextTracks = [...currentTracks]; + if (idx !== -1) { + nextTracks.splice(idx + 1, 0, newTrack); + } else { + nextTracks.push(newTrack); + } + if (window.DAWCommandDispatcher) { + window.DAWCommandDispatcher.currentTracks = nextTracks; + window.DAWCommandDispatcher.currentSelectedTrackId = newId; + } + setTracks(nextTracks); setSelectedTrackId(newId); selectionRef.current = { start: 0, end: slicedBuffer.duration }; clearLocalSelection(); @@ -7759,8 +7771,10 @@ const App = () => { return { success: true, trackId, time }; }, fadeIn: (args) => { - const trackIdRaw = args.track_id || selectedTrackId; - const track = tracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw); + const currentTracks = window.DAWCommandDispatcher?.currentTracks || tracks; + const currentSelTrackId = window.DAWCommandDispatcher?.currentSelectedTrackId || selectedTrackId; + const trackIdRaw = args.track_id || currentSelTrackId; + const track = currentTracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw); if (!track) return { success: false, error: `Track ${trackIdRaw} not found` }; const clips = track.clips && track.clips.length > 0 ? track.clips : (track.buffer ? [{ id: 'default_' + track.id, buffer: track.buffer, startTime: track.startTime || 0, name: track.name }] : []); if (clips.length === 0) return { success: false, error: 'No clips on track' }; @@ -7794,7 +7808,7 @@ const App = () => { } } const beforeSnap = captureTrackSnapshot(track.id); - setTracks(prev => prev.map(t => { + const nextTracks = currentTracks.map(t => { if (t.id !== track.id) return t; const existingClips = t.clips && t.clips.length > 0 ? t.clips : (t.buffer ? [{ id: 'default_' + t.id, buffer: t.buffer, startTime: t.startTime || 0, name: t.name }] : []); const updatedClips = existingClips.map(c => { @@ -7805,7 +7819,11 @@ const App = () => { }); const mainBuffer = updatedClips[0]?.buffer || t.buffer; return { ...t, clips: updatedClips, buffer: mainBuffer }; - })); + }); + if (window.DAWCommandDispatcher) { + window.DAWCommandDispatcher.currentTracks = nextTracks; + } + setTracks(nextTracks); setTimeout(() => { const afterSnap = captureTrackSnapshot(track.id); pushAction('AI_FADE_IN', track.id, beforeSnap, afterSnap); @@ -7813,8 +7831,10 @@ const App = () => { return { success: true, trackId: track.id, clipId: clip.id, duration_seconds: duration }; }, fadeOut: (args) => { - const trackIdRaw = args.track_id || selectedTrackId; - const track = tracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw); + const currentTracks = window.DAWCommandDispatcher?.currentTracks || tracks; + const currentSelTrackId = window.DAWCommandDispatcher?.currentSelectedTrackId || selectedTrackId; + const trackIdRaw = args.track_id || currentSelTrackId; + const track = currentTracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw); if (!track) return { success: false, error: `Track ${trackIdRaw} not found` }; const clips = track.clips && track.clips.length > 0 ? track.clips : (track.buffer ? [{ id: 'default_' + track.id, buffer: track.buffer, startTime: track.startTime || 0, name: track.name }] : []); if (clips.length === 0) return { success: false, error: 'No clips on track' }; @@ -7849,7 +7869,7 @@ const App = () => { } } const beforeSnap = captureTrackSnapshot(track.id); - setTracks(prev => prev.map(t => { + const nextTracks = currentTracks.map(t => { if (t.id !== track.id) return t; const existingClips = t.clips && t.clips.length > 0 ? t.clips : (t.buffer ? [{ id: 'default_' + t.id, buffer: t.buffer, startTime: t.startTime || 0, name: t.name }] : []); const updatedClips = existingClips.map(c => { @@ -7860,7 +7880,11 @@ const App = () => { }); const mainBuffer = updatedClips[0]?.buffer || t.buffer; return { ...t, clips: updatedClips, buffer: mainBuffer }; - })); + }); + if (window.DAWCommandDispatcher) { + window.DAWCommandDispatcher.currentTracks = nextTracks; + } + setTracks(nextTracks); setTimeout(() => { const afterSnap = captureTrackSnapshot(track.id); pushAction('AI_FADE_OUT', track.id, beforeSnap, afterSnap); diff --git a/app/static/js/app.precompiled.js b/app/static/js/app.precompiled.js index 1b72cfa..a6b0e45 100644 --- a/app/static/js/app.precompiled.js +++ b/app/static/js/app.precompiled.js @@ -7274,6 +7274,10 @@ const App = () => { showToast('Vui lòng nhập nội dung prompt.', 'warning'); return; } + if (window.DAWCommandDispatcher) { + window.DAWCommandDispatcher.currentSelectedTrackId = selectedTrackId; + window.DAWCommandDispatcher.currentTracks = tracks; + } setAiProcessing(true); setAiActionLog(prev => [...prev, { type: 'status', @@ -7779,8 +7783,10 @@ const App = () => { }; }, cutAudio: args => { - const tid = args.track_id || selectedTrackId; - const track = tracks.find(t => t.id === tid); + const currentTracks = window.DAWCommandDispatcher?.currentTracks || tracks; + const currentSelTrackId = window.DAWCommandDispatcher?.currentSelectedTrackId || selectedTrackId; + const tid = args.track_id || currentSelTrackId; + const track = currentTracks.find(t => t.id === String(tid)); if (!track) return { success: false, error: 'Track not found' @@ -7823,7 +7829,7 @@ const App = () => { } const newId = 'track_cut_' + Date.now(); const colors = ['#0f766e', '#1d4ed8', '#701a75', '#a21caf', '#b45309']; - const color = colors[tracks.length % colors.length]; + const color = colors[currentTracks.length % colors.length]; const cutName = args.new_track_name || `Cut_${track.name}`; const newTrack = { id: newId, @@ -7845,12 +7851,18 @@ const App = () => { }], serverFileId: null }; - setTracks(prev => { - const idx = prev.findIndex(t => t.id === tid); - const updated = [...prev]; - updated.splice(idx + 1, 0, newTrack); - return updated; - }); + const idx = currentTracks.findIndex(t => t.id === tid); + const nextTracks = [...currentTracks]; + if (idx !== -1) { + nextTracks.splice(idx + 1, 0, newTrack); + } else { + nextTracks.push(newTrack); + } + if (window.DAWCommandDispatcher) { + window.DAWCommandDispatcher.currentTracks = nextTracks; + window.DAWCommandDispatcher.currentSelectedTrackId = newId; + } + setTracks(nextTracks); setSelectedTrackId(newId); selectionRef.current = { start: 0, @@ -8140,8 +8152,10 @@ const App = () => { }; }, fadeIn: args => { - const trackIdRaw = args.track_id || selectedTrackId; - const track = tracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw); + const currentTracks = window.DAWCommandDispatcher?.currentTracks || tracks; + const currentSelTrackId = window.DAWCommandDispatcher?.currentSelectedTrackId || selectedTrackId; + const trackIdRaw = args.track_id || currentSelTrackId; + const track = currentTracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw); if (!track) return { success: false, error: `Track ${trackIdRaw} not found` @@ -8189,7 +8203,7 @@ const App = () => { } } const beforeSnap = captureTrackSnapshot(track.id); - setTracks(prev => prev.map(t => { + const nextTracks = currentTracks.map(t => { if (t.id !== track.id) return t; const existingClips = t.clips && t.clips.length > 0 ? t.clips : t.buffer ? [{ id: 'default_' + t.id, @@ -8212,7 +8226,11 @@ const App = () => { clips: updatedClips, buffer: mainBuffer }; - })); + }); + if (window.DAWCommandDispatcher) { + window.DAWCommandDispatcher.currentTracks = nextTracks; + } + setTracks(nextTracks); setTimeout(() => { const afterSnap = captureTrackSnapshot(track.id); pushAction('AI_FADE_IN', track.id, beforeSnap, afterSnap); @@ -8225,8 +8243,10 @@ const App = () => { }; }, fadeOut: args => { - const trackIdRaw = args.track_id || selectedTrackId; - const track = tracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw); + const currentTracks = window.DAWCommandDispatcher?.currentTracks || tracks; + const currentSelTrackId = window.DAWCommandDispatcher?.currentSelectedTrackId || selectedTrackId; + const trackIdRaw = args.track_id || currentSelTrackId; + const track = currentTracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw); if (!track) return { success: false, error: `Track ${trackIdRaw} not found` @@ -8275,7 +8295,7 @@ const App = () => { } } const beforeSnap = captureTrackSnapshot(track.id); - setTracks(prev => prev.map(t => { + const nextTracks = currentTracks.map(t => { if (t.id !== track.id) return t; const existingClips = t.clips && t.clips.length > 0 ? t.clips : t.buffer ? [{ id: 'default_' + t.id, @@ -8298,7 +8318,11 @@ const App = () => { clips: updatedClips, buffer: mainBuffer }; - })); + }); + if (window.DAWCommandDispatcher) { + window.DAWCommandDispatcher.currentTracks = nextTracks; + } + setTracks(nextTracks); setTimeout(() => { const afterSnap = captureTrackSnapshot(track.id); pushAction('AI_FADE_OUT', track.id, beforeSnap, afterSnap); diff --git a/app/storage/sonicforge.db b/app/storage/sonicforge.db index 8ec2f7f3cdf2efbae8a6cc2c0cbd7a745a476b7d..5a684f8b7f6615cb99035148a190fd3eda314b99 100644 GIT binary patch delta 336 zcmZp8z|`=7X@WFk+e8^>#4APR#j4YE4(^8TQ4bzg6Q;ZD^ER0eu49ra|(>8yW=L_KFZD(NS zh-Bbj&pnAFa$}=62WOiZ3uk<&eK-5$3AKC0ofC^n^7Hc)oD&ODi;5L|^79Myatn+n zTh;W{S1ToFBQpObrT_&>iV~BvJh2?7UnWo>X@la6>Kla6?ivod^2 Y0h4-r4hjLRLE4xo0Q{Kdv#)