feat: lang detector can be selected

This commit is contained in:
Gabe Yuan
2024-05-22 23:33:30 +08:00
parent e5b16ebfd3
commit 9312783f44
9 changed files with 142 additions and 10 deletions

View File

@@ -24,6 +24,8 @@ import {
OPT_TRANS_CUSTOMIZE_5, OPT_TRANS_CUSTOMIZE_5,
URL_CACHE_TRAN, URL_CACHE_TRAN,
KV_SALT_SYNC, KV_SALT_SYNC,
URL_GOOGLE_TRAN,
URL_MICROSOFT_LANGDETECT,
URL_BAIDU_LANGDETECT, URL_BAIDU_LANGDETECT,
URL_BAIDU_SUGGEST, URL_BAIDU_SUGGEST,
URL_BAIDU_TTS, URL_BAIDU_TTS,
@@ -31,9 +33,11 @@ import {
URL_TENCENT_TRANSMART, URL_TENCENT_TRANSMART,
OPT_LANGS_TENCENT, OPT_LANGS_TENCENT,
OPT_LANGS_SPECIAL, OPT_LANGS_SPECIAL,
OPT_LANGS_MICROSOFT,
} from "../config"; } from "../config";
import { sha256 } from "../libs/utils"; import { sha256 } from "../libs/utils";
import interpreter from "../libs/interpreter"; import interpreter from "../libs/interpreter";
import { msAuth } from "../libs/auth";
/** /**
* 同步数据 * 同步数据
@@ -59,6 +63,52 @@ export const apiSyncData = async (url, key, data) =>
*/ */
export const apiFetch = (url) => fetchData(url); export const apiFetch = (url) => fetchData(url);
/**
* Google语言识别
* @param {*} text
* @returns
*/
export const apiGoogleLangdetect = async (text) => {
const params = {
client: "gtx",
dt: "t",
dj: 1,
ie: "UTF-8",
sl: "auto",
tl: "zh-CN",
q: text,
};
const input = `${URL_GOOGLE_TRAN}?${queryString.stringify(params)}`;
const res = await fetchData(input, {
headers: {
"Content-type": "application/json",
},
useCache: true,
});
return res.src;
};
/**
* Microsoft语言识别
* @param {*} text
* @returns
*/
export const apiMicrosoftLangdetect = async (text) => {
const [token] = await msAuth();
const res = await fetchData(URL_MICROSOFT_LANGDETECT, {
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${token}`,
},
method: "POST",
body: JSON.stringify([{ Text: text }]),
useCache: true,
});
return OPT_LANGS_MICROSOFT.get(res[0].language) ?? res[0].language;
};
/** /**
* 百度语言识别 * 百度语言识别
* @param {*} text * @param {*} text

View File

@@ -141,6 +141,7 @@ function showTransbox({
transApis, transApis,
darkMode, darkMode,
uiLang, uiLang,
langDetector,
}) { }) {
if (!tranboxSetting?.transOpen) { if (!tranboxSetting?.transOpen) {
return; return;
@@ -172,6 +173,7 @@ function showTransbox({
tranboxSetting={tranboxSetting} tranboxSetting={tranboxSetting}
transApis={transApis} transApis={transApis}
uiLang={uiLang} uiLang={uiLang}
langDetector={langDetector}
/> />
</CacheProvider> </CacheProvider>
</React.StrictMode> </React.StrictMode>

View File

@@ -78,9 +78,16 @@ export const URL_RAW_PREFIX =
"https://raw.githubusercontent.com/fishjar/kiss-translator/master"; "https://raw.githubusercontent.com/fishjar/kiss-translator/master";
export const URL_CACHE_TRAN = `https://${APP_LCNAME}/translate`; export const URL_CACHE_TRAN = `https://${APP_LCNAME}/translate`;
// api.cognitive.microsofttranslator.com
export const URL_MICROSOFT_TRAN = export const URL_MICROSOFT_TRAN =
"https://api-edge.cognitive.microsofttranslator.com/translate"; "https://api-edge.cognitive.microsofttranslator.com/translate";
export const URL_MICROSOFT_AUTH = "https://edge.microsoft.com/translate/auth"; export const URL_MICROSOFT_AUTH = "https://edge.microsoft.com/translate/auth";
export const URL_MICROSOFT_LANGDETECT =
"https://api-edge.cognitive.microsofttranslator.com/detect?api-version=3.0";
export const URL_GOOGLE_TRAN =
"https://translate.googleapis.com/translate_a/single";
export const URL_BAIDU_LANGDETECT = "https://fanyi.baidu.com/langdetect"; export const URL_BAIDU_LANGDETECT = "https://fanyi.baidu.com/langdetect";
export const URL_BAIDU_SUGGEST = "https://fanyi.baidu.com/sug"; export const URL_BAIDU_SUGGEST = "https://fanyi.baidu.com/sug";
export const URL_BAIDU_TTS = "https://fanyi.baidu.com/gettts"; export const URL_BAIDU_TTS = "https://fanyi.baidu.com/gettts";
@@ -140,6 +147,13 @@ export const OPT_TRANS_ALL = [
OPT_TRANS_CUSTOMIZE_5, OPT_TRANS_CUSTOMIZE_5,
]; ];
export const OPT_LANGDETECTOR_ALL = [
OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
];
export const OPT_LANGS_TO = [ export const OPT_LANGS_TO = [
["en", "English - English"], ["en", "English - English"],
["zh-CN", "Simplified Chinese - 简体中文"], ["zh-CN", "Simplified Chinese - 简体中文"],
@@ -318,6 +332,12 @@ export const OPT_LANGS_SPECIAL = {
]), ]),
}; };
export const OPT_LANGS_LIST = OPT_LANGS_TO.map(([lang]) => lang); export const OPT_LANGS_LIST = OPT_LANGS_TO.map(([lang]) => lang);
export const OPT_LANGS_MICROSOFT = new Map(
Array.from(OPT_LANGS_SPECIAL[OPT_TRANS_MICROSOFT].entries()).map(([k, v]) => [
v,
k,
])
);
export const OPT_LANGS_BAIDU = new Map( export const OPT_LANGS_BAIDU = new Map(
Array.from(OPT_LANGS_SPECIAL[OPT_TRANS_BAIDU].entries()).map(([k, v]) => [ Array.from(OPT_LANGS_SPECIAL[OPT_TRANS_BAIDU].entries()).map(([k, v]) => [
v, v,
@@ -515,7 +535,7 @@ const defaultOllamaApi = {
}; };
export const DEFAULT_TRANS_APIS = { export const DEFAULT_TRANS_APIS = {
[OPT_TRANS_GOOGLE]: { [OPT_TRANS_GOOGLE]: {
url: "https://translate.googleapis.com/translate_a/single", url: URL_GOOGLE_TRAN,
key: "", key: "",
fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量 fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量
fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间 fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间
@@ -636,6 +656,7 @@ export const DEFAULT_SETTING = {
csplist: DEFAULT_CSPLIST.join(",\n"), // 禁用CSP名单 csplist: DEFAULT_CSPLIST.join(",\n"), // 禁用CSP名单
// disableLangs: [], // 不翻译的语言(移至rule作废) // disableLangs: [], // 不翻译的语言(移至rule作废)
transInterval: 500, // 翻译间隔时间 transInterval: 500, // 翻译间隔时间
langDetector: OPT_TRANS_MICROSOFT, // 远程语言识别服务
}; };
export const DEFAULT_RULES = [GLOBLA_RULE]; export const DEFAULT_RULES = [GLOBLA_RULE];

View File

@@ -30,7 +30,11 @@ export function useTranslate(q, rule, setting) {
return; return;
} }
const deLang = await tryDetectLang(q, detectRemote === "true"); const deLang = await tryDetectLang(
q,
detectRemote === "true",
setting.langDetector
);
if (deLang && (toLang.includes(deLang) || skipLangs.includes(deLang))) { if (deLang && (toLang.includes(deLang) || skipLangs.includes(deLang))) {
setSamelang(true); setSamelang(true);
} else { } else {

View File

@@ -1,8 +1,26 @@
import { CACHE_NAME } from "../config"; import {
CACHE_NAME,
OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
} from "../config";
import { browser } from "./browser"; import { browser } from "./browser";
import { apiBaiduLangdetect } from "../apis"; import {
apiGoogleLangdetect,
apiMicrosoftLangdetect,
apiBaiduLangdetect,
apiTencentLangdetect,
} from "../apis";
import { kissLog } from "./log"; import { kissLog } from "./log";
const langdetectMap = {
[OPT_TRANS_GOOGLE]: apiGoogleLangdetect,
[OPT_TRANS_MICROSOFT]: apiMicrosoftLangdetect,
[OPT_TRANS_BAIDU]: apiBaiduLangdetect,
[OPT_TRANS_TENCENT]: apiTencentLangdetect,
};
/** /**
* 清除缓存数据 * 清除缓存数据
*/ */
@@ -19,12 +37,16 @@ export const tryClearCaches = async () => {
* @param {*} q * @param {*} q
* @returns * @returns
*/ */
export const tryDetectLang = async (q, useRemote = false) => { export const tryDetectLang = async (
q,
useRemote = false,
langDetector = OPT_TRANS_MICROSOFT
) => {
let lang = ""; let lang = "";
if (useRemote) { if (useRemote) {
try { try {
lang = await apiBaiduLangdetect(q); lang = await langdetectMap[langDetector](q);
} catch (err) { } catch (err) {
kissLog(err, "detect lang remote"); kissLog(err, "detect lang remote");
} }

View File

@@ -17,6 +17,8 @@ import {
UI_LANGS, UI_LANGS,
TRANS_NEWLINE_LENGTH, TRANS_NEWLINE_LENGTH,
CACHE_NAME, CACHE_NAME,
OPT_TRANS_MICROSOFT,
OPT_LANGDETECTOR_ALL,
OPT_SHORTCUT_TRANSLATE, OPT_SHORTCUT_TRANSLATE,
OPT_SHORTCUT_STYLE, OPT_SHORTCUT_STYLE,
OPT_SHORTCUT_POPUP, OPT_SHORTCUT_POPUP,
@@ -113,6 +115,7 @@ export default function Settings() {
blacklist = DEFAULT_BLACKLIST.join(",\n"), blacklist = DEFAULT_BLACKLIST.join(",\n"),
csplist = DEFAULT_CSPLIST.join(",\n"), csplist = DEFAULT_CSPLIST.join(",\n"),
transInterval = 500, transInterval = 500,
langDetector = OPT_TRANS_MICROSOFT,
} = setting; } = setting;
const { isHide = false } = fab || {}; const { isHide = false } = fab || {};
@@ -231,6 +234,22 @@ export default function Settings() {
</Select> </Select>
</FormControl> </FormControl>
<FormControl size="small">
<InputLabel>{i18n("detect_lang_remote")}</InputLabel>
<Select
name="langDetector"
value={langDetector}
label={i18n("detect_lang_remote")}
onChange={handleChange}
>
{OPT_LANGDETECTOR_ALL.map((item) => (
<MenuItem value={item} key={item}>
{item}
</MenuItem>
))}
</Select>
</FormControl>
{isExt ? ( {isExt ? (
<> <>
<FormControl size="small"> <FormControl size="small">

View File

@@ -101,7 +101,14 @@ function Header({
); );
} }
function TranForm({ text, setText, tranboxSetting, transApis, simpleStyle }) { function TranForm({
text,
setText,
tranboxSetting,
transApis,
simpleStyle,
langDetector,
}) {
const i18n = useI18n(); const i18n = useI18n();
const [editMode, setEditMode] = useState(false); const [editMode, setEditMode] = useState(false);
@@ -242,6 +249,7 @@ function TranForm({ text, setText, tranboxSetting, transApis, simpleStyle }) {
toLang2={tranboxSetting.toLang2} toLang2={tranboxSetting.toLang2}
transApis={transApis} transApis={transApis}
simpleStyle={simpleStyle} simpleStyle={simpleStyle}
langDetector={langDetector}
/> />
)} )}
@@ -268,6 +276,7 @@ export default function TranBox({
followSelection, followSelection,
setFollowSelection, setFollowSelection,
extStyles, extStyles,
langDetector,
}) { }) {
const [mouseHover, setMouseHover] = useState(false); const [mouseHover, setMouseHover] = useState(false);
return ( return (
@@ -300,6 +309,7 @@ export default function TranBox({
tranboxSetting={tranboxSetting} tranboxSetting={tranboxSetting}
transApis={transApis} transApis={transApis}
simpleStyle={simpleStyle} simpleStyle={simpleStyle}
langDetector={langDetector}
/> />
</DraggableResizable> </DraggableResizable>
</ThemeProvider> </ThemeProvider>

View File

@@ -5,10 +5,11 @@ import Stack from "@mui/material/Stack";
import { useI18n } from "../../hooks/I18n"; import { useI18n } from "../../hooks/I18n";
import { DEFAULT_TRANS_APIS } from "../../config"; import { DEFAULT_TRANS_APIS } from "../../config";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { apiTranslate, apiBaiduLangdetect } from "../../apis"; import { apiTranslate } from "../../apis";
import CopyBtn from "./CopyBtn"; import CopyBtn from "./CopyBtn";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Alert from "@mui/material/Alert"; import Alert from "@mui/material/Alert";
import { tryDetectLang } from "../../libs";
export default function TranCont({ export default function TranCont({
text, text,
@@ -18,6 +19,7 @@ export default function TranCont({
toLang2 = "en", toLang2 = "en",
transApis, transApis,
simpleStyle, simpleStyle,
langDetector,
}) { }) {
const i18n = useI18n(); const i18n = useI18n();
const [trText, setTrText] = useState(""); const [trText, setTrText] = useState("");
@@ -33,7 +35,7 @@ export default function TranCont({
let to = toLang; let to = toLang;
if (toLang !== toLang2 && toLang2 !== "none") { if (toLang !== toLang2 && toLang2 !== "none") {
const detectLang = await apiBaiduLangdetect(text); const detectLang = await tryDetectLang(text, true, langDetector);
if (detectLang === toLang) { if (detectLang === toLang) {
to = toLang2; to = toLang2;
} }
@@ -55,7 +57,7 @@ export default function TranCont({
setLoading(false); setLoading(false);
} }
})(); })();
}, [text, translator, fromLang, toLang, toLang2, transApis]); }, [text, translator, fromLang, toLang, toLang2, transApis, langDetector]);
if (simpleStyle) { if (simpleStyle) {
return ( return (

View File

@@ -20,6 +20,7 @@ export default function Slection({
tranboxSetting, tranboxSetting,
transApis, transApis,
uiLang, uiLang,
langDetector,
}) { }) {
const { const {
hideTranBtn = false, hideTranBtn = false,
@@ -234,6 +235,7 @@ export default function Slection({
followSelection={followSelection} followSelection={followSelection}
setFollowSelection={setFollowSelection} setFollowSelection={setFollowSelection}
extStyles={extStyles} extStyles={extStyles}
langDetector={langDetector}
/> />
)} )}