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:
2026-07-18 17:26:12 +07:00
parent a8fd4546b2
commit c967627558
8 changed files with 200 additions and 53 deletions
+18 -53
View File
@@ -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(() => {