summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2025-08-15 22:34:04 +0200
committerMaze Winther <mazewinther@gmail.com>2025-08-15 22:34:04 +0200
commitaa5cd1edca05952b1ed3ccddf2fd93816bae3a2f (patch)
tree93ebdefb0d5f44a4efcb82362dc27ecea62c25d4 /apps
parent32d263fcccb43bc7a06033a79aac6537563a6196 (diff)
downloadopencut-aa5cd1edca05952b1ed3ccddf2fd93816bae3a2f.tar.gz
refactor: shortcuts help
Diffstat (limited to 'apps')
-rw-r--r--apps/web/src/components/keyboard-shortcuts-help.tsx186
1 files changed, 90 insertions, 96 deletions
diff --git a/apps/web/src/components/keyboard-shortcuts-help.tsx b/apps/web/src/components/keyboard-shortcuts-help.tsx
index fd0af837..dd06315d 100644
--- a/apps/web/src/components/keyboard-shortcuts-help.tsx
+++ b/apps/web/src/components/keyboard-shortcuts-help.tsx
@@ -19,96 +19,7 @@ import {
DialogTrigger,
} from "./ui/dialog";
-const ShortcutItem = ({
- shortcut,
- isRecording,
- onStartRecording,
-}: {
- shortcut: KeyboardShortcut;
- isRecording: boolean;
- onStartRecording: (shortcut: KeyboardShortcut) => void;
-}) => {
- // Filter out lowercase duplicates for display - if both "j" and "J" exist, only show "J"
- const displayKeys = shortcut.keys.filter((key: string) => {
- if (
- key.includes("Cmd") &&
- shortcut.keys.includes(key.replace("Cmd", "Ctrl"))
- )
- return false;
-
- return true;
- });
-
- return (
- <div className="flex items-center justify-between">
- <div className="flex items-center gap-3">
- {shortcut.icon && (
- <div className="text-muted-foreground">{shortcut.icon}</div>
- )}
- <span className="text-sm">{shortcut.description}</span>
- </div>
- <div className="flex items-center gap-1">
- {displayKeys.map((key: string, index: number) => (
- <div key={key} className="flex items-center gap-1">
- <div className="flex items-center">
- {key.split("+").map((keyPart: string, partIndex: number) => {
- const keyId = `${shortcut.id}-${index}-${partIndex}`;
- return (
- <EditableShortcutKey
- key={keyId}
- isRecording={isRecording}
- onStartRecording={() => onStartRecording(shortcut)}
- >
- {keyPart}
- </EditableShortcutKey>
- );
- })}
- </div>
- {index < displayKeys.length - 1 && (
- <span className="text-xs text-muted-foreground">or</span>
- )}
- </div>
- ))}
- </div>
- </div>
- );
-};
-
-const EditableShortcutKey = ({
- children,
- isRecording,
- onStartRecording,
-}: {
- children: React.ReactNode;
- isRecording: boolean;
- onStartRecording: () => void;
-}) => {
- const handleClick = (e: React.MouseEvent) => {
- e.preventDefault();
- e.stopPropagation();
- onStartRecording();
- };
-
- return (
- <Button
- variant="text"
- size="sm"
- className={`inline-flex font-sans text-xs rounded px-2 min-w-6 min-h-6 leading-none items-center justify-center shadow-xs border mr-1 cursor-pointer hover:bg-opacity-80 ${
- isRecording
- ? "border-primary bg-primary/10"
- : "border bg-accent"
- }`}
- onClick={handleClick}
- title={
- isRecording ? "Press any key combination..." : "Click to edit shortcut"
- }
- >
- {children}
- </Button>
- );
-};
-
-export const KeyboardShortcutsHelp = () => {
+export function KeyboardShortcutsHelp() {
const [open, setOpen] = useState(false);
const [recordingShortcut, setRecordingShortcut] =
useState<KeyboardShortcut | null>(null);
@@ -237,15 +148,98 @@ export const KeyboardShortcutsHelp = () => {
</div>
</div>
<DialogFooter className="flex-shrink-0 p-6 pt-4">
- <Button
- size="sm"
- variant="destructive"
- onClick={resetToDefaults}
- >
+ <Button size="sm" variant="destructive" onClick={resetToDefaults}>
Reset to Default
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
-};
+}
+
+function ShortcutItem({
+ shortcut,
+ isRecording,
+ onStartRecording,
+}: {
+ shortcut: KeyboardShortcut;
+ isRecording: boolean;
+ onStartRecording: (shortcut: KeyboardShortcut) => void;
+}) {
+ // Filter out lowercase duplicates for display - if both "j" and "J" exist, only show "J"
+ const displayKeys = shortcut.keys.filter((key: string) => {
+ if (
+ key.includes("Cmd") &&
+ shortcut.keys.includes(key.replace("Cmd", "Ctrl"))
+ )
+ return false;
+
+ return true;
+ });
+
+ return (
+ <div className="flex items-center justify-between">
+ <div className="flex items-center gap-3">
+ {shortcut.icon && (
+ <div className="text-muted-foreground">{shortcut.icon}</div>
+ )}
+ <span className="text-sm">{shortcut.description}</span>
+ </div>
+ <div className="flex items-center gap-1">
+ {displayKeys.map((key: string, index: number) => (
+ <div key={key} className="flex items-center gap-1">
+ <div className="flex items-center">
+ {key.split("+").map((keyPart: string, partIndex: number) => {
+ const keyId = `${shortcut.id}-${index}-${partIndex}`;
+ return (
+ <EditableShortcutKey
+ key={keyId}
+ isRecording={isRecording}
+ onStartRecording={() => onStartRecording(shortcut)}
+ >
+ {keyPart}
+ </EditableShortcutKey>
+ );
+ })}
+ </div>
+ {index < displayKeys.length - 1 && (
+ <span className="text-xs text-muted-foreground">or</span>
+ )}
+ </div>
+ ))}
+ </div>
+ </div>
+ );
+}
+
+function EditableShortcutKey({
+ children,
+ isRecording,
+ onStartRecording,
+}: {
+ children: React.ReactNode;
+ isRecording: boolean;
+ onStartRecording: () => void;
+}) {
+ const handleClick = (e: React.MouseEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+ onStartRecording();
+ };
+
+ return (
+ <Button
+ variant="text"
+ size="sm"
+ className={`inline-flex font-sans text-xs rounded px-2 min-w-6 min-h-6 leading-none items-center justify-center shadow-xs border mr-1 cursor-pointer hover:bg-opacity-80 ${
+ isRecording ? "border-primary bg-primary/10" : "border bg-accent"
+ }`}
+ onClick={handleClick}
+ title={
+ isRecording ? "Press any key combination..." : "Click to edit shortcut"
+ }
+ >
+ {children}
+ </Button>
+ );
+} \ No newline at end of file