diff --git a/src/apis/index.js b/src/apis/index.js
index c0b842f..378ca4a 100644
--- a/src/apis/index.js
+++ b/src/apis/index.js
@@ -24,6 +24,8 @@ import {
OPT_TRANS_CUSTOMIZE_5,
URL_CACHE_TRAN,
KV_SALT_SYNC,
+ URL_GOOGLE_TRAN,
+ URL_MICROSOFT_LANGDETECT,
URL_BAIDU_LANGDETECT,
URL_BAIDU_SUGGEST,
URL_BAIDU_TTS,
@@ -31,9 +33,11 @@ import {
URL_TENCENT_TRANSMART,
OPT_LANGS_TENCENT,
OPT_LANGS_SPECIAL,
+ OPT_LANGS_MICROSOFT,
} from "../config";
import { sha256 } from "../libs/utils";
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);
+/**
+ * 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
diff --git a/src/common.js b/src/common.js
index d296d31..f422d30 100644
--- a/src/common.js
+++ b/src/common.js
@@ -141,6 +141,7 @@ function showTransbox({
transApis,
darkMode,
uiLang,
+ langDetector,
}) {
if (!tranboxSetting?.transOpen) {
return;
@@ -172,6 +173,7 @@ function showTransbox({
tranboxSetting={tranboxSetting}
transApis={transApis}
uiLang={uiLang}
+ langDetector={langDetector}
/>
diff --git a/src/config/index.js b/src/config/index.js
index 1a030ef..bf49ed7 100644
--- a/src/config/index.js
+++ b/src/config/index.js
@@ -78,9 +78,16 @@ export const URL_RAW_PREFIX =
"https://raw.githubusercontent.com/fishjar/kiss-translator/master";
export const URL_CACHE_TRAN = `https://${APP_LCNAME}/translate`;
+
+// api.cognitive.microsofttranslator.com
export const URL_MICROSOFT_TRAN =
"https://api-edge.cognitive.microsofttranslator.com/translate";
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_SUGGEST = "https://fanyi.baidu.com/sug";
export const URL_BAIDU_TTS = "https://fanyi.baidu.com/gettts";
@@ -140,6 +147,13 @@ export const OPT_TRANS_ALL = [
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 = [
["en", "English - English"],
["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_MICROSOFT = new Map(
+ Array.from(OPT_LANGS_SPECIAL[OPT_TRANS_MICROSOFT].entries()).map(([k, v]) => [
+ v,
+ k,
+ ])
+);
export const OPT_LANGS_BAIDU = new Map(
Array.from(OPT_LANGS_SPECIAL[OPT_TRANS_BAIDU].entries()).map(([k, v]) => [
v,
@@ -515,7 +535,7 @@ const defaultOllamaApi = {
};
export const DEFAULT_TRANS_APIS = {
[OPT_TRANS_GOOGLE]: {
- url: "https://translate.googleapis.com/translate_a/single",
+ url: URL_GOOGLE_TRAN,
key: "",
fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量
fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间
@@ -636,6 +656,7 @@ export const DEFAULT_SETTING = {
csplist: DEFAULT_CSPLIST.join(",\n"), // 禁用CSP名单
// disableLangs: [], // 不翻译的语言(移至rule,作废)
transInterval: 500, // 翻译间隔时间
+ langDetector: OPT_TRANS_MICROSOFT, // 远程语言识别服务
};
export const DEFAULT_RULES = [GLOBLA_RULE];
diff --git a/src/hooks/Translate.js b/src/hooks/Translate.js
index a2f89ef..6ca03a7 100644
--- a/src/hooks/Translate.js
+++ b/src/hooks/Translate.js
@@ -30,7 +30,11 @@ export function useTranslate(q, rule, setting) {
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))) {
setSamelang(true);
} else {
diff --git a/src/libs/index.js b/src/libs/index.js
index 13ed33e..36759b1 100644
--- a/src/libs/index.js
+++ b/src/libs/index.js
@@ -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 { apiBaiduLangdetect } from "../apis";
+import {
+ apiGoogleLangdetect,
+ apiMicrosoftLangdetect,
+ apiBaiduLangdetect,
+ apiTencentLangdetect,
+} from "../apis";
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
* @returns
*/
-export const tryDetectLang = async (q, useRemote = false) => {
+export const tryDetectLang = async (
+ q,
+ useRemote = false,
+ langDetector = OPT_TRANS_MICROSOFT
+) => {
let lang = "";
if (useRemote) {
try {
- lang = await apiBaiduLangdetect(q);
+ lang = await langdetectMap[langDetector](q);
} catch (err) {
kissLog(err, "detect lang remote");
}
diff --git a/src/views/Options/Setting.js b/src/views/Options/Setting.js
index 4a0f3b9..b916e4c 100644
--- a/src/views/Options/Setting.js
+++ b/src/views/Options/Setting.js
@@ -17,6 +17,8 @@ import {
UI_LANGS,
TRANS_NEWLINE_LENGTH,
CACHE_NAME,
+ OPT_TRANS_MICROSOFT,
+ OPT_LANGDETECTOR_ALL,
OPT_SHORTCUT_TRANSLATE,
OPT_SHORTCUT_STYLE,
OPT_SHORTCUT_POPUP,
@@ -113,6 +115,7 @@ export default function Settings() {
blacklist = DEFAULT_BLACKLIST.join(",\n"),
csplist = DEFAULT_CSPLIST.join(",\n"),
transInterval = 500,
+ langDetector = OPT_TRANS_MICROSOFT,
} = setting;
const { isHide = false } = fab || {};
@@ -231,6 +234,22 @@ export default function Settings() {
+
+ {i18n("detect_lang_remote")}
+
+
+
{isExt ? (
<>
diff --git a/src/views/Selection/TranBox.js b/src/views/Selection/TranBox.js
index 6b96179..2f84e76 100644
--- a/src/views/Selection/TranBox.js
+++ b/src/views/Selection/TranBox.js
@@ -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 [editMode, setEditMode] = useState(false);
@@ -242,6 +249,7 @@ function TranForm({ text, setText, tranboxSetting, transApis, simpleStyle }) {
toLang2={tranboxSetting.toLang2}
transApis={transApis}
simpleStyle={simpleStyle}
+ langDetector={langDetector}
/>
)}
@@ -268,6 +276,7 @@ export default function TranBox({
followSelection,
setFollowSelection,
extStyles,
+ langDetector,
}) {
const [mouseHover, setMouseHover] = useState(false);
return (
@@ -300,6 +309,7 @@ export default function TranBox({
tranboxSetting={tranboxSetting}
transApis={transApis}
simpleStyle={simpleStyle}
+ langDetector={langDetector}
/>
diff --git a/src/views/Selection/TranCont.js b/src/views/Selection/TranCont.js
index 60abd14..b89ab32 100644
--- a/src/views/Selection/TranCont.js
+++ b/src/views/Selection/TranCont.js
@@ -5,10 +5,11 @@ import Stack from "@mui/material/Stack";
import { useI18n } from "../../hooks/I18n";
import { DEFAULT_TRANS_APIS } from "../../config";
import { useEffect, useState } from "react";
-import { apiTranslate, apiBaiduLangdetect } from "../../apis";
+import { apiTranslate } from "../../apis";
import CopyBtn from "./CopyBtn";
import Typography from "@mui/material/Typography";
import Alert from "@mui/material/Alert";
+import { tryDetectLang } from "../../libs";
export default function TranCont({
text,
@@ -18,6 +19,7 @@ export default function TranCont({
toLang2 = "en",
transApis,
simpleStyle,
+ langDetector,
}) {
const i18n = useI18n();
const [trText, setTrText] = useState("");
@@ -33,7 +35,7 @@ export default function TranCont({
let to = toLang;
if (toLang !== toLang2 && toLang2 !== "none") {
- const detectLang = await apiBaiduLangdetect(text);
+ const detectLang = await tryDetectLang(text, true, langDetector);
if (detectLang === toLang) {
to = toLang2;
}
@@ -55,7 +57,7 @@ export default function TranCont({
setLoading(false);
}
})();
- }, [text, translator, fromLang, toLang, toLang2, transApis]);
+ }, [text, translator, fromLang, toLang, toLang2, transApis, langDetector]);
if (simpleStyle) {
return (
diff --git a/src/views/Selection/index.js b/src/views/Selection/index.js
index 2f950a0..4982f76 100644
--- a/src/views/Selection/index.js
+++ b/src/views/Selection/index.js
@@ -20,6 +20,7 @@ export default function Slection({
tranboxSetting,
transApis,
uiLang,
+ langDetector,
}) {
const {
hideTranBtn = false,
@@ -234,6 +235,7 @@ export default function Slection({
followSelection={followSelection}
setFollowSelection={setFollowSelection}
extStyles={extStyles}
+ langDetector={langDetector}
/>
)}