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

217 lines
5.5 KiB
JavaScript
Raw Normal View History

2024-04-16 12:47:55 +08:00
import { useState, useEffect, useCallback, useMemo } from "react";
2023-10-26 12:24:24 +08:00
import TranBtn from "./TranBtn";
import TranBox from "./TranBox";
2024-01-04 12:18:36 +08:00
import { shortcutRegister } from "../../libs/shortcut";
import { sleep, limitNumber } from "../../libs/utils";
2024-01-04 12:18:36 +08:00
import { isGm, isExt } from "../../libs/client";
2024-04-16 12:47:55 +08:00
import {
MSG_OPEN_TRANBOX,
DEFAULT_TRANBOX_SHORTCUT,
OPT_TRANBOX_TRIGGER_CLICK,
OPT_TRANBOX_TRIGGER_HOVER,
OPT_TRANBOX_TRIGGER_SELECT,
} from "../../config";
import { isMobile } from "../../libs/mobile";
2024-03-19 18:07:18 +08:00
import { kissLog } from "../../libs/log";
2024-04-20 15:54:41 +08:00
import { useLangMap } from "../../hooks/I18n";
2023-10-23 18:02:42 +08:00
2024-02-05 11:28:34 +08:00
export default function Slection({
contextMenuType,
tranboxSetting,
transApis,
2024-04-20 15:54:41 +08:00
uiLang,
2024-02-05 11:28:34 +08:00
}) {
2024-04-16 12:47:55 +08:00
const {
hideTranBtn = false,
simpleStyle: initSimpleStyle = false,
hideClickAway: initHideClickAway = false,
tranboxShortcut = DEFAULT_TRANBOX_SHORTCUT,
triggerMode = OPT_TRANBOX_TRIGGER_CLICK,
2024-04-17 15:35:44 +08:00
extStyles,
2024-04-16 12:47:55 +08:00
} = tranboxSetting;
2024-04-16 00:54:37 +08:00
const boxWidth =
2024-04-16 12:47:55 +08:00
isMobile || initSimpleStyle
2024-04-16 00:54:37 +08:00
? 300
: limitNumber(window.innerWidth, 300, 600);
const boxHeight =
2024-04-16 12:47:55 +08:00
isMobile || initSimpleStyle
2024-04-16 00:54:37 +08:00
? 200
: limitNumber(window.innerHeight, 200, 400);
2024-04-20 15:54:41 +08:00
const langMap = useLangMap(uiLang);
2023-10-23 18:02:42 +08:00
const [showBox, setShowBox] = useState(false);
const [showBtn, setShowBtn] = useState(false);
2023-10-24 17:58:37 +08:00
const [selectedText, setSelText] = useState("");
2023-10-23 18:02:42 +08:00
const [text, setText] = useState("");
const [position, setPosition] = useState({ x: 0, y: 0 });
const [boxSize, setBoxSize] = useState({
w: boxWidth,
h: boxHeight,
});
2023-10-24 17:58:37 +08:00
const [boxPosition, setBoxPosition] = useState({
x: (window.innerWidth - boxWidth) / 2,
y: (window.innerHeight - boxHeight) / 2,
2023-10-24 17:58:37 +08:00
});
2024-04-16 12:47:55 +08:00
const [simpleStyle, setSimpleStyle] = useState(initSimpleStyle);
const [hideClickAway, setHideClickAway] = useState(initHideClickAway);
const handleTrigger = useCallback(
(text) => {
setShowBtn(false);
setText(text || selectedText);
setShowBox(true);
},
[selectedText]
2024-04-16 00:54:37 +08:00
);
2023-10-23 18:02:42 +08:00
const handleTranbox = useCallback(() => {
2023-11-21 11:20:05 +08:00
setShowBtn(false);
2023-11-11 17:22:43 +08:00
2023-10-24 17:58:37 +08:00
const selectedText = window.getSelection()?.toString()?.trim() || "";
if (!selectedText) {
setShowBox((pre) => !pre);
2023-10-24 17:58:37 +08:00
return;
}
setSelText(selectedText);
2023-11-21 11:20:05 +08:00
setText(selectedText);
setShowBox(true);
}, []);
2023-10-23 18:02:42 +08:00
2024-04-16 12:47:55 +08:00
const btnEvent = useMemo(() => {
if (isMobile) {
return "onTouchEnd";
} else if (triggerMode === OPT_TRANBOX_TRIGGER_HOVER) {
return "onMouseOver";
}
return "onMouseUp";
}, [triggerMode]);
2023-11-21 11:20:05 +08:00
useEffect(() => {
async function handleMouseup(e) {
e.stopPropagation();
2024-04-16 12:47:55 +08:00
await sleep(200);
2023-10-24 17:58:37 +08:00
2023-11-21 11:20:05 +08:00
const selectedText = window.getSelection()?.toString()?.trim() || "";
setSelText(selectedText);
if (!selectedText) {
setShowBtn(false);
return;
}
2024-04-16 12:47:55 +08:00
if (triggerMode === OPT_TRANBOX_TRIGGER_SELECT) {
handleTrigger(selectedText);
return;
}
2024-04-16 00:54:37 +08:00
const { clientX, clientY } = isMobile ? e.changedTouches[0] : e;
2024-04-16 12:47:55 +08:00
setShowBtn(!hideTranBtn);
2024-04-16 00:54:37 +08:00
setPosition({ x: clientX, y: clientY });
2023-10-23 18:02:42 +08:00
}
2024-01-04 10:39:40 +08:00
// todo: mobile support
2024-04-07 16:55:54 +08:00
// window.addEventListener("mouseup", handleMouseup);
window.addEventListener(isMobile ? "touchend" : "mouseup", handleMouseup);
2023-10-23 18:02:42 +08:00
return () => {
window.removeEventListener(
isMobile ? "touchend" : "mouseup",
handleMouseup
);
2023-10-23 18:02:42 +08:00
};
2024-04-16 12:47:55 +08:00
}, [hideTranBtn, triggerMode, handleTrigger]);
2023-10-23 18:02:42 +08:00
2024-01-04 12:18:36 +08:00
useEffect(() => {
if (isExt) {
return;
}
2024-04-16 12:47:55 +08:00
const clearShortcut = shortcutRegister(tranboxShortcut, handleTranbox);
2024-01-04 12:18:36 +08:00
return () => {
clearShortcut();
};
2024-04-16 12:47:55 +08:00
}, [tranboxShortcut, handleTranbox]);
2024-01-04 12:18:36 +08:00
2023-11-21 11:20:05 +08:00
useEffect(() => {
window.addEventListener(MSG_OPEN_TRANBOX, handleTranbox);
2023-11-21 11:20:05 +08:00
return () => {
window.removeEventListener(MSG_OPEN_TRANBOX, handleTranbox);
2023-11-21 11:20:05 +08:00
};
}, [handleTranbox]);
2023-11-22 11:02:48 +08:00
useEffect(() => {
if (!isGm) {
return;
}
// 注册菜单
try {
const menuCommandIds = [];
2024-02-05 11:28:34 +08:00
contextMenuType !== 0 &&
2023-12-15 11:43:01 +08:00
menuCommandIds.push(
GM.registerMenuCommand(
2024-04-20 15:54:41 +08:00
langMap("translate_selected_text"),
2023-12-15 11:43:01 +08:00
(event) => {
handleTranbox();
},
"S"
)
);
return () => {
menuCommandIds.forEach((id) => {
GM.unregisterMenuCommand(id);
});
};
} catch (err) {
2024-03-19 18:07:18 +08:00
kissLog(err, "registerMenuCommand");
}
2024-04-20 15:54:41 +08:00
}, [handleTranbox, contextMenuType, langMap]);
2024-04-01 12:25:59 +08:00
useEffect(() => {
2024-04-16 00:54:37 +08:00
if (hideClickAway) {
2024-04-01 12:25:59 +08:00
const handleHideBox = () => {
setShowBox(false);
};
window.addEventListener("click", handleHideBox);
return () => {
window.removeEventListener("click", handleHideBox);
};
}
2024-04-16 00:54:37 +08:00
}, [hideClickAway]);
2024-04-01 12:25:59 +08:00
2023-10-23 18:02:42 +08:00
return (
<>
{showBox && (
<TranBox
2023-10-24 17:58:37 +08:00
text={text}
setText={setText}
boxSize={boxSize}
setBoxSize={setBoxSize}
boxPosition={boxPosition}
setBoxPosition={setBoxPosition}
2023-10-23 18:02:42 +08:00
tranboxSetting={tranboxSetting}
2023-10-24 17:58:37 +08:00
transApis={transApis}
2023-10-23 18:02:42 +08:00
setShowBox={setShowBox}
2024-04-16 00:54:37 +08:00
simpleStyle={simpleStyle}
setSimpleStyle={setSimpleStyle}
hideClickAway={hideClickAway}
setHideClickAway={setHideClickAway}
2024-04-17 15:35:44 +08:00
extStyles={extStyles}
2023-10-23 18:02:42 +08:00
/>
)}
{showBtn && (
<TranBtn
position={position}
tranboxSetting={tranboxSetting}
2024-04-16 12:47:55 +08:00
btnEvent={btnEvent}
onTrigger={(e) => {
e.stopPropagation();
handleTrigger();
}}
2023-10-23 18:02:42 +08:00
/>
)}
</>
);
}