diff --git a/app/templates/index.html b/app/templates/index.html
index 1e9160b..3d21a73 100644
--- a/app/templates/index.html
+++ b/app/templates/index.html
@@ -832,40 +832,141 @@
);
};
- const SubTabToolbar = ({ st, activeTool, setActiveTool, handleSubTabNormalizeWithValue, handleSubTabGainWithValue, handleSubTabPitch, handleSubTabStretch, handleSubTabFade }) => (
+ const SubTabToolbar = ({ st, activeTool, setActiveTool, handleSubTabNormalizeWithValue, handleSubTabGainWithValue, handleSubTabPitch, handleSubTabStretch, handleSubTabFade, onPlayPause, onStop, onRewind, onForward, onLoop, onRecord, onRateChange, onCut, onCopy, onPaste, onGlue, snapValue, onSnapChange }) => {
+ const isPlaying = st?.isPlaying || false;
+ const isLooping = st?.isLooping || false;
+ const isRecording = st?.isRecording || false;
+
+ return (
+ {/* Tools Section - passthrough từ main session */}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+ {/* Snap Section - passthrough */}
+
+ Snap
+
+
+
+ {/* Effects Controls */}
+
-
+ {/* Fade Buttons */}
+
+
+ {/* Transport Controls */}
+
+
+
+
+
+
+
+
+
+ {/* Rate Control */}
+
+ Rate:
+
+
);
+ };
const App = () => {
// ── State Definitions ──
@@ -3991,6 +4092,36 @@
>
+
+
+
+ {/* Transport Controls - gần toolbar */}
+
+
+
+
+
@@ -4315,10 +4446,10 @@
- {/* Transport Section */}
+ {/* Selection Info Section */}
-
Transport Controls
+
Selection Info
{formatTime(currentTime)}
@@ -4340,44 +4471,6 @@
{selectionStats.length}s
-
-
-
-
-
-
-
-
-
-
-
{/* AI Analysis & Edit Section */}
@@ -4487,6 +4580,19 @@
handleSubTabPitch={handleSubTabPitch}
handleSubTabStretch={handleSubTabStretch}
handleSubTabFade={handleSubTabFadeState}
+ onPlayPause={handlePlayPause}
+ onStop={handleStop}
+ onRewind={() => setSubTabs(prev => prev.map(s => s.id === st.id ? { ...s, currentTime: Math.max(0, (s.currentTime || 0) - 1) } : s))}
+ onForward={() => setSubTabs(prev => prev.map(s => s.id === st.id ? { ...s, currentTime: Math.min(s.buffer?.duration || 0, (s.currentTime || 0) + 1) } : s))}
+ onLoop={() => setSubTabs(prev => prev.map(s => s.id === st.id ? { ...s, isLooping: !s.isLooping } : s))}
+ onRecord={() => setSubTabs(prev => prev.map(s => s.id === st.id ? { ...s, isRecording: !s.isRecording } : s))}
+ onRateChange={(rate) => setSubTabs(prev => prev.map(s => s.id === st.id ? { ...s, playbackRate: rate } : s))}
+ onCut={() => { const curTabId = activeTab; handleSubTabCut(curTabId); }}
+ onCopy={() => { const curTabId = activeTab; handleSubTabCopy(curTabId); }}
+ onPaste={() => { const curTabId = activeTab; handleSubTabPaste(curTabId); }}
+ onGlue={() => showToast('Glue: Gộp clip trong subtab', 'info')}
+ snapValue={snapValue}
+ onSnapChange={setSnapValue}
/>
-
-
-
-
- SonicForge Studio - Professional DAW Editor
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file