summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2025-07-20 16:12:38 +0200
committerMaze Winther <mazewinther@gmail.com>2025-07-20 16:12:38 +0200
commitd7c9a2391cd0916357105cc9371675d8172b45e9 (patch)
treea9f1503e448cb7b91c24a7ff5df6ba0f8758b5c8
parent33d8caf65ca33fec731edcae84f43105b55245c6 (diff)
downloadopencut-d7c9a2391cd0916357105cc9371675d8172b45e9.tar.gz
fix: import
-rw-r--r--apps/web/src/components/keyboard-shortcuts-help.tsx63
-rw-r--r--timeline-toolbar.tsx219
2 files changed, 38 insertions, 244 deletions
diff --git a/apps/web/src/components/keyboard-shortcuts-help.tsx b/apps/web/src/components/keyboard-shortcuts-help.tsx
index 91cfb01a..4c8bfff5 100644
--- a/apps/web/src/components/keyboard-shortcuts-help.tsx
+++ b/apps/web/src/components/keyboard-shortcuts-help.tsx
@@ -1,6 +1,5 @@
"use client";
-import { useKeyboardShortcuts } from "@/hooks/use-keyboard-shortcuts";
import { useState, useEffect } from "react";
import { Button } from "./ui/button";
import {
@@ -37,11 +36,11 @@ function getKeyWithModifier(key: string) {
return modifier[key] || key;
}
-const ShortcutItem = ({
- shortcut,
- recordingKey,
- onStartRecording
-}: {
+const ShortcutItem = ({
+ shortcut,
+ recordingKey,
+ onStartRecording,
+}: {
shortcut: KeyboardShortcut;
recordingKey: string | null;
onStartRecording: (keyId: string, shortcut: KeyboardShortcut) => void;
@@ -72,7 +71,7 @@ const ShortcutItem = ({
{key.split("+").map((keyPart: string, partIndex: number) => {
const keyId = `${shortcut.id}-${index}-${partIndex}`;
return (
- <EditableShortcutKey
+ <EditableShortcutKey
key={partIndex}
keyId={keyId}
originalKey={key}
@@ -95,14 +94,14 @@ const ShortcutItem = ({
);
};
-const EditableShortcutKey = ({
- children,
+const EditableShortcutKey = ({
+ children,
keyId,
- originalKey,
+ originalKey,
shortcut,
isRecording,
- onStartRecording
-}: {
+ onStartRecording,
+}: {
children: React.ReactNode;
keyId: string;
originalKey: string;
@@ -119,22 +118,25 @@ const EditableShortcutKey = ({
return (
<kbd
className={`inline-flex font-sans text-xs rounded px-2 min-w-[1.5rem] min-h-[1.5rem] leading-none items-center justify-center shadow-sm border mr-1 cursor-pointer hover:bg-opacity-80 ${
- isRecording
- ? "border-primary bg-primary/10"
+ isRecording
+ ? "border-primary bg-primary/10"
: "border-white/10 bg-black/20"
}`}
onClick={handleClick}
- title={isRecording ? "Press any key combination..." : "Click to edit shortcut"}
- >
- {children}
- </kbd>
+ title={
+ isRecording ? "Press any key combination..." : "Click to edit shortcut"
+ }
+ >
+ {children}
+ </kbd>
);
};
export const KeyboardShortcutsHelp = () => {
const [open, setOpen] = useState(false);
const [recordingKey, setRecordingKey] = useState<string | null>(null);
- const [recordingShortcut, setRecordingShortcut] = useState<KeyboardShortcut | null>(null);
+ const [recordingShortcut, setRecordingShortcut] =
+ useState<KeyboardShortcut | null>(null);
const {
updateKeybinding,
@@ -159,7 +161,10 @@ export const KeyboardShortcutsHelp = () => {
const keyString = getKeybindingString(e);
if (keyString) {
// Auto-save the new keybinding
- const conflict = validateKeybinding(keyString, recordingShortcut.action);
+ const conflict = validateKeybinding(
+ keyString,
+ recordingShortcut.action
+ );
if (conflict) {
toast.error(
`Key "${keyString}" is already bound to "${conflict.existingAction}"`
@@ -175,7 +180,7 @@ export const KeyboardShortcutsHelp = () => {
// Add new keybinding
updateKeybinding(keyString, recordingShortcut.action);
-
+
setRecordingKey(null);
setRecordingShortcut(null);
}
@@ -188,12 +193,20 @@ export const KeyboardShortcutsHelp = () => {
document.addEventListener("keydown", handleKeyDown);
document.addEventListener("click", handleClickOutside);
-
+
return () => {
document.removeEventListener("keydown", handleKeyDown);
document.removeEventListener("click", handleClickOutside);
};
- }, [recordingKey, recordingShortcut, getKeybindingString, updateKeybinding, removeKeybinding, validateKeybinding, getKeybindingsForAction]);
+ }, [
+ recordingKey,
+ recordingShortcut,
+ getKeybindingString,
+ updateKeybinding,
+ removeKeybinding,
+ validateKeybinding,
+ getKeybindingsForAction,
+ ]);
const handleStartRecording = (keyId: string, shortcut: KeyboardShortcut) => {
setRecordingKey(keyId);
@@ -230,8 +243,8 @@ export const KeyboardShortcutsHelp = () => {
{shortcuts
.filter((shortcut) => shortcut.category === category)
.map((shortcut, index) => (
- <ShortcutItem
- key={index}
+ <ShortcutItem
+ key={index}
shortcut={shortcut}
recordingKey={recordingKey}
onStartRecording={handleStartRecording}
diff --git a/timeline-toolbar.tsx b/timeline-toolbar.tsx
deleted file mode 100644
index e887efa0..00000000
--- a/timeline-toolbar.tsx
+++ /dev/null
@@ -1,219 +0,0 @@
-"use client";
-
-import type { TrackType } from "@/types/timeline";
-import {
- ArrowLeftToLine,
- ArrowRightToLine,
- Copy,
- Pause,
- Play,
- Scissors,
- Snowflake,
- SplitSquareHorizontal,
- Trash2,
-} from "lucide-react";
-import { Button } from "../ui/button";
-import {
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "../ui/select";
-import {
- Tooltip,
- TooltipContent,
- TooltipProvider,
- TooltipTrigger,
-} from "../ui/tooltip";
-
-interface TimelineToolbarProps {
- isPlaying: boolean;
- currentTime: number;
- duration: number;
- speed: number;
- tracks: any[];
- toggle: () => void;
- setSpeed: (speed: number) => void;
- addTrack: (type: TrackType) => string;
- addClipToTrack: (trackId: string, clip: any) => void;
- handleSplitSelected: () => void;
- handleDuplicateSelected: () => void;
- handleFreezeSelected: () => void;
- handleDeleteSelected: () => void;
-}
-
-export function TimelineToolbar({
- isPlaying,
- currentTime,
- duration,
- speed,
- tracks,
- toggle,
- setSpeed,
- addTrack,
- addClipToTrack,
- handleSplitSelected,
- handleDuplicateSelected,
- handleFreezeSelected,
- handleDeleteSelected,
-}: TimelineToolbarProps) {
- return (
- <div className="border-b flex items-center px-2 py-1 gap-1">
- <TooltipProvider delayDuration={500}>
- {/* Play/Pause Button */}
- <Tooltip>
- <TooltipTrigger asChild>
- <Button
- variant="text"
- size="icon"
- onClick={toggle}
- className="mr-2"
- >
- {isPlaying ? (
- <Pause className="h-4 w-4" />
- ) : (
- <Play className="h-4 w-4" />
- )}
- </Button>
- </TooltipTrigger>
- <TooltipContent>
- {isPlaying ? "Pause (Space)" : "Play (Space)"}
- </TooltipContent>
- </Tooltip>
-
- <div className="w-px h-6 bg-border mx-1" />
-
- {/* Time Display */}
- <div
- className="text-xs text-muted-foreground font-mono px-2"
- style={{ minWidth: "18ch", textAlign: "center" }}
- >
- {currentTime.toFixed(1)}s / {duration.toFixed(1)}s
- </div>
-
- {/* Test Clip Button - for debugging */}
- {tracks.length === 0 && (
- <>
- <div className="w-px h-6 bg-border mx-1" />
- <Tooltip>
- <TooltipTrigger asChild>
- <Button
- variant="outline"
- size="sm"
- onClick={() => {
- const trackId = addTrack("media");
- addClipToTrack(trackId, {
- mediaId: "test",
- name: "Test Clip",
- duration: 5,
- startTime: 0,
- trimStart: 0,
- trimEnd: 0,
- });
- }}
- className="text-xs"
- >
- Add Test Clip
- </Button>
- </TooltipTrigger>
- <TooltipContent>Add a test clip to try playback</TooltipContent>
- </Tooltip>
- </>
- )}
-
- <div className="w-px h-6 bg-border mx-1" />
-
- <Tooltip>
- <TooltipTrigger asChild>
- <Button variant="text" size="icon" onClick={handleSplitSelected}>
- <Scissors className="h-4 w-4" />
- </Button>
- </TooltipTrigger>
- <TooltipContent>Split clip (S)</TooltipContent>
- </Tooltip>
-
- <Tooltip>
- <TooltipTrigger asChild>
- <Button variant="text" size="icon">
- <ArrowLeftToLine className="h-4 w-4" />
- </Button>
- </TooltipTrigger>
- <TooltipContent>Split and keep left (A)</TooltipContent>
- </Tooltip>
-
- <Tooltip>
- <TooltipTrigger asChild>
- <Button variant="text" size="icon">
- <ArrowRightToLine className="h-4 w-4" />
- </Button>
- </TooltipTrigger>
- <TooltipContent>Split and keep right (D)</TooltipContent>
- </Tooltip>
-
- <Tooltip>
- <TooltipTrigger asChild>
- <Button variant="text" size="icon">
- <SplitSquareHorizontal className="h-4 w-4" />
- </Button>
- </TooltipTrigger>
- <TooltipContent>Separate audio (E)</TooltipContent>
- </Tooltip>
-
- <Tooltip>
- <TooltipTrigger asChild>
- <Button
- variant="text"
- size="icon"
- onClick={handleDuplicateSelected}
- >
- <Copy className="h-4 w-4" />
- </Button>
- </TooltipTrigger>
- <TooltipContent>Duplicate clip (Ctrl+D)</TooltipContent>
- </Tooltip>
-
- <Tooltip>
- <TooltipTrigger asChild>
- <Button variant="text" size="icon" onClick={handleFreezeSelected}>
- <Snowflake className="h-4 w-4" />
- </Button>
- </TooltipTrigger>
- <TooltipContent>Freeze frame (F)</TooltipContent>
- </Tooltip>
-
- <Tooltip>
- <TooltipTrigger asChild>
- <Button variant="text" size="icon" onClick={handleDeleteSelected}>
- <Trash2 className="h-4 w-4" />
- </Button>
- </TooltipTrigger>
- <TooltipContent>Delete clip (Delete)</TooltipContent>
- </Tooltip>
-
- <div className="w-px h-6 bg-border mx-1" />
-
- {/* Speed Control */}
- <Tooltip>
- <TooltipTrigger asChild>
- <Select
- value={speed.toFixed(1)}
- onValueChange={(value) => setSpeed(parseFloat(value))}
- >
- <SelectTrigger className="w-[90px] h-8">
- <SelectValue placeholder="1.0x" />
- </SelectTrigger>
- <SelectContent>
- <SelectItem value="0.5">0.5x</SelectItem>
- <SelectItem value="1.0">1.0x</SelectItem>
- <SelectItem value="1.5">1.5x</SelectItem>
- <SelectItem value="2.0">2.0x</SelectItem>
- </SelectContent>
- </Select>
- </TooltipTrigger>
- <TooltipContent>Playback Speed</TooltipContent>
- </Tooltip>
- </TooltipProvider>
- </div>
- );
-}