shortcuts dev

This commit is contained in:
Gabe Yuan
2023-09-07 23:47:24 +08:00
parent d8b0cc4834
commit 3b9b404482
7 changed files with 15389 additions and 10898 deletions

View File

@@ -494,15 +494,15 @@ export const I18N = {
en: `Shortcuts Setting`, en: `Shortcuts Setting`,
}, },
toggle_translate_shortcut: { toggle_translate_shortcut: {
zh: `开启翻译快捷键`, zh: `"开启翻译"快捷键`,
en: `Toggle Translate Shortcut`, en: `"Toggle Translate" Shortcut`,
}, },
toggle_style_shortcut: { toggle_style_shortcut: {
zh: `切换样式快捷键`, zh: `"切换样式"快捷键`,
en: `Toggle Style Shortcut`, en: `"Toggle Style" Shortcut`,
}, },
toggle_popup_shortcut: { toggle_popup_shortcut: {
zh: `打开弹窗快捷键`, zh: `"打开弹窗"快捷键`,
en: `Open Popup Shortcut`, en: `"Open Popup" Shortcut`,
}, },
}; };

View File

@@ -4,21 +4,21 @@ import { useSetting } from "./Setting";
export function useApi(translator) { export function useApi(translator) {
const { setting, updateSetting } = useSetting(); const { setting, updateSetting } = useSetting();
const apis = setting?.transApis || DEFAULT_TRANS_APIS; const transApis = setting?.transApis || DEFAULT_TRANS_APIS;
const updateApi = useCallback( const updateApi = useCallback(
async (obj) => { async (obj) => {
const api = apis[translator] || {}; const api = transApis[translator] || {};
const transApis = { ...apis, [translator]: { ...api, ...obj } }; Object.assign(transApis, { [translator]: { ...api, ...obj } });
await updateSetting({ transApis }); await updateSetting({ transApis });
}, },
[translator, apis, updateSetting] [translator, transApis, updateSetting]
); );
const resetApi = useCallback(async () => { const resetApi = useCallback(async () => {
const transApis = { ...apis, [translator]: DEFAULT_TRANS_APIS[translator] }; Object.assign(transApis, { [translator]: DEFAULT_TRANS_APIS[translator] });
await updateSetting({ transApis }); await updateSetting({ transApis });
}, [translator, apis, updateSetting]); }, [translator, transApis, updateSetting]);
return { api: apis[translator] || {}, updateApi, resetApi }; return { api: transApis[translator] || {}, updateApi, resetApi };
} }

View File

