From f8ccb673bfd327e9001d5b7ba1ff77f303c2ec49 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Fri, 18 Jul 2025 11:51:47 +0200 Subject: style: match editing experience to match capcut --- apps/web/src/components/keybinding-editor.tsx | 425 -------------------------- 1 file changed, 425 deletions(-) delete mode 100644 apps/web/src/components/keybinding-editor.tsx (limited to 'apps/web/src/components/keybinding-editor.tsx') diff --git a/apps/web/src/components/keybinding-editor.tsx b/apps/web/src/components/keybinding-editor.tsx deleted file mode 100644 index bc98c5fd..00000000 --- a/apps/web/src/components/keybinding-editor.tsx +++ /dev/null @@ -1,425 +0,0 @@ -"use client"; - -import { useState, useEffect } from "react"; -import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { Badge } from "@/components/ui/badge"; -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, -} from "@/components/ui/alert-dialog"; -import { useKeybindingsStore } from "@/stores/keybindings-store"; -import { Action } from "@/constants/actions"; -import { KeyboardShortcut } from "@/hooks/use-keyboard-shortcuts-help"; -import { - Settings, - RotateCcw, - Download, - Upload, - X, - Check, - AlertTriangle, -} from "lucide-react"; -import { toast } from "sonner"; - -interface KeybindingEditorProps { - shortcuts: KeyboardShortcut[]; - onClose: () => void; -} - -interface KeyRecorderProps { - value: string; - onValueChange: (value: string) => void; - onCancel: () => void; -} - -const KeyRecorder = ({ value, onValueChange, onCancel }: KeyRecorderProps) => { - const [isRecording, setIsRecording] = useState(false); - const [recordedKey, setRecordedKey] = useState(""); - const { getKeybindingString } = useKeybindingsStore(); - - useEffect(() => { - if (!isRecording) return; - - const handleKeyDown = (e: KeyboardEvent) => { - e.preventDefault(); - - const keyString = getKeybindingString(e); - if (keyString) { - setRecordedKey(keyString); - } - }; - - document.addEventListener("keydown", handleKeyDown); - return () => document.removeEventListener("keydown", handleKeyDown); - }, [isRecording, getKeybindingString]); - - const handleStartRecording = () => { - setIsRecording(true); - setRecordedKey(""); - }; - - const handleConfirm = () => { - onValueChange(recordedKey); - setIsRecording(false); - setRecordedKey(""); - }; - - const handleCancel = () => { - setIsRecording(false); - setRecordedKey(""); - onCancel(); - }; - - const displayKey = recordedKey || value; - - return ( -
- - {isRecording ? ( -
- - -
- ) : ( - - )} -
- ); -}; - -export const KeybindingEditor = ({ - shortcuts, - onClose, -}: KeybindingEditorProps) => { - const { - keybindings, - updateKeybinding, - removeKeybinding, - resetToDefaults, - isCustomized, - validateKeybinding, - getKeybindingsForAction, - exportKeybindings, - importKeybindings, - } = useKeybindingsStore(); - - const [editingShortcut, setEditingShortcut] = useState(null); - const [newKeyBinding, setNewKeyBinding] = useState(""); - const [showResetDialog, setShowResetDialog] = useState(false); - const [searchTerm, setSearchTerm] = useState(""); - const [selectedCategory, setSelectedCategory] = useState("all"); - - const categories = [ - "all", - ...Array.from(new Set(shortcuts.map((s) => s.category))), - ]; - - const filteredShortcuts = shortcuts.filter((shortcut) => { - const matchesSearch = - shortcut.description.toLowerCase().includes(searchTerm.toLowerCase()) || - shortcut.keys.some((key) => - key.toLowerCase().includes(searchTerm.toLowerCase()) - ); - const matchesCategory = - selectedCategory === "all" || shortcut.category === selectedCategory; - return matchesSearch && matchesCategory; - }); - - const handleEditShortcut = (shortcut: KeyboardShortcut) => { - setEditingShortcut(shortcut.id); - setNewKeyBinding(shortcut.keys[0] || ""); - }; - - const handleSaveShortcut = () => { - if (!editingShortcut || !newKeyBinding) return; - - const shortcut = shortcuts.find((s) => s.id === editingShortcut); - if (!shortcut) return; - - // Validate the new keybinding - const conflict = validateKeybinding(newKeyBinding, shortcut.action); - if (conflict) { - toast.error( - `Key "${newKeyBinding}" is already bound to "${conflict.existingAction}"` - ); - return; - } - - // Remove old keybindings for this action - const oldKeys = getKeybindingsForAction(shortcut.action); - oldKeys.forEach((key) => removeKeybinding(key)); - - // Add new keybinding - updateKeybinding(newKeyBinding, shortcut.action); - - setEditingShortcut(null); - setNewKeyBinding(""); - toast.success("Keybinding updated successfully"); - }; - - const handleCancelEdit = () => { - setEditingShortcut(null); - setNewKeyBinding(""); - }; - - const handleRemoveShortcut = (shortcut: KeyboardShortcut) => { - const keys = getKeybindingsForAction(shortcut.action); - keys.forEach((key) => removeKeybinding(key)); - toast.success("Keybinding removed"); - }; - - const handleResetToDefaults = () => { - resetToDefaults(); - setShowResetDialog(false); - toast.success("Keybindings reset to defaults"); - }; - - const handleExportKeybindings = () => { - const config = exportKeybindings(); - const blob = new Blob([JSON.stringify(config, null, 2)], { - type: "application/json", - }); - const url = URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = url; - a.download = "opencut-keybindings.json"; - a.click(); - URL.revokeObjectURL(url); - toast.success("Keybindings exported"); - }; - - const handleImportKeybindings = ( - event: React.ChangeEvent - ) => { - const file = event.target.files?.[0]; - if (!file) return; - - const reader = new FileReader(); - reader.onload = (e) => { - try { - const config = JSON.parse(e.target?.result as string); - // Validate config structure - if (!config || typeof config !== "object") { - throw new Error("Invalid configuration format"); - } - - // Validate each keybinding - for (const [key, action] of Object.entries(config)) { - if (typeof key !== "string" || typeof action !== "string") { - throw new Error(`Invalid keybinding: ${key} -> ${action}`); - } - } - importKeybindings(config); - toast.success("Keybindings imported successfully"); - } catch (error) { - toast.error(`Failed to import keybindings: ${error}`); - } - }; - reader.readAsText(file); - }; - - return ( -
-
-
- -

- Customize Keyboard Shortcuts -

- {isCustomized && ( - - Modified - - )} -
-
- - - - - -
-
- -
- setSearchTerm(e.target.value)} - className="flex-1" - /> - - - {categories.map((category) => ( - - {category === "all" ? "All" : category} - - ))} - - -
- -
- {filteredShortcuts.map((shortcut) => ( - - -
-
-
-
-

{shortcut.description}

-

- {shortcut.category} -

-
-
-
-
-
- {editingShortcut === shortcut.id ? ( - - ) : ( -
- {shortcut.keys.map((key, index) => ( - - {key} - - ))} - {shortcut.keys.length === 0 && ( - - No binding - - )} -
- )} -
-
- {editingShortcut === shortcut.id ? ( - <> - - - - ) : ( - <> - - - - )} -
-
-
-
-
- ))} -
- - - - - - - Reset Keyboard Shortcuts? - - - This will reset all keyboard shortcuts to their default values. - Any custom keybindings will be lost. - - - - Cancel - - Reset to Defaults - - - - -
- ); -}; -- cgit v1.3.1