feat: complete Phase 13 - Keyboard Shortcuts
Added all remaining keyboard shortcuts for a complete keyboard-driven workflow: Playback Shortcuts: - Home: Jump to start - End: Jump to end - Left/Right Arrow: Seek ±1 second - Ctrl+Left/Right: Seek ±5 seconds Editing Shortcuts: - Ctrl+A: Select All (entire track content) View Shortcuts: - Ctrl+Plus/Equals: Zoom in - Ctrl+Minus: Zoom out - Ctrl+0: Fit to view All shortcuts work seamlessly with existing shortcuts: - Spacebar: Play/Pause - Ctrl+Z/Y: Undo/Redo - Ctrl+X/C/V: Cut/Copy/Paste - Ctrl+S: Save - Ctrl+D: Duplicate - Delete/Backspace: Delete - Escape: Clear selection The editor is now fully controllable via keyboard for a professional audio editing workflow similar to Audacity/Reaper. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1386,12 +1386,90 @@ export function AudioEditor() {
|
||||
if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
setSelectedTrackId(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Home: Go to start
|
||||
if (e.key === 'Home') {
|
||||
e.preventDefault();
|
||||
seek(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// End: Go to end
|
||||
if (e.key === 'End') {
|
||||
e.preventDefault();
|
||||
seek(duration);
|
||||
return;
|
||||
}
|
||||
|
||||
// Left Arrow: Seek backward 1 second
|
||||
if (e.key === 'ArrowLeft' && !e.ctrlKey && !e.metaKey) {
|
||||
e.preventDefault();
|
||||
seek(Math.max(0, currentTime - 1));
|
||||
return;
|
||||
}
|
||||
|
||||
// Right Arrow: Seek forward 1 second
|
||||
if (e.key === 'ArrowRight' && !e.ctrlKey && !e.metaKey) {
|
||||
e.preventDefault();
|
||||
seek(Math.min(duration, currentTime + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+Left Arrow: Seek backward 5 seconds
|
||||
if (e.key === 'ArrowLeft' && (e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
seek(Math.max(0, currentTime - 5));
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+Right Arrow: Seek forward 5 seconds
|
||||
if (e.key === 'ArrowRight' && (e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
seek(Math.min(duration, currentTime + 5));
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+A: Select All (select all content on current track)
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'a') {
|
||||
e.preventDefault();
|
||||
if (selectedTrackId) {
|
||||
const track = tracks.find(t => t.id === selectedTrackId);
|
||||
if (track?.audioBuffer) {
|
||||
updateTrack(selectedTrackId, {
|
||||
selection: { start: 0, end: track.audioBuffer.duration }
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+Plus/Equals: Zoom in
|
||||
if ((e.ctrlKey || e.metaKey) && (e.key === '+' || e.key === '=')) {
|
||||
e.preventDefault();
|
||||
handleZoomIn();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+Minus: Zoom out
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === '-') {
|
||||
e.preventDefault();
|
||||
handleZoomOut();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+0: Fit to view
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === '0') {
|
||||
e.preventDefault();
|
||||
handleFitToView();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, [togglePlayPause, canUndo, canRedo, undo, redo, handleCut, handleCopy, handlePaste, handleDelete, handleDuplicate, handleSaveProject]);
|
||||
}, [togglePlayPause, canUndo, canRedo, undo, redo, handleCut, handleCopy, handlePaste, handleDelete, handleDuplicate, handleSaveProject, seek, duration, currentTime, selectedTrackId, tracks, updateTrack, handleZoomIn, handleZoomOut, handleFitToView]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user