Files
kiss-translator/src/views/Action/index.js

226 lines
5.5 KiB
JavaScript
Raw Normal View History

2023-08-05 23:56:16 +08:00
import Fab from "@mui/material/Fab";
2023-08-08 14:58:36 +08:00
import TranslateIcon from "@mui/icons-material/Translate";
2023-08-05 23:56:16 +08:00
import ThemeProvider from "../../hooks/Theme";
2023-08-06 21:12:01 +08:00
import Draggable from "./Draggable";
import { useEffect, useState, useMemo, useCallback } from "react";
2023-08-30 18:05:37 +08:00
import { SettingProvider } from "../../hooks/Setting";
2023-08-06 21:12:01 +08:00
import Popup from "../Popup";
2023-09-07 23:47:24 +08:00
import { debounce } from "../../libs/utils";
2023-09-02 13:14:27 +08:00
import { isGm } from "../../libs/client";
2023-09-04 22:03:17 +08:00
import Header from "../Popup/Header";
2023-09-12 11:00:54 +08:00
import Box from "@mui/material/Box";
import Divider from "@mui/material/Divider";
2023-09-07 23:47:24 +08:00
import {
DEFAULT_SHORTCUTS,
OPT_SHORTCUT_TRANSLATE,
OPT_SHORTCUT_STYLE,
OPT_SHORTCUT_POPUP,
2023-09-09 15:08:34 +08:00
OPT_SHORTCUT_SETTING,
2023-09-17 20:45:05 +08:00
MSG_TRANS_TOGGLE,
MSG_TRANS_TOGGLE_STYLE,
2023-09-07 23:47:24 +08:00
} from "../../config";
import { shortcutRegister } from "../../libs/shortcut";
2023-09-17 20:45:05 +08:00
import { sendIframeMsg } from "../../libs/iframe";
2023-08-05 23:56:16 +08:00
2023-08-16 22:38:58 +08:00
export default function Action({ translator, fab }) {
2023-08-16 17:36:22 +08:00
const fabWidth = 40;
2023-08-06 21:12:01 +08:00
const [showPopup, setShowPopup] = useState(false);
const [windowSize, setWindowSize] = useState({
w: window.innerWidth,
h: window.innerHeight,
2023-08-06 21:12:01 +08:00
});
const [moved, setMoved] = useState(false);
2023-08-16 22:13:07 +08:00
const handleWindowResize = useMemo(
() =>
debounce(() => {
setWindowSize({
w: window.innerWidth,
h: window.innerHeight,
2023-08-16 22:13:07 +08:00
});
}),
[]
);
2023-08-06 21:12:01 +08:00
const handleWindowClick = (e) => {
setShowPopup(false);
};
const handleStart = useCallback(() => {
setMoved(false);
}, []);
const handleMove = useCallback(() => {
setMoved(true);
}, []);
2023-09-02 13:14:27 +08:00
useEffect(() => {
2023-09-23 19:16:51 +08:00
if (!isGm) {
return;
}
2023-09-02 13:14:27 +08:00
// 注册快捷键
2023-09-07 18:12:45 +08:00
const shortcuts = translator.setting.shortcuts || DEFAULT_SHORTCUTS;
2023-09-07 23:47:24 +08:00
const clearShortcuts = [
shortcutRegister(shortcuts[OPT_SHORTCUT_TRANSLATE], () => {
translator.toggle();
2023-09-17 20:45:05 +08:00
sendIframeMsg(MSG_TRANS_TOGGLE);
2023-09-07 23:47:24 +08:00
setShowPopup(false);
}),
shortcutRegister(shortcuts[OPT_SHORTCUT_STYLE], () => {
translator.toggleStyle();
2023-09-17 20:45:05 +08:00
sendIframeMsg(MSG_TRANS_TOGGLE_STYLE);
2023-09-07 23:47:24 +08:00
setShowPopup(false);
}),
shortcutRegister(shortcuts[OPT_SHORTCUT_POPUP], () => {
setShowPopup((pre) => !pre);
}),
2023-09-09 15:08:34 +08:00
shortcutRegister(shortcuts[OPT_SHORTCUT_SETTING], () => {
window.open(process.env.REACT_APP_OPTIONSPAGE, "_blank");
}),
2023-09-07 23:47:24 +08:00
];
2023-09-02 13:14:27 +08:00
return () => {
2023-09-07 23:47:24 +08:00
clearShortcuts.forEach((fn) => {
fn();
});
2023-09-02 13:14:27 +08:00
};
}, [translator]);
useEffect(() => {
2023-09-12 17:20:56 +08:00
if (!isGm) {
return;
2023-09-02 13:14:27 +08:00
}
2023-09-12 17:20:56 +08:00
// 注册菜单
try {
const menuCommandIds = [];
menuCommandIds.push(
GM.registerMenuCommand(
"Toggle Translate (Alt+q)",
(event) => {
translator.toggle();
2023-09-17 20:45:05 +08:00
sendIframeMsg(MSG_TRANS_TOGGLE);
2023-09-12 17:20:56 +08:00
setShowPopup(false);
},
"Q"
),
GM.registerMenuCommand(
"Toggle Style (Alt+c)",
(event) => {
translator.toggleStyle();
2023-09-17 20:45:05 +08:00
sendIframeMsg(MSG_TRANS_TOGGLE_STYLE);
2023-09-12 17:20:56 +08:00
setShowPopup(false);
},
"C"
),
GM.registerMenuCommand(
"Open Menu (Alt+k)",
(event) => {
setShowPopup((pre) => !pre);
},
"K"
),
GM.registerMenuCommand(
"Open Setting (Alt+o)",
(event) => {
window.open(process.env.REACT_APP_OPTIONSPAGE, "_blank");
},
"O"
)
);
return () => {
menuCommandIds.forEach((id) => {
GM.unregisterMenuCommand(id);
});
};
} catch (err) {
console.log("[registerMenuCommand]", err);
}
2023-09-02 13:14:27 +08:00
}, [translator]);
2023-08-06 21:12:01 +08:00
useEffect(() => {
window.addEventListener("resize", handleWindowResize);
return () => {
window.removeEventListener("resize", handleWindowResize);
2023-08-16 22:13:07 +08:00
};
}, [handleWindowResize]);
useEffect(() => {
window.addEventListener("click", handleWindowClick);
2023-09-02 13:14:27 +08:00
2023-08-16 22:13:07 +08:00
return () => {
2023-08-06 21:12:01 +08:00
window.removeEventListener("click", handleWindowClick);
};
}, []);
const popProps = useMemo(() => {
const width = Math.min(windowSize.w, 300);
2023-08-09 22:58:03 +08:00
const height = Math.min(windowSize.h, 442);
2023-08-06 21:12:01 +08:00
const left = (windowSize.w - width) / 2;
const top = (windowSize.h - height) / 2;
return {
windowSize,
width,
height,
left,
top,
};
}, [windowSize]);
const fabProps = {
windowSize,
width: fabWidth,
height: fabWidth,
2023-09-12 15:44:30 +08:00
left: fab.x ?? -fabWidth,
2023-08-16 22:38:58 +08:00
top: fab.y ?? windowSize.h / 2,
2023-08-06 21:12:01 +08:00
};
2023-08-05 23:56:16 +08:00
return (
2023-08-30 18:05:37 +08:00
<SettingProvider>
2023-08-06 21:12:01 +08:00
<ThemeProvider>
2023-08-08 14:58:36 +08:00
<Draggable
key="pop"
{...popProps}
show={showPopup}
onStart={handleStart}
onMove={handleMove}
2023-09-12 11:00:54 +08:00
usePaper
2023-08-08 14:58:36 +08:00
handler={
2023-09-12 11:00:54 +08:00
<Box style={{ cursor: "move" }}>
2023-09-04 22:03:17 +08:00
<Header setShowPopup={setShowPopup} />
2023-09-12 11:00:54 +08:00
<Divider />
</Box>
2023-08-08 14:58:36 +08:00
}
>
2023-09-12 11:00:54 +08:00
{showPopup && (
<Popup setShowPopup={setShowPopup} translator={translator} />
)}
2023-08-08 14:58:36 +08:00
</Draggable>
<Draggable
key="fab"
2023-08-16 17:36:22 +08:00
snapEdge
2023-08-08 14:58:36 +08:00
{...fabProps}
2023-09-23 19:16:51 +08:00
show={fab.isHide ? false : !showPopup}
2023-08-08 14:58:36 +08:00
onStart={handleStart}
onMove={handleMove}
handler={
<Fab
2023-08-16 17:36:22 +08:00
size="small"
2023-08-08 14:58:36 +08:00
color="primary"
onClick={(e) => {
if (!moved) {
setShowPopup((pre) => !pre);
}
}}
>
<TranslateIcon />
</Fab>
}
/>
2023-08-06 21:12:01 +08:00
</ThemeProvider>
2023-08-30 18:05:37 +08:00
</SettingProvider>
2023-08-05 23:56:16 +08:00
);
}