feat: simple style tranbox

This commit is contained in:
Gabe Yuan
2024-04-16 00:54:37 +08:00
parent ce4ac79e5f
commit a13493ebc2
5 changed files with 222 additions and 128 deletions

View File

@@ -418,7 +418,8 @@ export const DEFAULT_TRANBOX_SETTING = {
btnOffsetX: 10, btnOffsetX: 10,
btnOffsetY: 10, btnOffsetY: 10,
hideTranBtn: false, // 是否隐藏翻译按钮 hideTranBtn: false, // 是否隐藏翻译按钮
hideClickAway: false, // 是否点击外部关闭弹窗 hideClickAway: false, // 默认是否点击外部关闭弹窗
simpleStyle: false, // 默认是否简洁界面
}; };
// 订阅列表 // 订阅列表

View File

@@ -1,7 +1,6 @@
import { SettingProvider } from "../../hooks/Setting"; import { SettingProvider } from "../../hooks/Setting";
import ThemeProvider from "../../hooks/Theme"; import ThemeProvider from "../../hooks/Theme";
import DraggableResizable from "./DraggableResizable"; import DraggableResizable from "./DraggableResizable";
import Header from "../Popup/Header";
import Stack from "@mui/material/Stack"; import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField"; import TextField from "@mui/material/TextField";
import MenuItem from "@mui/material/MenuItem"; import MenuItem from "@mui/material/MenuItem";
@@ -10,6 +9,12 @@ import Box from "@mui/material/Box";
import Divider from "@mui/material/Divider"; import Divider from "@mui/material/Divider";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
import DoneIcon from "@mui/icons-material/Done"; import DoneIcon from "@mui/icons-material/Done";
import DragIndicatorIcon from "@mui/icons-material/DragIndicator";
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 CloseIcon from "@mui/icons-material/Close";
import { useI18n } from "../../hooks/I18n"; import { useI18n } from "../../hooks/I18n";
import { OPT_TRANS_ALL, OPT_LANGS_FROM, OPT_LANGS_TO } from "../../config"; import { OPT_TRANS_ALL, OPT_LANGS_FROM, OPT_LANGS_TO } from "../../config";
import { useState, useRef } from "react"; import { useState, useRef } from "react";
@@ -17,8 +22,50 @@ import TranCont from "./TranCont";
import DictCont from "./DictCont"; import DictCont from "./DictCont";
import SugCont from "./SugCont"; import SugCont from "./SugCont";
import CopyBtn from "./CopyBtn"; import CopyBtn from "./CopyBtn";
import { isValidWord } from "../../libs/utils";
function TranForm({ text, setText, tranboxSetting, transApis }) { function Header({
setShowPopup,
simpleStyle,
setSimpleStyle,
hideClickAway,
setHideClickAway,
}) {
return (
<Stack direction="row" justifyContent="space-between" alignItems="center">
<DragIndicatorIcon />
<Stack direction="row" alignItems="center">
<IconButton
size="small"
onClick={() => {
setHideClickAway((pre) => !pre);
}}
>
{hideClickAway ? <PushPinOutlinedIcon /> : <PushPinIcon />}
</IconButton>
<IconButton
size="small"
onClick={() => {
setSimpleStyle((pre) => !pre);
}}
>
{simpleStyle ? <UnfoldMoreIcon /> : <UnfoldLessIcon />}
</IconButton>
<IconButton
size="small"
onClick={() => {
setShowPopup(false);
}}
>
<CloseIcon />
</IconButton>
</Stack>
</Stack>
);
}
function TranForm({ text, setText, tranboxSetting, transApis, simpleStyle }) {
const i18n = useI18n(); const i18n = useI18n();
const [editMode, setEditMode] = useState(false); const [editMode, setEditMode] = useState(false);
@@ -29,127 +76,135 @@ function TranForm({ text, setText, tranboxSetting, transApis }) {
const inputRef = useRef(null); const inputRef = useRef(null);
return ( return (
<Stack sx={{ p: 2 }} spacing={2}> <Stack sx={{ p: simpleStyle ? 1 : 2 }} spacing={simpleStyle ? 1 : 2}>
<Box> {!simpleStyle && (
<Grid container spacing={2} columns={12}> <>
<Grid item xs={4} sm={4} md={4} lg={4}> <Box>
<TextField <Grid container spacing={simpleStyle ? 1 : 2} columns={12}>
select <Grid item xs={4} sm={4} md={4} lg={4}>
SelectProps={{ MenuProps: { disablePortal: true } }} <TextField
fullWidth select
size="small" SelectProps={{ MenuProps: { disablePortal: true } }}
name="fromLang" fullWidth
value={fromLang} size="small"
label={i18n("from_lang")} name="fromLang"
onChange={(e) => { value={fromLang}
setFromLang(e.target.value); label={i18n("from_lang")}
}} onChange={(e) => {
> setFromLang(e.target.value);
{OPT_LANGS_FROM.map(([lang, name]) => ( }}
<MenuItem key={lang} value={lang}> >
{name} {OPT_LANGS_FROM.map(([lang, name]) => (
</MenuItem> <MenuItem key={lang} value={lang}>
))} {name}
</TextField> </MenuItem>
</Grid> ))}
<Grid item xs={4} sm={4} md={4} lg={4}> </TextField>
<TextField </Grid>
select <Grid item xs={4} sm={4} md={4} lg={4}>
SelectProps={{ MenuProps: { disablePortal: true } }} <TextField
fullWidth select
size="small" SelectProps={{ MenuProps: { disablePortal: true } }}
name="toLang" fullWidth
value={toLang} size="small"
label={i18n("to_lang")} name="toLang"
onChange={(e) => { value={toLang}
setToLang(e.target.value); label={i18n("to_lang")}
}} onChange={(e) => {
> setToLang(e.target.value);
{OPT_LANGS_TO.map(([lang, name]) => ( }}
<MenuItem key={lang} value={lang}> >
{name} {OPT_LANGS_TO.map(([lang, name]) => (
</MenuItem> <MenuItem key={lang} value={lang}>
))} {name}
</TextField> </MenuItem>
</Grid> ))}
<Grid item xs={4} sm={4} md={4} lg={4}> </TextField>
<TextField </Grid>
select <Grid item xs={4} sm={4} md={4} lg={4}>
SelectProps={{ MenuProps: { disablePortal: true } }} <TextField
fullWidth select
size="small" SelectProps={{ MenuProps: { disablePortal: true } }}
value={translator} fullWidth
name="translator" size="small"
label={i18n("translate_service")} value={translator}
onChange={(e) => { name="translator"
setTranslator(e.target.value); label={i18n("translate_service")}
}} onChange={(e) => {
> setTranslator(e.target.value);
{OPT_TRANS_ALL.map((item) => ( }}
<MenuItem key={item} value={item}> >
{item} {OPT_TRANS_ALL.map((item) => (
</MenuItem> <MenuItem key={item} value={item}>
))} {item}
</TextField> </MenuItem>
</Grid> ))}
</Grid> </TextField>
</Box> </Grid>
</Grid>
</Box>
<Box> <Box>
<TextField <TextField
size="small" size="small"
label={i18n("original_text")} label={i18n("original_text")}
inputRef={inputRef} inputRef={inputRef}
fullWidth fullWidth
multiline multiline
value={editMode ? editText : text} value={editMode ? editText : text}
onChange={(e) => { onChange={(e) => {
setEditText(e.target.value); setEditText(e.target.value);
}} }}
onFocus={() => { onFocus={() => {
setEditMode(true); setEditMode(true);
setEditText(text); setEditText(text);
}} }}
onBlur={() => { onBlur={() => {
setEditMode(false); setEditMode(false);
setText(editText.trim()); setText(editText.trim());
}} }}
InputProps={{ InputProps={{
endAdornment: ( endAdornment: (
<Stack <Stack
direction="row" direction="row"
sx={{ sx={{
position: "absolute", position: "absolute",
right: 0, right: 0,
top: 0, top: 0,
}}
>
{editMode ? (
<IconButton
size="small"
onClick={(e) => {
e.stopPropagation();
}} }}
> >
<DoneIcon fontSize="inherit" /> {editMode ? (
</IconButton> <IconButton
) : ( size="small"
<CopyBtn text={text} /> onClick={(e) => {
)} e.stopPropagation();
</Stack> }}
), >
}} <DoneIcon fontSize="inherit" />
/> </IconButton>
</Box> ) : (
<CopyBtn text={text} />
)}
</Stack>
),
}}
/>
</Box>
</>
)}
{(!simpleStyle || !isValidWord(text)) && (
<TranCont
text={text}
translator={translator}
fromLang={fromLang}
toLang={toLang}
toLang2={tranboxSetting.toLang2}
transApis={transApis}
simpleStyle={simpleStyle}
/>
)}
<TranCont
text={text}
translator={translator}
fromLang={fromLang}
toLang={toLang}
toLang2={tranboxSetting.toLang2}
transApis={transApis}
/>
<DictCont text={text} /> <DictCont text={text} />
<SugCont text={text} /> <SugCont text={text} />
</Stack> </Stack>
@@ -166,6 +221,10 @@ export default function TranBox({
setBoxSize, setBoxSize,
boxPosition, boxPosition,
setBoxPosition, setBoxPosition,
simpleStyle,
setSimpleStyle,
hideClickAway,
setHideClickAway,
}) { }) {
return ( return (
<SettingProvider> <SettingProvider>
@@ -173,7 +232,15 @@ export default function TranBox({
<DraggableResizable <DraggableResizable
defaultPosition={boxPosition} defaultPosition={boxPosition}
defaultSize={boxSize} defaultSize={boxSize}
header={<Header setShowPopup={setShowBox} />} header={
<Header
setShowPopup={setShowBox}
simpleStyle={simpleStyle}
setSimpleStyle={setSimpleStyle}
hideClickAway={hideClickAway}
setHideClickAway={setHideClickAway}
/>
}
onChangeSize={setBoxSize} onChangeSize={setBoxSize}
onChangePosition={setBoxPosition} onChangePosition={setBoxPosition}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
@@ -184,6 +251,7 @@ export default function TranBox({
setText={setText} setText={setText}
tranboxSetting={tranboxSetting} tranboxSetting={tranboxSetting}
transApis={transApis} transApis={transApis}
simpleStyle={simpleStyle}
/> />
</DraggableResizable> </DraggableResizable>
</ThemeProvider> </ThemeProvider>

View File

@@ -25,7 +25,8 @@ export default function TranBtn({ onClick, position, tranboxSetting }) {
<div <div
style={{ style={{
cursor: "pointer", cursor: "pointer",
position: "absolute", // position: "absolute",
position: "fixed",
left, left,
top, top,
zIndex: 2147483647, zIndex: 2147483647,

View File

@@ -7,6 +7,7 @@ import { DEFAULT_TRANS_APIS } from "../../config";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { apiTranslate, apiBaiduLangdetect } from "../../apis"; import { apiTranslate, apiBaiduLangdetect } from "../../apis";
import CopyBtn from "./CopyBtn"; import CopyBtn from "./CopyBtn";
import Typography from "@mui/material/Typography";
export default function TranCont({ export default function TranCont({
text, text,
@@ -15,6 +16,7 @@ export default function TranCont({
toLang, toLang,
toLang2 = "en", toLang2 = "en",
transApis, transApis,
simpleStyle,
}) { }) {
const i18n = useI18n(); const i18n = useI18n();
const [trText, setTrText] = useState(""); const [trText, setTrText] = useState("");
@@ -54,6 +56,14 @@ export default function TranCont({
})(); })();
}, [text, translator, fromLang, toLang, toLang2, transApis]); }, [text, translator, fromLang, toLang, toLang2, transApis]);
if (simpleStyle) {
return (
<Box>
<Typography style={{ whiteSpace: "pre-line" }}>{trText}</Typography>
</Box>
);
}
return ( return (
<Box> <Box>
<TextField <TextField

View File

@@ -13,9 +13,16 @@ export default function Slection({
tranboxSetting, tranboxSetting,
transApis, transApis,
}) { }) {
const boxWidth = limitNumber(window.innerWidth, 300, 600); const boxWidth =
const boxHeight = limitNumber(window.innerHeight, 200, 400); isMobile || tranboxSetting.simpleStyle
? 300
: limitNumber(window.innerWidth, 300, 600);
const boxHeight =
isMobile || tranboxSetting.simpleStyle
? 200
: limitNumber(window.innerHeight, 200, 400);
const [simpleStyle, setSimpleStyle] = useState(!!tranboxSetting.simpleStyle);
const [showBox, setShowBox] = useState(false); const [showBox, setShowBox] = useState(false);
const [showBtn, setShowBtn] = useState(false); const [showBtn, setShowBtn] = useState(false);
const [selectedText, setSelText] = useState(""); const [selectedText, setSelText] = useState("");
@@ -29,6 +36,9 @@ export default function Slection({
x: (window.innerWidth - boxWidth) / 2, x: (window.innerWidth - boxWidth) / 2,
y: (window.innerHeight - boxHeight) / 2, y: (window.innerHeight - boxHeight) / 2,
}); });
const [hideClickAway, setHideClickAway] = useState(
!!tranboxSetting.hideClickAway
);
const handleClick = (e) => { const handleClick = (e) => {
e.stopPropagation(); e.stopPropagation();
@@ -64,10 +74,10 @@ export default function Slection({
return; return;
} }
const { pageX, pageY } = isMobile ? e.changedTouches[0] : e; const { clientX, clientY } = isMobile ? e.changedTouches[0] : e;
!tranboxSetting.hideTranBtn && setShowBtn(true); !tranboxSetting.hideTranBtn && setShowBtn(true);
// setPosition({ x: e.clientX, y: e.clientY }); // setPosition({ x: e.clientX, y: e.clientY });
setPosition({ x: pageX, y: pageY }); setPosition({ x: clientX, y: clientY });
} }
// todo: mobile support // todo: mobile support
@@ -133,7 +143,7 @@ export default function Slection({
}, [handleTranbox, contextMenuType]); }, [handleTranbox, contextMenuType]);
useEffect(() => { useEffect(() => {
if (tranboxSetting.hideClickAway) { if (hideClickAway) {
const handleHideBox = () => { const handleHideBox = () => {
setShowBox(false); setShowBox(false);
}; };
@@ -142,7 +152,7 @@ export default function Slection({
window.removeEventListener("click", handleHideBox); window.removeEventListener("click", handleHideBox);
}; };
} }
}, [tranboxSetting.hideClickAway]); }, [hideClickAway]);
return ( return (
<> <>
@@ -157,6 +167,10 @@ export default function Slection({
tranboxSetting={tranboxSetting} tranboxSetting={tranboxSetting}
transApis={transApis} transApis={transApis}
setShowBox={setShowBox} setShowBox={setShowBox}
simpleStyle={simpleStyle}
setSimpleStyle={setSimpleStyle}
hideClickAway={hideClickAway}
setHideClickAway={setHideClickAway}
/> />
)} )}