@@ -8,12 +8,8 @@ export function useShortcut(action) {
const setShortcut = useCallback( const setShortcut = useCallback(
async (val) => { async (val) => {
await updateSetting({ Object.assign(shortcuts, { [action]: val });
shortcuts: { await updateSetting({ shortcuts });
...shortcuts,
[action]: val,
},
});
}, },
[action, shortcuts, updateSetting] [action, shortcuts, updateSetting]
); );

49
src/libs/shortcut.js Normal file
View File

@@ -0,0 +1,49 @@
import { isSameSet } from "./utils";
/**
* 键盘快捷键监听
* @param {*} fn
* @param {*} target
* @returns
*/
export const shortcutListener = (fn, target = document) => {
const allkeys = new Set();
const curkeys = new Set();
const handleKeydown = (e) => {
if (e.code) {
allkeys.add(e.key);
curkeys.add(e.key);
}
};
const handleKeyup = (e) => {
curkeys.delete(e.key);
if (curkeys.size === 0) {
fn([...allkeys]);
allkeys.clear();
}
};
target.addEventListener("keydown", handleKeydown);
target.addEventListener("keyup", handleKeyup);
return () => {
target.removeEventListener("keydown", handleKeydown);
target.removeEventListener("keyup", handleKeyup);
};
};
/**
* 注册键盘快捷键
* @param {*} targetKeys
* @param {*} fn
* @param {*} target
* @returns
*/
export const shortcutRegister = (targetKeys, fn, target = document) => {
return shortcutListener((keys) => {
if (isSameSet(new Set(targetKeys), new Set(keys))) {
fn();
}
}, target);
};

View File

@@ -6,10 +6,16 @@ import Draggable from "./Draggable";
import { useEffect, useState, useMemo, useCallback } from "react"; import { useEffect, useState, useMemo, useCallback } from "react";
import { SettingProvider } from "../../hooks/Setting"; import { SettingProvider } from "../../hooks/Setting";
import Popup from "../Popup"; import Popup from "../Popup";
import { debounce, isSameSet } from "../../libs/utils"; import { debounce } from "../../libs/utils";
import { isGm } from "../../libs/client"; import { isGm } from "../../libs/client";
import Header from "../Popup/Header"; import Header from "../Popup/Header";
import { DEFAULT_SHORTCUTS, OPT_SHORTCUT_TRANSLATE } from "../../config"; import {
DEFAULT_SHORTCUTS,
OPT_SHORTCUT_TRANSLATE,
OPT_SHORTCUT_STYLE,
OPT_SHORTCUT_POPUP,
} from "../../config";
import { shortcutRegister } from "../../libs/shortcut";
export default function Action({ translator, fab }) { export default function Action({ translator, fab }) {
const fabWidth = 40; const fabWidth = 40;
@@ -43,55 +49,27 @@ export default function Action({ translator, fab }) {
setMoved(true); setMoved(true);
}, []); }, []);
// useEffect(() => {
// // 注册快捷键
// const handleKeydown = (e) => {
// if (!e.altKey) {
// return;
// }
// if (e.code === "KeyQ") {
// translator.toggle();
// setShowPopup(false);
// } else if (e.code === "KeyC") {
// translator.toggleStyle();
// setShowPopup(false);
// } else if (e.code === "KeyK") {
// setShowPopup((pre) => !pre);
// }
// };
// window.addEventListener("keydown", handleKeydown);
// return () => {
// window.removeEventListener("keydown", handleKeydown);
// };
// }, [translator]);
useEffect(() => { useEffect(() => {
// 注册快捷键 // 注册快捷键
const shortcuts = translator.setting.shortcuts || DEFAULT_SHORTCUTS; const shortcuts = translator.setting.shortcuts || DEFAULT_SHORTCUTS;
const keys = new Set(); const clearShortcuts = [
shortcutRegister(shortcuts[OPT_SHORTCUT_TRANSLATE], () => {
translator.toggle();
setShowPopup(false);
}),
shortcutRegister(shortcuts[OPT_SHORTCUT_STYLE], () => {
translator.toggleStyle();
setShowPopup(false);
}),
shortcutRegister(shortcuts[OPT_SHORTCUT_POPUP], () => {
setShowPopup((pre) => !pre);
}),
];
const handleKeydown = (e) => {
console.log("keydown", e);
e.code && keys.add(e.key);
console.log("keys", keys);
const isSame = isSameSet(
keys,
new Set(shortcuts[OPT_SHORTCUT_TRANSLATE])
);
console.log("isSame", keys, isSame);
};
const handleKeyup = (e) => {
console.log("keyup", e);
keys.delete(e.key);
};
window.addEventListener("keydown", handleKeydown);
window.addEventListener("keyup", handleKeyup);
return () => { return () => {
window.removeEventListener("keydown", handleKeydown); clearShortcuts.forEach((fn) => {
window.removeEventListener("keyup", handleKeyup); fn();
});
}; };
}, [translator]); }, [translator]);

View File

@@ -27,44 +27,29 @@ import {
} from "../../config"; } from "../../config";
import { useEffect, useState, useRef } from "react"; import { useEffect, useState, useRef } from "react";
import { useShortcut } from "../../hooks/Shortcut"; import { useShortcut } from "../../hooks/Shortcut";
import { shortcutListener } from "../../libs/shortcut";
function ShortcutItem({ action, label }) { function ShortcutItem({ action, label }) {
const { shortcut, setShortcut } = useShortcut(action); const { shortcut, setShortcut } = useShortcut(action);
const [disabled, setDisabled] = useState(true); const [disabled, setDisabled] = useState(true);
const [focused, setFocus] = useState(false);
const [formval, setFormval] = useState(shortcut);
const inputRef = useRef(null); const inputRef = useRef(null);
useEffect(() => { useEffect(() => {
if (!disabled) { if (disabled) {
inputRef.current.focus();
setFormval([]);
}
}, [disabled]);
useEffect(() => {
if (!focused) {
return; return;
} }
const keys = new Set(); inputRef.current.focus();
const handleKeydown = (e) => { setShortcut([]);
// console.log("keydown", e);
e.code && keys.add(e.key); const clearShortcut = shortcutListener((keys) => {
setFormval([...keys]); setShortcut(keys);
}; }, inputRef.current);
const handleKeyup = (e) => {
// console.log("keyup", e);
keys.delete(e.key);
};
window.addEventListener("keydown", handleKeydown);
window.addEventListener("keyup", handleKeyup);
return () => { return () => {
window.removeEventListener("keydown", handleKeydown); clearShortcut();
window.removeEventListener("keyup", handleKeyup);
}; };
}, [focused]); }, [disabled, setShortcut]);
return ( return (
<Stack direction="row"> <Stack direction="row">
@@ -72,17 +57,12 @@ function ShortcutItem({ action, label }) {
size="small" size="small"
label={label} label={label}
name={label} name={label}
value={formval.join(" + ")} value={shortcut.join(" + ")}
fullWidth fullWidth
inputRef={inputRef} inputRef={inputRef}
disabled={disabled} disabled={disabled}
onFocus={(e) => { onBlur={() => {
setFocus(true);
}}
onBlur={(e) => {
setFocus(false);
setDisabled(true); setDisabled(true);
setShortcut(formval);
}} }}
/> />
<IconButton <IconButton

26090
yarn.lock

File diff suppressed because it is too large Load Diff