diff --git a/enjoy/src/i18n/en.json b/enjoy/src/i18n/en.json
index 6a9b0d12..fd137187 100644
--- a/enjoy/src/i18n/en.json
+++ b/enjoy/src/i18n/en.json
@@ -523,7 +523,8 @@
"AiTranslate": "AI translate",
"cambridgeDictionary": "Cambridge dictionary",
"customizeShortcuts": "Customize shortcuts",
- "customizeShortcutsTip":"Press any sequence of keys to set a shortcut",
+ "customizeShortcutsTip":"Click to change",
+ "customizeShortcutsRecordingTip":"Recording new shortcut",
"customizeShortcutsInvalidToast": "Your shortcut should only have one modifier (Ctrl, Alt, Shift, or Meta) and one key, like 'Ctrl+C'.",
"customizeShortcutsConflictToast": "{{input}} conflicts with the existing {{otherHotkeyName}} shortcut.",
"customizeShortcutsUpdated": "Changes saved",
diff --git a/enjoy/src/i18n/zh-CN.json b/enjoy/src/i18n/zh-CN.json
index 22a1c115..5e15d3d4 100644
--- a/enjoy/src/i18n/zh-CN.json
+++ b/enjoy/src/i18n/zh-CN.json
@@ -522,9 +522,10 @@
"AiTranslate": "智能翻译",
"cambridgeDictionary": "剑桥词典",
"customizeShortcuts": "自定义快捷键",
- "customizeShortcutsTip":"按任意键序列设置快捷键",
- "customizeShortcutsInvalidToast":"快捷键应最多含一个修饰键(Ctrl、Alt、Shift 或 Meta)和一个键,如 'Ctrl+C'",
- "customizeShortcutsConflictToast": "{{input}}和已有{{otherHotkeyName}}的键位冲突了",
+ "customizeShortcutsTip":"点击重新录制",
+ "customizeShortcutsRecordingTip":"正在录制快捷键",
+ "customizeShortcutsInvalidToast":"快捷键应最多含一个修饰键(Ctrl, Alt, Shift 或 Meta)和一个键,如 'Ctrl+C'",
+ "customizeShortcutsConflictToast": "{{input}} 和已有 {{otherHotkeyName}} 的键位冲突了",
"customizeShortcutsUpdated": "设置成功",
"following": "关注中",
"followers": "被关注",
diff --git a/enjoy/src/renderer/components/change-hotkey-dialog.tsx b/enjoy/src/renderer/components/change-hotkey-dialog.tsx
deleted file mode 100644
index d016f357..00000000
--- a/enjoy/src/renderer/components/change-hotkey-dialog.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import {
- AlertDialog,
- AlertDialogAction,
- AlertDialogContent,
- AlertDialogFooter,
- AlertDialogHeader,
- AlertDialogTitle,
-} from "@renderer/components/ui";
-import { toast } from "@renderer/components/ui";
-import { useContext, useMemo } from "react";
-import { HotKeysSettingsProviderContext } from "../context";
-import { CheckIcon, KeyboardIcon, XIcon } from "lucide-react";
-import { t } from "i18next";
-
-export const ChangeHotkeyDialog = ({
- open,
- name,
- keyName,
- onOpenChange,
-}: {
- open: boolean;
- name: string;
- keyName: string;
- onOpenChange: (open: boolean) => void;
-}) => {
- const {
- changeHotkey,
- currentHotkeys,
- recordingHotkeys,
- resetRecordingHotkeys,
- } = 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;
- };
- const { error, data, input } = ret ?? {};
- if (error === "conflict") {
- toast.error(
- t("customizeShortcutsConflictToast", {
- input,
- otherHotkeyName: (data as string[]).join(","),
- })
- );
- } else if (error === "invalid") {
- toast.error(t("customizeShortcutsInvalidToast"));
- } else {
- toast.success(t("customizeShortcutsUpdated"));
- }
- };
-
- const clear = () => {
- resetRecordingHotkeys();
- };
-
- return (
-
-
-
- {t("customizeShortcuts")}
-
-
-
{name}
-
-
- {currentHotkeys[keyName]}
-
- {joinedKeys.length > 0 ? (
-
-
- {joinedKeys}
-
-
-
-
-
-
-
-
- ) : (
-
- {t("customizeShortcutsTip")}
-
-
- )}
-
-
-
- Close
-
-
-
- );
-};
diff --git a/enjoy/src/renderer/components/preferences/hotkeys-settings.tsx b/enjoy/src/renderer/components/preferences/hotkeys-settings.tsx
new file mode 100644
index 00000000..4352c6ac
--- /dev/null
+++ b/enjoy/src/renderer/components/preferences/hotkeys-settings.tsx
@@ -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 (
+
+
+
+ {name}
+
+
+ {isRecording ? (
+
+
+
+
+
+ {t("customizeShortcutsRecordingTip")}
+
+
+ ) : (
+
+
+
+
+
+ {t("customizeShortcutsTip")}
+
+
+ )}
+
+
+
+ {t("cancel")}
+
+
+
+ );
+};
diff --git a/enjoy/src/renderer/components/preferences/hotkeys.tsx b/enjoy/src/renderer/components/preferences/hotkeys.tsx
index 604d872a..1e997cf8 100644
--- a/enjoy/src/renderer/components/preferences/hotkeys.tsx
+++ b/enjoy/src/renderer/components/preferences/hotkeys.tsx
@@ -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 (
<>
{t("hotkeys")}
@@ -39,8 +29,8 @@ export const Hotkeys = () => {
{t("quitApp")}
-
- {commandOrCtrl} + Q
+
+ {commandOrCtrl}+Q
@@ -53,11 +43,11 @@ export const Hotkeys = () => {
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}
@@ -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}
@@ -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}
@@ -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}
@@ -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}
@@ -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}
@@ -181,12 +171,12 @@ export const Hotkeys = () => {
-
>
);
-};
+};
\ No newline at end of file
diff --git a/enjoy/src/renderer/components/preferences/index.ts b/enjoy/src/renderer/components/preferences/index.ts
index 6ba224ee..4fa9c13b 100644
--- a/enjoy/src/renderer/components/preferences/index.ts
+++ b/enjoy/src/renderer/components/preferences/index.ts
@@ -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";
diff --git a/enjoy/src/renderer/context/hotkeys-settings-provider.tsx b/enjoy/src/renderer/context/hotkeys-settings-provider.tsx
index 943b1687..9c664673 100644
--- a/enjoy/src/renderer/context/hotkeys-settings-provider.tsx
+++ b/enjoy/src/renderer/context/hotkeys-settings-provider.tsx
@@ -47,11 +47,11 @@ const defaultKeyMap = {
OpenPreferences: `${ControlOrCommand}+Comma`,
// player
PlayOrPause: "Space",
- StartOrStopRecording: "r",
- PlayOrPauseRecording: `${ControlOrCommand}+r`,
- PlayPreviousSegment: "p",
- PlayNextSegment: "n",
- Compare: "c",
+ StartOrStopRecording: "R",
+ PlayOrPauseRecording: `${ControlOrCommand}+R`,
+ PlayPreviousSegment: "P",
+ PlayNextSegment: "N",
+ Compare: "C",
// dev tools
OpenDevTools: `${ControlOrCommand}+Shift+I`,
};
@@ -76,6 +76,7 @@ type HotkeysSettingsProviderState = {
currentHotkeys: Record;
recordingHotkeys?: any;
enabled: boolean;
+ isRecording: boolean;
startRecordingHotkeys?: () => void;
stopRecordingHotkeys?: () => void;
resetRecordingHotkeys?: () => void;
@@ -85,6 +86,7 @@ type HotkeysSettingsProviderState = {
const initialState: HotkeysSettingsProviderState = {
currentHotkeys: {},
enabled: true,
+ isRecording: false,
};
export const HotKeysSettingsProviderContext = createContext<
@@ -215,6 +217,7 @@ export const HotKeysSettingsProvider = ({
currentHotkeys,
recordingHotkeys: keys,
enabled: !isRecording,
+ isRecording,
startRecordingHotkeys,
stopRecordingHotkeys,
resetRecordingHotkeys: resetKeys,