Refactor hotkey setting UI (#506)

* refactor hotkeys setting

* update UI

* refactor

* fix toast
This commit is contained in:
an-lee
2024-04-10 11:54:28 +08:00
committed by GitHub
parent 5b87d218ac
commit 7dfd47bb6d
7 changed files with 163 additions and 140 deletions

View File

@@ -0,0 +1,129 @@
import { t } from "i18next";
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
Button,
toast,
} from "@renderer/components/ui";
import { HotKeysSettingsProviderContext } from "@renderer/context";
import { useContext, useMemo, useEffect } from "react";
export const HotkeysSettings = ({
open,
name,
keyName,
onOpenChange,
}: {
open: boolean;
name: string;
keyName: string;
onOpenChange: (open: boolean) => void;
}) => {
const {
changeHotkey,
currentHotkeys,
recordingHotkeys,
resetRecordingHotkeys,
startRecordingHotkeys,
stopRecordingHotkeys,
isRecording,
} = useContext(HotKeysSettingsProviderContext);
const joinedKeys = useMemo(
() => [...recordingHotkeys].join("+"),
[recordingHotkeys]
);
const changeKeyMap = async () => {
const ret = (await changeHotkey(keyName, recordingHotkeys)) as unknown as {
error: "conflict" | "invalid";
data: string | string[];
input: string;
};
stopRecordingHotkeys();
const { error, data, input } = ret ?? {};
if (error === "conflict") {
toast.error(
t("customizeShortcutsConflictToast", {
input,
otherHotkeyName: (data as string[])
.map((str) => t(str.charAt(0).toLowerCase() + str.slice(1)))
.join(","),
})
);
} else if (error === "invalid") {
toast.error(t("customizeShortcutsInvalidToast"));
} else {
toast.success(t("customizeShortcutsUpdated"));
onOpenChange(false);
}
};
const reset = () => {
stopRecordingHotkeys();
resetRecordingHotkeys();
};
// ensure recording disabled when dialog close
useEffect(() => {
return () => {
stopRecordingHotkeys();
};
}, [open]);
return (
<AlertDialog open={open} onOpenChange={onOpenChange}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{name}</AlertDialogTitle>
</AlertDialogHeader>
<div>
{isRecording ? (
<div className="">
<div className="flex justify-center mb-4">
<Button variant="secondary">
{joinedKeys.length > 0 ? (
<span className="text-sm">{joinedKeys}</span>
) : (
<span className="font-mono">-</span>
)}
</Button>
</div>
<div className="py-2 text-center text-sm text-muted-foreground">
{t("customizeShortcutsRecordingTip")}
</div>
</div>
) : (
<div className="">
<div className="flex justify-center mb-4">
<Button
variant="outline"
className="font-mono"
onClick={() => {
startRecordingHotkeys();
}}
>
{currentHotkeys[keyName]}
</Button>
</div>
<div className="py-2 text-center text-sm text-muted-foreground">
{t("customizeShortcutsTip")}
</div>
</div>
)}
</div>
<AlertDialogFooter>
<Button disabled={!isRecording || !joinedKeys} onClick={changeKeyMap}>
{t("save")}
</Button>
<AlertDialogCancel onClick={reset}>{t("cancel")}</AlertDialogCancel>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};

View File

@@ -1,8 +1,10 @@
import { t } from "i18next";
import { Separator } from "@renderer/components/ui";
import { HotKeysSettingsProviderContext, Hotkey } from "@/renderer/context";
import {
Separator,
} from "@renderer/components/ui";
import { HotKeysSettingsProviderContext, Hotkey } from "@renderer/context";
import { HotkeysSettings } from "@renderer/components";
import { useContext, useState } from "react";
import { ChangeHotkeyDialog } from "../change-hotkey-dialog";
export const Hotkeys = () => {
const [open, setOpen] = useState(false);
@@ -10,27 +12,15 @@ export const Hotkeys = () => {
name: string;
keyName: string;
} | null>(null);
const {
currentHotkeys,
startRecordingHotkeys,
stopRecordingHotkeys,
} = useContext(HotKeysSettingsProviderContext);
const { currentHotkeys } = useContext(HotKeysSettingsProviderContext);
const commandOrCtrl = navigator.platform.includes("Mac") ? "Cmd" : "Ctrl";
const handleItemSelected = (item: { name: string; keyName: Hotkey }) => {
setOpen(true);
startRecordingHotkeys();
setSelectedItem(item);
};
const handleOpenChange = (open: boolean) => {
setOpen(open);
if (!open) {
stopRecordingHotkeys();
}
};
return (
<>
<div className="font-semibold mb-4 capitilized">{t("hotkeys")}</div>
@@ -39,8 +29,8 @@ export const Hotkeys = () => {
<div className="flex items-center justify-between py-4">
<div className="flex items-center space-x-2">{t("quitApp")}</div>
<kbd className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-not-allowed">
{commandOrCtrl} + Q
<kbd className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-not-allowed capitalize">
{commandOrCtrl}+Q
</kbd>
</div>
@@ -53,11 +43,11 @@ export const Hotkeys = () => {
<kbd
onClick={() =>
handleItemSelected({
name: "Open preferences",
name: t("openPreferences"),
keyName: "OpenPreferences",
})
}
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer"
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer capitalize"
>
{currentHotkeys.OpenPreferences}
</kbd>
@@ -77,7 +67,7 @@ export const Hotkeys = () => {
keyName: "PlayOrPause",
})
}
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer"
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer capitalize"
>
{currentHotkeys.PlayOrPause}
</kbd>
@@ -96,7 +86,7 @@ export const Hotkeys = () => {
keyName: "StartOrStopRecording",
})
}
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer"
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer capitalize"
>
{currentHotkeys.StartOrStopRecording}
</kbd>
@@ -115,7 +105,7 @@ export const Hotkeys = () => {
keyName: "PlayOrPauseRecording",
})
}
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer"
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer capitalize"
>
{currentHotkeys.PlayOrPauseRecording}
</kbd>
@@ -153,7 +143,7 @@ export const Hotkeys = () => {
keyName: "PlayNextSegment",
})
}
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer"
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer capitalize"
>
{currentHotkeys.PlayNextSegment}
</kbd>
@@ -172,7 +162,7 @@ export const Hotkeys = () => {
keyName: "Compare",
})
}
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer"
className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground cursor-pointer capitalize"
>
{currentHotkeys.Compare}
</kbd>
@@ -181,12 +171,12 @@ export const Hotkeys = () => {
<Separator />
</div>
<ChangeHotkeyDialog
<HotkeysSettings
open={open}
keyName={selectedItem?.keyName}
name={selectedItem?.name}
onOpenChange={handleOpenChange}
onOpenChange={setOpen}
/>
</>
);
};
};

View File

@@ -1,6 +1,8 @@
export * from "./preferences";
export * from "./about";
export * from "./hotkeys";
export * from "./hotkeys-settings";
export * from "./default-engine-settings";
export * from "./openai-settings";