feat: Extensive refactoring and modification to support any number of interfaces

This commit is contained in:
Gabe
2025-09-24 23:24:00 +08:00
parent 779c9fc850
commit 2a46939aa5
65 changed files with 2054 additions and 1947 deletions

View File

@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useState, useEffect, useMemo } from "react";
import Stack from "@mui/material/Stack";
import FavBtn from "./FavBtn";
import Typography from "@mui/material/Typography";
@@ -26,10 +26,10 @@ export default function DictCont({ text }) {
return;
}
// todo
// todo: 修复
const dictRes = await apiTranslate({
text,
translator: OPT_TRANS_BAIDU,
apiSlug: OPT_TRANS_BAIDU,
fromLang: "en",
toLang: "zh-CN",
});
@@ -45,70 +45,74 @@ export default function DictCont({ text }) {
})();
}, [text]);
if (error) {
return <Alert severity="error">{error}</Alert>;
}
const copyText = useMemo(() => {
if (!dictResult) {
return text;
}
return [
dictResult.src,
dictResult.voice
?.map(Object.entries)
.map((item) => item[0])
.map(([key, val]) => `${PHONIC_MAP[key]?.[0] || key} ${val}`)
.join(" "),
dictResult.content[0].mean
.map(({ pre, cont }) => {
return `${pre ? `[${pre}] ` : ""}${Object.keys(cont).join("; ")}`;
})
.join("\n"),
].join("\n");
}, [text, dictResult]);
if (loading) {
return <CircularProgress size={16} />;
}
if (!text || !dictResult) {
return;
}
const copyText = [
dictResult.src,
dictResult.voice
?.map(Object.entries)
.map((item) => item[0])
.map(([key, val]) => `${PHONIC_MAP[key]?.[0] || key} ${val}`)
.join(" "),
dictResult.content[0].mean
.map(({ pre, cont }) => {
return `${pre ? `[${pre}] ` : ""}${Object.keys(cont).join("; ")}`;
})
.join("\n"),
].join("\n");
return (
<Stack className="KT-transbox-dict" spacing={1}>
<Stack direction="row" justifyContent="space-between">
<Typography variant="subtitle1" style={{ fontWeight: "bold" }}>
{dictResult.src}
</Typography>
{text && (
<Stack direction="row" justifyContent="space-between">
<CopyBtn text={copyText} />
<FavBtn word={dictResult.src} />
<Typography variant="subtitle1" style={{ fontWeight: "bold" }}>
{dictResult?.src || text}
</Typography>
<Stack direction="row" justifyContent="space-between">
<CopyBtn text={copyText} />
<FavBtn word={dictResult?.src || text} />
</Stack>
</Stack>
</Stack>
)}
<Typography component="div">
{error && <Alert severity="error">{error}</Alert>}
{dictResult && (
<Typography component="div">
{dictResult.voice
?.map(Object.entries)
.map((item) => item[0])
.map(([key, val]) => (
<Typography
component="div"
key={key}
style={{ display: "inline-block" }}
>
<Typography component="span">{`${PHONIC_MAP[key]?.[0] || key} ${val}`}</Typography>
<AudioBtn text={dictResult.src} lan={PHONIC_MAP[key]?.[1]} />
<Typography component="div">
{dictResult.voice
?.map(Object.entries)
.map((item) => item[0])
.map(([key, val]) => (
<Typography
component="div"
key={key}
style={{ display: "inline-block" }}
>
<Typography component="span">{`${PHONIC_MAP[key]?.[0] || key} ${val}`}</Typography>
<AudioBtn text={dictResult.src} lan={PHONIC_MAP[key]?.[1]} />
</Typography>
))}
</Typography>
<Typography component="ul">
{dictResult.content[0].mean.map(({ pre, cont }, idx) => (
<Typography component="li" key={idx}>
{pre && `[${pre}] `}
{Object.keys(cont).join("; ")}
</Typography>
))}
</Typography>
</Typography>
<Typography component="ul">
{dictResult.content[0].mean.map(({ pre, cont }, idx) => (
<Typography component="li" key={idx}>
{pre && `[${pre}] `}
{Object.keys(cont).join("; ")}
</Typography>
))}
</Typography>
</Typography>
)}
</Stack>
);
}

View File

@@ -9,12 +9,12 @@ export default function FavBtn({ word }) {
const { favWords, toggleFav } = useFavWords();
const [loading, setLoading] = useState(false);
const handleClick = async () => {
const handleClick = () => {
try {
setLoading(true);
await toggleFav(word);
toggleFav(word);
} catch (err) {
kissLog(err, "set fav");
kissLog("set fav", err);
} finally {
setLoading(false);
}

View File

@@ -18,12 +18,7 @@ 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,
DEFAULT_TRANS_APIS,
} from "../../config";
import { OPT_LANGS_FROM, OPT_LANGS_TO } from "../../config";
import { useState, useRef, useMemo } from "react";
import TranCont from "./TranCont";
import DictCont from "./DictCont";
@@ -119,21 +114,18 @@ function TranForm({
const [editMode, setEditMode] = useState(false);
const [editText, setEditText] = useState("");
const [translator, setTranslator] = useState(tranboxSetting.translator);
const [apiSlug, setApiSlug] = useState(tranboxSetting.apiSlug);
const [fromLang, setFromLang] = useState(tranboxSetting.fromLang);
const [toLang, setToLang] = useState(tranboxSetting.toLang);
const inputRef = useRef(null);
const optApis = useMemo(
() =>
OPT_TRANS_ALL.map((key) => ({
...(transApis[key] || DEFAULT_TRANS_APIS[key]),
apiKey: key,
}))
.filter((item) => !item.isDisabled)
.map(({ apiKey, apiName }) => ({
key: apiKey,
name: apiName?.trim() || apiKey,
transApis
.filter((api) => !api.isDisabled)
.map((api) => ({
key: api.apiSlug,
name: api.apiName || api.apiSlug,
})),
[transApis]
);
@@ -194,11 +186,11 @@ function TranForm({
SelectProps={{ MenuProps: { disablePortal: true } }}
fullWidth
size="small"
value={translator}
name="translator"
value={apiSlug}
name="apiSlug"
label={i18n("translate_service")}
onChange={(e) => {
setTranslator(e.target.value);
setApiSlug(e.target.value);
}}
>
{optApis.map(({ key, name }) => (
@@ -266,7 +258,7 @@ function TranForm({
enDict === "-") && (
<TranCont
text={text}
translator={translator}
apiSlug={apiSlug}
fromLang={fromLang}
toLang={toLang}
toLang2={tranboxSetting.toLang2}
@@ -307,6 +299,7 @@ export default function TranBox({
enDict,
}) {
const [mouseHover, setMouseHover] = useState(false);
// todo: 这里的 SettingProvider 不应和 background 的共用
return (
<SettingProvider>
<ThemeProvider styles={extStyles}>

View File

@@ -3,7 +3,7 @@ import Box from "@mui/material/Box";
import CircularProgress from "@mui/material/CircularProgress";
import Stack from "@mui/material/Stack";
import { useI18n } from "../../hooks/I18n";
import { DEFAULT_TRANS_APIS } from "../../config";
import { DEFAULT_API_SETTING } from "../../config";
import { useEffect, useState } from "react";
import { apiTranslate } from "../../apis";
import CopyBtn from "./CopyBtn";
@@ -13,7 +13,7 @@ import { tryDetectLang } from "../../libs";
export default function TranCont({
text,
translator,
apiSlug,
fromLang,
toLang,
toLang2 = "en",
@@ -42,10 +42,11 @@ export default function TranCont({
}
const apiSetting =
transApis[translator] || DEFAULT_TRANS_APIS[translator];
transApis.find((api) => api.apiSlug === apiSlug) ||
DEFAULT_API_SETTING;
const [trText] = await apiTranslate({
text,
translator,
apiSlug,
fromLang,
toLang: to,
apiSetting,
@@ -57,7 +58,7 @@ export default function TranCont({
setLoading(false);
}
})();
}, [text, translator, fromLang, toLang, toLang2, transApis, langDetector]);
}, [text, apiSlug, fromLang, toLang, toLang2, transApis, langDetector]);
if (simpleStyle) {
return (

View File

@@ -201,7 +201,7 @@ export default function Slection({
});
};
} catch (err) {
kissLog(err, "registerMenuCommand");
kissLog("registerMenuCommand", err);
}
}, [handleTranbox, contextMenuType, langMap]);