Skip to content

Commit

Permalink
Refactor hotkey setting UI (#506)
Browse files Browse the repository at this point in the history
* refactor hotkeys setting

* update UI

* refactor

* fix toast
  • Loading branch information
an-lee committed Apr 10, 2024
1 parent 5b87d21 commit 7dfd47b
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 140 deletions.
3 changes: 2 additions & 1 deletion enjoy/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
7 changes: 4 additions & 3 deletions enjoy/src/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "被关注",
Expand Down
103 changes: 0 additions & 103 deletions enjoy/src/renderer/components/change-hotkey-dialog.tsx

This file was deleted.

129 changes: 129 additions & 0 deletions enjoy/src/renderer/components/preferences/hotkeys-settings.tsx
Original file line number Diff line number Diff line change
@@ -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>
);
};
46 changes: 18 additions & 28 deletions enjoy/src/renderer/components/preferences/hotkeys.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,26 @@
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);
const [selectedItem, setSelectedItem] = useState<{
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>
Expand All @@ -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>

Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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>
Expand All @@ -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>
Expand All @@ -181,12 +171,12 @@ export const Hotkeys = () => {
<Separator />
</div>

<ChangeHotkeyDialog
<HotkeysSettings
open={open}
keyName={selectedItem?.keyName}
name={selectedItem?.name}
onOpenChange={handleOpenChange}
onOpenChange={setOpen}
/>
</>
);
};
};
2 changes: 2 additions & 0 deletions enjoy/src/renderer/components/preferences/index.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
Loading

0 comments on commit 7dfd47b

Please sign in to comment.