Files
audio-ui/components/editor/EditControls.tsx
Sebastian Krüger 159da29082 feat: implement Phase 5 - undo/redo system with command pattern
Added comprehensive undo/redo functionality:
- Command pattern interface and base classes
- HistoryManager with 50-operation stack
- EditCommand for all edit operations (cut, delete, paste, trim)
- Full keyboard shortcuts (Ctrl+Z undo, Ctrl+Y/Ctrl+Shift+Z redo)
- HistoryControls UI component with visual feedback
- Integrated history system with all edit operations
- Toast notifications for undo/redo actions
- History state tracking and display

New files:
- lib/history/command.ts - Command interface and BaseCommand
- lib/history/history-manager.ts - HistoryManager class
- lib/history/commands/edit-command.ts - EditCommand and factory functions
- lib/hooks/useHistory.ts - React hook for history management
- components/editor/HistoryControls.tsx - History UI component

Modified files:
- components/editor/AudioEditor.tsx - Integrated history system
- components/editor/EditControls.tsx - Updated keyboard shortcuts display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 17:08:31 +01:00

140 lines
3.9 KiB
TypeScript

'use client';
import * as React from 'react';
import { Scissors, Copy, Clipboard, Trash2, CropIcon, Info } from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { cn } from '@/lib/utils/cn';
import type { Selection } from '@/types/selection';
import { formatDuration } from '@/lib/audio/decoder';
export interface EditControlsProps {
selection: Selection | null;
hasClipboard: boolean;
onCut: () => void;
onCopy: () => void;
onPaste: () => void;
onDelete: () => void;
onTrim: () => void;
onClearSelection: () => void;
className?: string;
}
export function EditControls({
selection,
hasClipboard,
onCut,
onCopy,
onPaste,
onDelete,
onTrim,
onClearSelection,
className,
}: EditControlsProps) {
const hasSelection = selection !== null;
const selectionDuration = selection ? selection.end - selection.start : 0;
return (
<div className={cn('space-y-4', className)}>
{/* Selection Info */}
{hasSelection && (
<div className="rounded-lg border border-info bg-info/10 p-3">
<div className="flex items-start gap-2">
<Info className="h-4 w-4 text-info-foreground mt-0.5 flex-shrink-0" />
<div className="flex-1 min-w-0 text-sm">
<p className="font-medium text-info-foreground">Selection Active</p>
<p className="text-info-foreground/90 mt-1">
Duration: {formatDuration(selectionDuration)} |
Start: {formatDuration(selection.start)} |
End: {formatDuration(selection.end)}
</p>
<p className="text-xs text-info-foreground/75 mt-1">
Tip: Hold Shift and drag on the waveform to select a region
</p>
</div>
</div>
</div>
)}
{/* Edit Buttons */}
<div className="grid grid-cols-2 gap-2">
<Button
variant="outline"
onClick={onCut}
disabled={!hasSelection}
title="Cut (Ctrl+X)"
className="justify-start"
>
<Scissors className="h-4 w-4 mr-2" />
Cut
</Button>
<Button
variant="outline"
onClick={onCopy}
disabled={!hasSelection}
title="Copy (Ctrl+C)"
className="justify-start"
>
<Copy className="h-4 w-4 mr-2" />
Copy
</Button>
<Button
variant="outline"
onClick={onPaste}
disabled={!hasClipboard}
title="Paste (Ctrl+V)"
className="justify-start"
>
<Clipboard className="h-4 w-4 mr-2" />
Paste
</Button>
<Button
variant="outline"
onClick={onDelete}
disabled={!hasSelection}
title="Delete (Del)"
className="justify-start"
>
<Trash2 className="h-4 w-4 mr-2" />
Delete
</Button>
<Button
variant="outline"
onClick={onTrim}
disabled={!hasSelection}
title="Trim to Selection"
className="justify-start"
>
<CropIcon className="h-4 w-4 mr-2" />
Trim
</Button>
<Button
variant="outline"
onClick={onClearSelection}
disabled={!hasSelection}
title="Clear Selection (Esc)"
className="justify-start"
>
Clear
</Button>
</div>
{/* Keyboard Shortcuts Info */}
<div className="text-xs text-muted-foreground space-y-1 p-3 rounded-lg bg-muted/30">
<p className="font-medium mb-2">Edit Shortcuts:</p>
<p> Shift+Drag: Select region</p>
<p> Ctrl+A: Select all</p>
<p> Ctrl+X: Cut</p>
<p> Ctrl+C: Copy</p>
<p> Ctrl+V: Paste</p>
<p> Delete: Delete selection</p>
<p> Escape: Clear selection</p>
</div>
</div>
);
}