Skip to content

Commit

Permalink
feat(web): optimize hotkey function (#604)
Browse files Browse the repository at this point in the history
* feat(web): optimize hotkey function
  • Loading branch information
kongwy229 authored Jan 6, 2023
1 parent caa2a5d commit f429c2a
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 32 deletions.
60 changes: 33 additions & 27 deletions web/src/hooks/useHotKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useRef } from "react";

import { formatHotKeyModifier } from "@/utils/format";
import { getWhiteList, stringToCode } from "@/utils/hotKeyMap";
function useHotKey(
keyMap: string[],
trigger: () => void,
Expand All @@ -10,54 +10,60 @@ function useHotKey(
enabled: true,
},
) {
const pressKey = useRef<any>(null);
const timeout = useRef<any>(null);
const downKeys = useRef<Set<Number>>(new Set());
const upKeys = useRef<Set<Number>>(new Set());

const handleKeyDown = useCallback(
(event: any) => {
if (event.repeat) {
return;
}
if (keyMap.indexOf(event.key) > -1 && (event.ctrlKey || event.metaKey)) {
if ((event.ctrlKey || event.metaKey) && getWhiteList().indexOf(event.keyCode) !== -1) {
event.preventDefault();
pressKey.current = event.key;
if (timeout.current === null) {
timeout.current = setTimeout(() => {
// trigger the event if there is no change within 100ms
if (pressKey.current === event.key) {
trigger();
}
clearTimeout(timeout.current);
timeout.current = null;
pressKey.current = null;
}, 100);
}
downKeys.current.add(event.keyCode);
},
[downKeys],
);

const handleKeyUp = useCallback(
(event: any) => {
upKeys.current.add(event.keyCode);
const size = downKeys.current.size;
if (upKeys.current.size >= size) {
let isMatch = false;
for (let i = 0; i < keyMap.length && !isMatch; i++) {
const targetKey = keyMap[i].split("+").map((item) => stringToCode(item));
if (targetKey.length !== size) continue;
let count = size;
for (let item of targetKey) {
if (downKeys.current.has(item)) count--;
}
isMatch = count === 0;
}
if (isMatch) {
trigger();
}
downKeys.current.clear();
upKeys.current.clear();
}
},
[keyMap, trigger],
[keyMap, trigger, downKeys, upKeys],
);

useEffect(() => {
// attach the event listener
if (config?.enabled) {
document.addEventListener("keydown", handleKeyDown);
document.addEventListener("keyup", handleKeyUp);
}

// remove the event listener
return () => {
document.removeEventListener("keydown", handleKeyDown);
document.removeEventListener("keyup", handleKeyUp);
};
}, [config?.enabled, handleKeyDown]);

// return shortcut key text ,if keyMap has more than two items will format [../..]
const res = `${formatHotKeyModifier()} +
${
keyMap.length > 1
? "[" + keyMap.map((item) => item.toUpperCase()).join("/") + "]"
: keyMap[0].toUpperCase()
}`;

return res;
}, [config?.enabled, handleKeyDown, handleKeyUp]);
}

export default useHotKey;
2 changes: 1 addition & 1 deletion web/src/pages/app/functions/mods/DebugPannel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function DebugPanel() {
const [params, setParams] = useState(JSON.stringify({ name: "test" }, null, 2));

useHotKey(
["r", "s"],
[`${formatHotKeyModifier()}+r`, `${formatHotKeyModifier()}+s`],
() => {
runningCode();
},
Expand Down
7 changes: 4 additions & 3 deletions web/src/pages/app/functions/mods/DeployButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { t } from "i18next";

import CommonDiffEditor from "@/components/Editor/CommonDiffEditor";
import { Pages } from "@/constants";
import { formatHotKeyModifier } from "@/utils/format";

import { useUpdateFunctionMutation } from "../../service";
import useFunctionStore from "../../store";
Expand All @@ -30,8 +31,8 @@ export default function DeployButton() {

const updateFunctionMutation = useUpdateFunctionMutation();

const hotKeyP = useHotKey(
["p"],
useHotKey(
[`${formatHotKeyModifier()}+p`],
async () => {
onOpen();
},
Expand Down Expand Up @@ -69,7 +70,7 @@ export default function DeployButton() {
onOpen();
}}
>
{t("FunctionPanel.Deploy")} ({hotKeyP})
{t("FunctionPanel.Deploy")} ({`${formatHotKeyModifier()}+P`})
</Button>

{isOpen ? (
Expand Down
2 changes: 1 addition & 1 deletion web/src/pages/home/mods/CreateAppModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const CreateAppModal = (props: { application?: any; children: React.ReactElement
<Modal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
<ModalContent>
<ModalHeader>新建应用</ModalHeader>
<ModalHeader>{isEdit ? "编辑应用" : "新建应用"}</ModalHeader>
<ModalCloseButton />

<ModalBody pb={6}>
Expand Down
88 changes: 88 additions & 0 deletions web/src/utils/hotKeyMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
let isff =
typeof navigator !== "undefined"
? navigator.userAgent.toLowerCase().indexOf("firefox") > 0
: false; // 绑定事件
let _keyMap: any = {
backspace: 8,
"⌫": 8,
tab: 9,
clear: 12,
enter: 13,
"↩": 13,
return: 13,
esc: 27,
escape: 27,
space: 32,
left: 37,
up: 38,
right: 39,
down: 40,
del: 46,
delete: 46,
ins: 45,
insert: 45,
home: 36,
end: 35,
pageup: 33,
pagedown: 34,
capslock: 20,
num_0: 96,
num_1: 97,
num_2: 98,
num_3: 99,
num_4: 100,
num_5: 101,
num_6: 102,
num_7: 103,
num_8: 104,
num_9: 105,
num_multiply: 106,
num_add: 107,
num_enter: 108,
num_subtract: 109,
num_decimal: 110,
num_divide: 111,
"⇪": 20,
",": 188,
".": 190,
"/": 191,
"`": 192,
"-": isff ? 173 : 189,
"=": isff ? 61 : 187,
";": isff ? 59 : 186,
"'": 222,
"[": 219,
"]": 221,
"\\": 220,
}; // Modifier Keys

const _modifier: any = {
// shiftKey
"⇧": 16,
shift: 16,
// altKey
"⌥": 18,
alt: 18,
option: 18,
// ctrlKey
"⌃": 17,
ctrl: 17,
control: 17,
// metaKey
"⌘": 91,
cmd: 91,
command: 91,
};
for (let k = 1; k < 20; k++) {
// F1~F12 special key
_keyMap["f".concat(k.toString())] = 111 + k;
}

export function stringToCode(x: string) {
return _keyMap[x.toLowerCase()] || _modifier[x.toLowerCase()] || x.toUpperCase().charCodeAt(0);
}

export function getWhiteList() {
const whiteList = ["s", "r", "p"];
return whiteList.map((item: string) => stringToCode(item));
}

0 comments on commit f429c2a

Please sign in to comment.