feat: transbox follow selection
This commit is contained in:
@@ -861,4 +861,8 @@ export const I18N = {
|
||||
zh: `打开设置`,
|
||||
en: `Open Setting`,
|
||||
},
|
||||
follow_selection: {
|
||||
zh: `翻译框跟随选中文本`,
|
||||
en: `Transbox Follow Selection`,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -434,6 +434,7 @@ export const DEFAULT_TRANBOX_SETTING = {
|
||||
hideTranBtn: false, // 是否隐藏翻译按钮
|
||||
hideClickAway: false, // 是否点击外部关闭弹窗
|
||||
simpleStyle: false, // 是否简洁界面
|
||||
followSelection: false, // 翻译框是否跟随选中文本
|
||||
triggerMode: OPT_TRANBOX_TRIGGER_CLICK, // 触发翻译方式
|
||||
extStyles: "", // 附加样式
|
||||
};
|
||||
|
||||
@@ -58,6 +58,7 @@ export default function Tranbox() {
|
||||
hideTranBtn = false,
|
||||
hideClickAway = false,
|
||||
simpleStyle = false,
|
||||
followSelection = false,
|
||||
triggerMode = OPT_TRANBOX_TRIGGER_CLICK,
|
||||
extStyles = "",
|
||||
} = tranboxSetting;
|
||||
@@ -194,6 +195,18 @@ export default function Tranbox() {
|
||||
<MenuItem value={true}>{i18n("enable")}</MenuItem>
|
||||
</TextField>
|
||||
|
||||
<TextField
|
||||
select
|
||||
size="small"
|
||||
name="followSelection"
|
||||
value={followSelection}
|
||||
label={i18n("follow_selection")}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<MenuItem value={false}>{i18n("disable")}</MenuItem>
|
||||
<MenuItem value={true}>{i18n("enable")}</MenuItem>
|
||||
</TextField>
|
||||
|
||||
<TextField
|
||||
select
|
||||
size="small"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Box from "@mui/material/Box";
|
||||
import { isMobile } from "../../libs/mobile";
|
||||
@@ -130,11 +130,11 @@ function Pointer({
|
||||
export default function DraggableResizable({
|
||||
header,
|
||||
children,
|
||||
defaultPosition = {
|
||||
position = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
defaultSize = {
|
||||
size = {
|
||||
w: 600,
|
||||
h: 400,
|
||||
},
|
||||
@@ -146,14 +146,13 @@ export default function DraggableResizable({
|
||||
w: 1200,
|
||||
h: 1200,
|
||||
},
|
||||
setSize,
|
||||
setPosition,
|
||||
onChangeSize,
|
||||
onChangePosition,
|
||||
...props
|
||||
}) {
|
||||
const lineWidth = 4;
|
||||
const [position, setPosition] = useState(defaultPosition);
|
||||
const [size, setSize] = useState(defaultSize);
|
||||
|
||||
const opts = {
|
||||
size,
|
||||
setSize,
|
||||
@@ -163,14 +162,6 @@ export default function DraggableResizable({
|
||||
maxSize,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
onChangeSize && onChangeSize(size);
|
||||
}, [size, onChangeSize]);
|
||||
|
||||
useEffect(() => {
|
||||
onChangePosition && onChangePosition(position);
|
||||
}, [position, onChangePosition]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
className="KT-draggable"
|
||||
|
||||
@@ -14,6 +14,8 @@ import UnfoldLessIcon from "@mui/icons-material/UnfoldLess";
|
||||
import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore";
|
||||
import PushPinIcon from "@mui/icons-material/PushPin";
|
||||
import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined";
|
||||
import LockIcon from "@mui/icons-material/Lock";
|
||||
import LockOpenIcon from "@mui/icons-material/LockOpen";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import { useI18n } from "../../hooks/I18n";
|
||||
import { OPT_TRANS_ALL, OPT_LANGS_FROM, OPT_LANGS_TO } from "../../config";
|
||||
@@ -30,6 +32,8 @@ function Header({
|
||||
setSimpleStyle,
|
||||
hideClickAway,
|
||||
setHideClickAway,
|
||||
followSelection,
|
||||
setFollowSelection,
|
||||
}) {
|
||||
return (
|
||||
<Box
|
||||
@@ -47,6 +51,18 @@ function Header({
|
||||
}}
|
||||
>
|
||||
{hideClickAway ? (
|
||||
<LockOpenIcon fontSize="small" />
|
||||
) : (
|
||||
<LockIcon fontSize="small" />
|
||||
)}
|
||||
</IconButton>
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setFollowSelection((pre) => !pre);
|
||||
}}
|
||||
>
|
||||
{followSelection ? (
|
||||
<PushPinOutlinedIcon fontSize="small" />
|
||||
) : (
|
||||
<PushPinIcon fontSize="small" />
|
||||
@@ -243,14 +259,18 @@ export default function TranBox({
|
||||
setSimpleStyle,
|
||||
hideClickAway,
|
||||
setHideClickAway,
|
||||
followSelection,
|
||||
setFollowSelection,
|
||||
extStyles,
|
||||
}) {
|
||||
return (
|
||||
<SettingProvider>
|
||||
<ThemeProvider styles={extStyles}>
|
||||
<DraggableResizable
|
||||
defaultPosition={boxPosition}
|
||||
defaultSize={boxSize}
|
||||
position={boxPosition}
|
||||
size={boxSize}
|
||||
setSize={setBoxSize}
|
||||
setPosition={setBoxPosition}
|
||||
header={
|
||||
<Header
|
||||
setShowPopup={setShowBox}
|
||||
@@ -258,10 +278,10 @@ export default function TranBox({
|
||||
setSimpleStyle={setSimpleStyle}
|
||||
hideClickAway={hideClickAway}
|
||||
setHideClickAway={setHideClickAway}
|
||||
followSelection={followSelection}
|
||||
setFollowSelection={setFollowSelection}
|
||||
/>
|
||||
}
|
||||
onChangeSize={setBoxSize}
|
||||
onChangePosition={setBoxPosition}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<TranForm
|
||||
|
||||
@@ -25,6 +25,7 @@ export default function Slection({
|
||||
hideTranBtn = false,
|
||||
simpleStyle: initSimpleStyle = false,
|
||||
hideClickAway: initHideClickAway = false,
|
||||
followSelection: initFollowMouse = false,
|
||||
tranboxShortcut = DEFAULT_TRANBOX_SHORTCUT,
|
||||
triggerMode = OPT_TRANBOX_TRIGGER_CLICK,
|
||||
extStyles,
|
||||
@@ -55,6 +56,7 @@ export default function Slection({
|
||||
});
|
||||
const [simpleStyle, setSimpleStyle] = useState(initSimpleStyle);
|
||||
const [hideClickAway, setHideClickAway] = useState(initHideClickAway);
|
||||
const [followSelection, setFollowSelection] = useState(initFollowMouse);
|
||||
|
||||
const handleTrigger = useCallback(
|
||||
(text) => {
|
||||
@@ -68,16 +70,25 @@ export default function Slection({
|
||||
const handleTranbox = useCallback(() => {
|
||||
setShowBtn(false);
|
||||
|
||||
const selectedText = window.getSelection()?.toString()?.trim() || "";
|
||||
const selection = window.getSelection();
|
||||
const selectedText = selection?.toString()?.trim() || "";
|
||||
if (!selectedText) {
|
||||
setShowBox((pre) => !pre);
|
||||
return;
|
||||
}
|
||||
|
||||
const rect = selection?.getRangeAt(0)?.getBoundingClientRect();
|
||||
if (rect && followSelection) {
|
||||
setBoxPosition({
|
||||
x: limitNumber(rect.right, 0, window.innerWidth - 300),
|
||||
y: limitNumber(rect.bottom, 0, window.innerHeight - 200),
|
||||
});
|
||||
}
|
||||
|
||||
setSelText(selectedText);
|
||||
setText(selectedText);
|
||||
setShowBox(true);
|
||||
}, []);
|
||||
}, [followSelection]);
|
||||
|
||||
const btnEvent = useMemo(() => {
|
||||
if (isMobile) {
|
||||
@@ -93,13 +104,22 @@ export default function Slection({
|
||||
e.stopPropagation();
|
||||
await sleep(200);
|
||||
|
||||
const selectedText = window.getSelection()?.toString()?.trim() || "";
|
||||
const selection = window.getSelection();
|
||||
const selectedText = selection?.toString()?.trim() || "";
|
||||
setSelText(selectedText);
|
||||
if (!selectedText) {
|
||||
setShowBtn(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const rect = selection?.getRangeAt(0)?.getBoundingClientRect();
|
||||
if (rect && followSelection) {
|
||||
setBoxPosition({
|
||||
x: limitNumber(rect.right, 0, window.innerWidth - 300),
|
||||
y: limitNumber(rect.bottom, 0, window.innerHeight - 200),
|
||||
});
|
||||
}
|
||||
|
||||
if (triggerMode === OPT_TRANBOX_TRIGGER_SELECT) {
|
||||
handleTrigger(selectedText);
|
||||
return;
|
||||
@@ -119,7 +139,7 @@ export default function Slection({
|
||||
handleMouseup
|
||||
);
|
||||
};
|
||||
}, [hideTranBtn, triggerMode, handleTrigger]);
|
||||
}, [hideTranBtn, triggerMode, followSelection, handleTrigger]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isExt) {
|
||||
@@ -196,6 +216,8 @@ export default function Slection({
|
||||
setSimpleStyle={setSimpleStyle}
|
||||
hideClickAway={hideClickAway}
|
||||
setHideClickAway={setHideClickAway}
|
||||
followSelection={followSelection}
|
||||
setFollowSelection={setFollowSelection}
|
||||
extStyles={extStyles}
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user