fix: không hiển thị UI trên browser sau khi cài đặt phím tắt cho menu hệ thống
This commit is contained in:
+18
-53
@@ -6,9 +6,9 @@
|
||||
<title>SonicForge Studio - Professional DAW Editor</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js"></script>
|
||||
<script src="https://unpkg.com/@babel/standalone@7.26.0/babel.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #1a1a1a;
|
||||
@@ -460,70 +460,35 @@
|
||||
const isDraggingRulerRef = useRef(false);
|
||||
const handlePlayPauseRef = useRef(null);
|
||||
|
||||
// ── Keyboard Shortcuts (LOOP_EDITOR_2.md §4.3, menu shortcuts) ──
|
||||
// ── Keyboard Shortcuts ──
|
||||
const handleUndoRef = useRef(handleUndo);
|
||||
const handleRedoRef = useRef(handleRedo);
|
||||
const handlePlayPauseRef = useRef(null);
|
||||
const keyHandlersRef = useRef({});
|
||||
handleUndoRef.current = handleUndo;
|
||||
handleRedoRef.current = handleRedo;
|
||||
|
||||
// Keep key handlers up-to-date via refs (avoids stale closures in useEffect)
|
||||
useEffect(() => {
|
||||
keyHandlersRef.current = {
|
||||
addNewTrack, handleSplitTrack, handleMergeTracks, handleCopyTrack,
|
||||
handleCutTrack, handleDeleteTrack, contextMenuPaste, openTempTab,
|
||||
openTempTabImport: () => {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'file'; input.accept = 'audio/*';
|
||||
input.onchange = async (e) => {
|
||||
if (e.target.files[0]) {
|
||||
addNewTrack();
|
||||
const newId = (tracks.length + 1).toString();
|
||||
setTimeout(() => loadFileOnTrack(newId, e.target.files[0]), 100);
|
||||
}
|
||||
};
|
||||
input.click();
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e) => {
|
||||
const k = keyHandlersRef.current;
|
||||
const handler = (e) => {
|
||||
const ctrl = e.ctrlKey || e.metaKey;
|
||||
const alt = e.altKey;
|
||||
|
||||
// Space: play/pause
|
||||
if (e.key === ' ' || e.code === 'Space') {
|
||||
e.preventDefault();
|
||||
if (handlePlayPauseRef.current) handlePlayPauseRef.current();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+Z: Undo, Ctrl+Y or Ctrl+Shift+Z: Redo
|
||||
if (e.key === ' ' || e.code === 'Space') { e.preventDefault(); if (handlePlayPauseRef.current) handlePlayPauseRef.current(); return; }
|
||||
if (ctrl && e.key === 'z' && !e.shiftKey) { e.preventDefault(); handleUndoRef.current(); return; }
|
||||
if (ctrl && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) { e.preventDefault(); handleRedoRef.current(); return; }
|
||||
|
||||
// File menu shortcuts
|
||||
if (ctrl && !alt && e.key === 'o') { e.preventDefault(); showToast('Open Project dialog','info'); return; }
|
||||
if (ctrl && !alt && e.key === 's') { e.preventDefault(); showToast('Project saved','success'); return; }
|
||||
if (ctrl && alt && e.key === 's') { e.preventDefault(); showToast('Save As dialog','info'); return; }
|
||||
|
||||
// Edit menu shortcuts
|
||||
if (ctrl && !alt && e.key === 'i') { e.preventDefault(); k.addNewTrack(); return; }
|
||||
if (ctrl && alt && e.key === 'i') { e.preventDefault(); k.openTempTabImport(); return; }
|
||||
if (ctrl && !alt && e.key === 'e') { e.preventDefault(); k.openTempTab(); return; }
|
||||
if (!ctrl && !alt && (e.key === 's' || e.key === 'S')) { e.preventDefault(); k.handleSplitTrack(selectedTrackId); return; }
|
||||
if (ctrl && !alt && e.key === 'm') { e.preventDefault(); k.handleMergeTracks(); return; }
|
||||
if (ctrl && !alt && e.key === 'c') { e.preventDefault(); k.handleCopyTrack(); return; }
|
||||
if (ctrl && !alt && e.key === 'x') { e.preventDefault(); k.handleCutTrack(); return; }
|
||||
if (ctrl && !alt && e.key === 'v') { e.preventDefault(); k.contextMenuPaste(); return; }
|
||||
if (e.key === 'Delete' || e.key === 'Del') { e.preventDefault(); k.handleDeleteTrack(); return; }
|
||||
if (ctrl && !alt && e.key === 'i') { e.preventDefault(); addNewTrack(); return; }
|
||||
if (ctrl && alt && e.key === 'i') { e.preventDefault(); showToast('Import audio','info'); return; }
|
||||
if (ctrl && !alt && e.key === 'e') { e.preventDefault(); openTempTab(); return; }
|
||||
if (ctrl && !alt && e.key === 'm') { e.preventDefault(); handleMergeTracks(); return; }
|
||||
if (ctrl && !alt && e.key === 'c') { e.preventDefault(); handleCopyTrack(); return; }
|
||||
if (ctrl && !alt && e.key === 'x') { e.preventDefault(); handleCutTrack(); return; }
|
||||
if (ctrl && !alt && e.key === 'v') { e.preventDefault(); contextMenuPaste(); return; }
|
||||
if (e.key === 'Delete' || e.key === 'Del') { e.preventDefault(); handleDeleteTrack(); return; }
|
||||
if (!ctrl && !alt && e.key === 's') { e.preventDefault(); handleSplitTrack(selectedTrackId); return; }
|
||||
};
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, []); // empty deps: refs avoid stale closure
|
||||
window.addEventListener('keydown', handler);
|
||||
return () => window.removeEventListener('keydown', handler);
|
||||
}, []);
|
||||
|
||||
// ── Temp Tab: draw isolated waveform ──
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user