diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index d98df55..f59a552 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -17852,8 +17852,9 @@ const App = () => { isPlayingRef.current = isPlaying; // Bounce realtime = project đang phát thật; guardPlay (scheduleMidiNoteDispatch) // phải cho note fire dù isPlayingRef bị render ghi đè =false khi bounce setState. + // (Không sync từ state ở đây — isExporting khai báo sau; bounce set true/false + // tường minh ở triggerBounceExport/finally.) const isExportingRef = useRef(false); - isExportingRef.current = isExporting; const [selectionStart, setSelectionStart] = useState(null); const [selectionEnd, setSelectionEnd] = useState(null); const [selectionFollowsTempo, setSelectionFollowsTempo] = useState(true); diff --git a/app/static/js/app.precompiled.js b/app/static/js/app.precompiled.js index 30ebedb..a8764b2 100644 --- a/app/static/js/app.precompiled.js +++ b/app/static/js/app.precompiled.js @@ -1140,7 +1140,9 @@ const[selectedTrackId,setSelectedTrackId]=useState('1');const[selectedItemIds,se // khi hết âm). const isPlayingRef=useRef(false);isPlayingRef.current=isPlaying;// Bounce realtime = project đang phát thật; guardPlay (scheduleMidiNoteDispatch) // phải cho note fire dù isPlayingRef bị render ghi đè =false khi bounce setState. -const isExportingRef=useRef(false);isExportingRef.current=isExporting;const[selectionStart,setSelectionStart]=useState(null);const[selectionEnd,setSelectionEnd]=useState(null);const[selectionFollowsTempo,setSelectionFollowsTempo]=useState(true);const selectionRef=useRef({start:null,end:null});selectionRef.current={start:selectionStart,end:selectionEnd};const[selectionMode,setSelectionMode]=useState(null);// 'global' (from ruler) | 'local' (from track) +// (Không sync từ state ở đây — isExporting khai báo sau; bounce set true/false +// tường minh ở triggerBounceExport/finally.) +const isExportingRef=useRef(false);const[selectionStart,setSelectionStart]=useState(null);const[selectionEnd,setSelectionEnd]=useState(null);const[selectionFollowsTempo,setSelectionFollowsTempo]=useState(true);const selectionRef=useRef({start:null,end:null});selectionRef.current={start:selectionStart,end:selectionEnd};const[selectionMode,setSelectionMode]=useState(null);// 'global' (from ruler) | 'local' (from track) const[sweepSelect,setSweepSelect]=useState(null);const isSweepingRef=useRef(false);const sweepStartRef=useRef(0);const sweepTrackIdRef=useRef(null);const sweepStartYRef=useRef(0);const sweepEndYRef=useRef(0);const sweepSelectRef=useRef(null);const pendingDragRef=useRef(null);// { trackId, itemType, itemId, clickOffset, startX, startY } const handleSectionItemDragStartRef=useRef(null);const[localSelectionTrackId,setLocalSelectionTrackId]=useState(null);const[localSelectionStart,setLocalSelectionStart]=useState(null);const[localSelectionEnd,setLocalSelectionEnd]=useState(null);const[zoom,setZoom]=useState(()=>{// Persist zoom qua reload (user yêu cầu giữ kích thước items sau refresh) try{const v=parseFloat(localStorage.getItem('sf_zoom'));if(isFinite(v)&&v>0)return v;}catch(e){}return 100;});React.useEffect(()=>{try{localStorage.setItem('sf_zoom',String(zoom));}catch(e){}// Zoom TIMELINE (App) — serialize project dùng cái này (window.__currentZoom diff --git a/app/templates/index.html b/app/templates/index.html index b457484..8516a06 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -51,7 +51,7 @@ - +