fix: lang detect

This commit is contained in:
Gabe
2025-09-27 21:21:56 +08:00
parent b1142b88f1
commit fffa448425
12 changed files with 238 additions and 181 deletions

View File

@@ -3,10 +3,8 @@ import { fetchData } from "../libs/fetch";
import {
URL_CACHE_TRAN,
KV_SALT_SYNC,
OPT_LANGS_BAIDU,
OPT_LANGS_TENCENT,
OPT_LANGS_SPECIAL,
OPT_LANGS_MICROSOFT,
OPT_LANGS_TO_SPEC,
OPT_LANGS_SPEC_DEFAULT,
API_SPE_TYPES,
DEFAULT_API_SETTING,
} from "../config";
@@ -41,6 +39,13 @@ export const apiSyncData = async (url, key, data) =>
*/
export const apiFetch = (url) => fetchData(url);
/**
* Microsoft token
* @returns
*/
export const apiMsAuth = async () =>
fetchData("https://edge.microsoft.com/translate/auth");
/**
* Google语言识别
* @param {*} text
@@ -78,7 +83,7 @@ export const apiGoogleLangdetect = async (text) => {
* @returns
*/
export const apiMicrosoftLangdetect = async (text) => {
const [token] = await msAuth();
const token = await msAuth();
const input =
"https://api-edge.cognitive.microsofttranslator.com/detect?api-version=3.0";
const init = {
@@ -93,9 +98,9 @@ export const apiMicrosoftLangdetect = async (text) => {
useCache: true,
});
if (res[0].language) {
if (res?.[0]?.language) {
await putHttpCachePolyfill(input, init, res);
return OPT_LANGS_MICROSOFT.get(res[0].language) ?? res[0].language;
return res[0].language;
}
return "";
@@ -119,9 +124,9 @@ export const apiBaiduLangdetect = async (text) => {
};
const res = await fetchData(input, init, { useCache: true });
if (res.error === 0) {
if (res?.error === 0) {
await putHttpCachePolyfill(input, init, res);
return OPT_LANGS_BAIDU.get(res.lan) ?? res.lan;
return res.lan;
}
return "";
@@ -145,7 +150,7 @@ export const apiBaiduSuggest = async (text) => {
};
const res = await fetchData(input, init, { useCache: true });
if (res.errno === 0) {
if (res?.errno === 0) {
await putHttpCachePolyfill(input, init, res);
return res.data;
}
@@ -175,21 +180,26 @@ export const apiTencentLangdetect = async (text) => {
const body = JSON.stringify({
header: {
fn: "text_analysis",
client_key:
"browser-chrome-110.0.0-Mac OS-df4bd4c5-a65d-44b2-a40f-42f34f3535f2-1677486696487",
},
text,
});
const init = {
headers: {
"Content-type": "application/json",
"user-agent":
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36",
referer: "https://transmart.qq.com/zh-CN/index",
},
method: "POST",
body,
};
const res = await fetchData(input, init, { useCache: true });
if (res.language) {
if (res?.language) {
await putHttpCachePolyfill(input, init, res);
return OPT_LANGS_TENCENT.get(res.language) ?? res.language;
return res.language;
}
return "";
@@ -202,7 +212,7 @@ export const apiTencentLangdetect = async (text) => {
*/
export const apiTranslate = async ({
text,
fromLang,
fromLang = "auto",
toLang,
apiSetting = DEFAULT_API_SETTING,
docInfo = {},
@@ -214,8 +224,8 @@ export const apiTranslate = async ({
}
const { apiType, apiSlug, useBatchFetch } = apiSetting;
const langMap = OPT_LANGS_SPECIAL[apiType];
const from = langMap.get(fromLang) ?? langMap.get("auto");
const langMap = OPT_LANGS_TO_SPEC[apiType] || OPT_LANGS_SPEC_DEFAULT;
const from = langMap.get(fromLang);
const to = langMap.get(toLang);
if (!to) {
kissLog(`target lang: ${toLang} not support`);
@@ -283,8 +293,7 @@ export const apiTranslate = async ({
}
}
// const isSame = srLang && (to.includes(srLang) || srLang.includes(to));
const isSame = srLang && srLang.slice(0, 2) === to.slice(0, 2);
const isSame = fromLang !== "auto" && srLang === to;
// 插入缓存
if (useCache && trText) {

View File

@@ -686,7 +686,7 @@ export const parseTransRes = async (
case OPT_TRANS_MICROSOFT:
return res?.map((item) => [
item.translations.map((item) => item.text).join(" "),
item.detectedLanguage.language,
item.detectedLanguage?.language,
]);
case OPT_TRANS_DEEPL:
return res?.translations?.map((item) => [
@@ -811,7 +811,7 @@ export const handleTranslate = async ({
let token = "";
if (apiType === OPT_TRANS_MICROSOFT) {
[token] = await msAuth();
token = await msAuth();
}
const [input, init, userMsg] = await genTransReq({

View File

@@ -23,10 +23,9 @@ import {
import { getSettingWithDefault, tryInitDefaultData } from "./libs/storage";
import { trySyncSettingAndRules } from "./libs/sync";
import { fetchHandle } from "./libs/fetch";
import { getHttpCache, putHttpCache } from "./libs/cache";
import { tryClearCaches, getHttpCache, putHttpCache } from "./libs/cache";
import { sendTabMsg } from "./libs/msg";
import { trySyncAllSubRules } from "./libs/subRules";
import { tryClearCaches } from "./libs";
import { saveRule } from "./libs/rules";
import { getCurTabId } from "./libs/msg";
import { injectInlineJs, injectInternalCss } from "./libs/injector";

View File

@@ -180,48 +180,61 @@ export const OPT_LANGS_TO = [
["uk", "Ukrainian - Українська"],
["vi", "Vietnamese - Tiếng Việt"],
];
export const OPT_LANGS_LIST = OPT_LANGS_TO.map(([lang]) => lang);
export const OPT_LANGS_FROM = [["auto", "Auto-detect"], ...OPT_LANGS_TO];
export const OPT_LANGS_SPECIAL = {
[OPT_TRANS_GOOGLE]: new Map(OPT_LANGS_FROM.map(([key]) => [key, key])),
[OPT_TRANS_GOOGLE_2]: new Map(OPT_LANGS_FROM.map(([key]) => [key, key])),
export const OPT_LANGS_MAP = new Map(OPT_LANGS_TO);
// CODE->名称
export const OPT_LANGS_SPEC_NAME = new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
);
export const OPT_LANGS_SPEC_DEFAULT = new Map(
OPT_LANGS_FROM.map(([key]) => [key, key])
);
export const OPT_LANGS_SPEC_DEFAULT_UC = new Map(
OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()])
);
export const OPT_LANGS_TO_SPEC = {
[OPT_TRANS_GOOGLE]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_GOOGLE_2]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_MICROSOFT]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key]),
...OPT_LANGS_SPEC_DEFAULT,
["auto", ""],
["zh-CN", "zh-Hans"],
["zh-TW", "zh-Hant"],
]),
[OPT_TRANS_DEEPL]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]),
...OPT_LANGS_SPEC_DEFAULT_UC,
["auto", ""],
["zh-CN", "ZH"],
["zh-TW", "ZH"],
]),
[OPT_TRANS_DEEPLFREE]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]),
...OPT_LANGS_SPEC_DEFAULT_UC,
["auto", "auto"],
["zh-CN", "ZH"],
["zh-TW", "ZH"],
]),
[OPT_TRANS_DEEPLX]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]),
...OPT_LANGS_SPEC_DEFAULT_UC,
["auto", "auto"],
["zh-CN", "ZH"],
["zh-TW", "ZH"],
]),
[OPT_TRANS_NIUTRANS]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key]),
...OPT_LANGS_SPEC_DEFAULT,
["auto", "auto"],
["zh-CN", "zh"],
["zh-TW", "cht"],
]),
[OPT_TRANS_VOLCENGINE]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key]),
...OPT_LANGS_SPEC_DEFAULT,
["auto", "auto"],
["zh-CN", "zh"],
["zh-TW", "zh-Hant"],
]),
[OPT_TRANS_BAIDU]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key]),
...OPT_LANGS_SPEC_DEFAULT,
["zh-CN", "zh"],
["zh-TW", "cht"],
["ar", "ara"],
@@ -269,62 +282,34 @@ export const OPT_LANGS_SPECIAL = {
["id", "id"],
["vi", "vi"],
]),
[OPT_TRANS_OPENAI]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
),
[OPT_TRANS_GEMINI]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
),
[OPT_TRANS_GEMINI_2]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
),
[OPT_TRANS_CLAUDE]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
),
[OPT_TRANS_OLLAMA]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
),
[OPT_TRANS_OPENROUTER]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
),
[OPT_TRANS_CLOUDFLAREAI]: new Map([
["auto", ""],
["zh-CN", "chinese"],
["zh-TW", "chinese"],
["en", "english"],
["ar", "arabic"],
["de", "german"],
["ru", "russian"],
["fr", "french"],
["pt", "portuguese"],
["ja", "japanese"],
["es", "spanish"],
["hi", "hindi"],
]),
[OPT_TRANS_CUSTOMIZE]: new Map([
...OPT_LANGS_FROM.map(([key]) => [key, key]),
]),
[OPT_TRANS_OPENAI]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_GEMINI]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_GEMINI_2]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_CLAUDE]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_OLLAMA]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_OPENROUTER]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_CLOUDFLAREAI]: OPT_LANGS_SPEC_DEFAULT,
[OPT_TRANS_CUSTOMIZE]: OPT_LANGS_SPEC_DEFAULT,
};
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,
k,
])
);
export const OPT_LANGS_TENCENT = new Map(
Array.from(OPT_LANGS_SPECIAL[OPT_TRANS_TENCENT].entries()).map(([k, v]) => [
v,
k,
])
);
OPT_LANGS_TENCENT.set("zh", "zh-CN");
const specToCode = (m) =>
new Map(
Array.from(m.entries()).map(([k, v]) => {
if (v === "") {
return ["auto", "auto"];
}
if (v === "zh" || v === "ZH") {
return [v, "zh-CN"];
}
return [v, k];
})
);
// 名称->CODE
export const OPT_LANGS_TO_CODE = {};
Object.entries(OPT_LANGS_TO_SPEC).forEach(([t, m]) => {
OPT_LANGS_TO_CODE[t] = specToCode(m);
});
const defaultSystemPrompt = `Act as a translation API. Output a single raw JSON object only. No extra text or fences.

View File

@@ -8,7 +8,7 @@ import { useCallback } from "react";
* @returns
*/
export function useRules() {
const { data: list, save } = useStorage(
const { data: list = [], save } = useStorage(
STOKEY_RULES,
DEFAULT_RULES,
KV_RULES_KEY

View File

@@ -1,6 +1,6 @@
import { getMsauth, setMsauth } from "./storage";
import { fetchData } from "./fetch";
import { kissLog } from "./log";
import { apiMsAuth } from "../apis";
const parseMSToken = (token) => {
try {
@@ -16,28 +16,55 @@ const parseMSToken = (token) => {
* @returns
*/
const _msAuth = () => {
let { token, exp } = {};
let tokenPromise = null;
const EXPIRATION_MS = 1000;
const fetchNewToken = async () => {
try {
const now = Date.now();
// 1. 查询storage缓存
const storageToken = await getMsauth();
if (storageToken) {
const storageExp = parseMSToken(storageToken);
const storageExpiresAt = storageExp * 1000;
if (storageExpiresAt > now + EXPIRATION_MS) {
return { token: storageToken, expiresAt: storageExpiresAt };
}
}
// 2. 缓存没有或失效,查询接口
const apiToken = await apiMsAuth();
if (!apiToken) {
throw new Error("Failed to fetch ms token");
}
const apiExp = parseMSToken(apiToken);
const apiExpiresAt = apiExp * 1000;
await setMsauth(apiToken);
return { token: apiToken, expiresAt: apiExpiresAt };
} catch (error) {
kissLog("get msauth failed", error);
throw error;
}
};
return async () => {
// 查询内存缓存
const now = Date.now();
if (token && exp * 1000 > now + 1000) {
return [token, exp];
// 检查是否有缓存的 Promise
if (tokenPromise) {
try {
const cachedResult = await tokenPromise;
if (cachedResult.expiresAt > Date.now() + EXPIRATION_MS) {
return cachedResult.token;
}
} catch (error) {
//
}
}
// 查询storage缓存
const res = await getMsauth();
token = res?.token;
exp = res?.exp;
if (token && exp * 1000 > now + 1000) {
return [token, exp];
}
// 缓存没有或失效,查询接口
token = await fetchData("https://edge.microsoft.com/translate/auth");
exp = parseMSToken(token);
await setMsauth({ token, exp });
return [token, exp];
tokenPromise = fetchNewToken();
const result = await tokenPromise;
return result.token;
};
};

View File

@@ -10,6 +10,17 @@ import { isBg } from "./browser";
import { sendBgMsg } from "./msg";
import { blobToBase64 } from "./utils";
/**
* 清除缓存数据
*/
export const tryClearCaches = async () => {
try {
caches.delete(CACHE_NAME);
} catch (err) {
kissLog("clean caches", err);
}
};
/**
* 构造缓存 request
* @param {*} input

View File

@@ -1,9 +1,10 @@
import {
CACHE_NAME,
OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
OPT_LANGS_TO_CODE,
OPT_LANGS_MAP,
} from "../config";
import { browser } from "./browser";
import {
@@ -14,52 +15,51 @@ import {
} from "../apis";
import { kissLog } from "./log";
const langdetectMap = {
const langdetectFns = {
[OPT_TRANS_GOOGLE]: apiGoogleLangdetect,
[OPT_TRANS_MICROSOFT]: apiMicrosoftLangdetect,
[OPT_TRANS_BAIDU]: apiBaiduLangdetect,
[OPT_TRANS_TENCENT]: apiTencentLangdetect,
};
/**
* 清除缓存数据
*/
export const tryClearCaches = async () => {
try {
caches.delete(CACHE_NAME);
} catch (err) {
kissLog("clean caches", err);
}
};
/**
* 语言识别
* @param {*} q
* @param {*} text
* @returns
*/
export const tryDetectLang = async (
q,
useRemote = false,
text,
useRemote = "false",
langDetector = OPT_TRANS_MICROSOFT
) => {
let lang = "";
let deLang = "";
if (useRemote) {
// 远程识别
if (useRemote === "true" && langDetector) {
try {
lang = await langdetectMap[langDetector](q);
const lang = await langdetectFns[langDetector](text);
if (lang) {
deLang = OPT_LANGS_TO_CODE[langDetector].get(lang) || "";
}
} catch (err) {
kissLog("detect lang remote", err);
}
}
if (!lang) {
// 本地识别
if (!deLang) {
try {
const res = await browser?.i18n?.detectLanguage(q);
lang = res?.languages?.[0]?.language;
const res = await browser?.i18n?.detectLanguage(text);
const lang = res?.languages?.[0]?.language;
if (OPT_LANGS_MAP.has(lang)) {
deLang = lang;
} else if (lang.startsWith("zh")) {
deLang = "zh-CN";
}
} catch (err) {
kissLog("detect lang local", err);
}
}
return lang;
return deLang;
};

View File

@@ -24,7 +24,7 @@ import { clearAllBatchQueue } from "./batchQueue";
import { genTextClass } from "./style";
import { loadingSvg } from "./svg";
import { shortcutRegister } from "./shortcut";
import { tryDetectLang } from ".";
import { tryDetectLang } from "./detect";
/**
* @class Translator
@@ -436,6 +436,7 @@ export class Translator {
}
}
// todo: 利用AI总结
#getDocDescription() {
try {
const meta = document.querySelector('meta[name="description"]');
@@ -738,19 +739,29 @@ export class Translator {
}
// 提前进行语言检测
const { detectRemote, toLang, skipLangs = [] } = this.#rule;
const { langDetector } = this.#setting;
const deLang = await tryDetectLang(
node.textContent,
let deLang = "";
const {
detectRemote,
langDetector
);
// console.log("deLang", deLang, toLang);
if (
deLang &&
(toLang.slice(0, 2) === deLang.slice(0, 2) || skipLangs.includes(deLang))
) {
return;
fromLang = "auto",
toLang,
skipLangs = [],
} = this.#rule;
if (fromLang === "auto") {
const { langDetector } = this.#setting;
deLang = await tryDetectLang(
node.textContent,
detectRemote,
langDetector
);
if (
deLang &&
(toLang.slice(0, 2) === deLang.slice(0, 2) ||
skipLangs.includes(deLang))
) {
// 保留处理状态,不做删除
// this.#processedNodes.delete(node);
return;
}
}
let nodeGroup = [];
@@ -762,13 +773,13 @@ export class Translator {
if (!shouldBreak && shouldGroup) {
nodeGroup.push(child);
} else if (shouldBreak && nodeGroup.length) {
this.#translateNodeGroup(nodeGroup, node);
this.#translateNodeGroup(nodeGroup, node, deLang);
nodeGroup = [];
}
});
if (nodeGroup.length) {
this.#translateNodeGroup(nodeGroup, node);
this.#translateNodeGroup(nodeGroup, node, deLang);
}
}
@@ -834,7 +845,7 @@ export class Translator {
}
// 翻译内联节点
async #translateNodeGroup(nodes, hostNode) {
async #translateNodeGroup(nodes, hostNode, deLang) {
const {
transTag,
textStyle,
@@ -901,8 +912,10 @@ export class Translator {
// return;
// }
const [translatedText, isSameLang] =
await this.#translateFetch(processedString);
const [translatedText, isSameLang] = await this.#translateFetch(
processedString,
deLang
);
// console.log("translatedText", translatedText);
if (isSameLang || this.#runId !== currentRunId) {
wrapper.remove();
@@ -1060,7 +1073,7 @@ export class Translator {
}
// 发起翻译请求
#translateFetch(text) {
#translateFetch(text, deLang = "") {
const { apiSlug, fromLang, toLang } = this.#rule;
const apiSetting =
this.#setting.transApis.find((api) => api.apiSlug === apiSlug) ||
@@ -1068,7 +1081,7 @@ export class Translator {
return apiTranslate({
text,
fromLang,
fromLang: deLang || fromLang,
toLang,
apiSetting,
docInfo: this.#docInfo,
@@ -1295,17 +1308,23 @@ export class Translator {
this.#init();
}
// 翻译页面标题
if (this.#rule.transTitle === "true") {
const title = document.title;
this.#docInfo.title = title;
this.#translateFetch(title)
.then(([trText]) => {
document.title = trText || title;
})
.catch((err) => {
kissLog("tanslate title", err);
});
this.#translateTitle();
}
}
// 翻译页面标题
async #translateTitle() {
const title = document.title;
this.#docInfo.title = title;
if (!title) return;
try {
const deLang = await tryDetectLang(title);
const [translatedTitle] = await this.#translateFetch(title, deLang);
document.title = translatedTitle || title;
} catch (err) {
kissLog("tanslate title", err);
}
}

View File

@@ -63,24 +63,30 @@ import { kissLog } from "../../libs/log";
import { useApiList } from "../../hooks/Api";
import ShowMoreButton from "./ShowMoreButton";
const calculateInitialValues = (rule) => {
const base = rule?.pattern === "*" ? GLOBLA_RULE : DEFAULT_RULE;
return { ...base, ...(rule || {}) };
};
function RuleFields({ rule, rules, setShow, setKeyword }) {
const initFormValues = useMemo(
() => ({
...(rule?.pattern === "*" ? GLOBLA_RULE : DEFAULT_RULE),
...(rule || {}),
}),
[rule]
);
const editMode = useMemo(() => !!rule, [rule]);
const i18n = useI18n();
const [disabled, setDisabled] = useState(editMode);
const [errors, setErrors] = useState({});
const [formValues, setFormValues] = useState(initFormValues);
const [initialFormValues, setInitialFormValues] = useState(() =>
calculateInitialValues(rule)
);
const [formValues, setFormValues] = useState(initialFormValues);
const [showMore, setShowMore] = useState(!rules);
const [isModified, setIsModified] = useState(false);
const { enabledApis } = useApiList();
useEffect(() => {
const newInitialValues = calculateInitialValues(rule);
setInitialFormValues(newInitialValues);
setFormValues(newInitialValues);
}, [rule]);
const {
pattern,
selector,
@@ -116,12 +122,9 @@ function RuleFields({ rule, rules, setShow, setKeyword }) {
// transRemoveHook = "",
} = formValues;
useEffect(() => {
if (!initFormValues) return;
const hasChanged =
JSON.stringify(initFormValues) !== JSON.stringify(formValues);
setIsModified(hasChanged);
}, [initFormValues, formValues]);
const isModified = useMemo(() => {
return JSON.stringify(initialFormValues) !== JSON.stringify(formValues);
}, [initialFormValues, formValues]);
const hasSamePattern = (str) => {
for (const item of rules.list) {
@@ -163,7 +166,7 @@ function RuleFields({ rule, rules, setShow, setKeyword }) {
setShow(false);
}
setErrors({});
setFormValues(initFormValues);
setFormValues(initialFormValues);
};
const handleRestore = (e) => {
@@ -199,7 +202,7 @@ function RuleFields({ rule, rules, setShow, setKeyword }) {
// 添加
rules.add(formValues);
setShow(false);
setFormValues(initFormValues);
setFormValues(initialFormValues);
}
};
@@ -1205,11 +1208,15 @@ function SubRules({ subRules }) {
}
function GlobalRule({ rules }) {
if (!rules.list) {
const globalRule = useMemo(
() => rules.list[rules.list.length - 1],
[rules.list]
);
if (!globalRule) {
return;
}
const globalRule = rules.list[rules.list.length - 1];
return (
<Stack spacing={3}>
<RuleAccordion

View File

@@ -26,7 +26,7 @@ import {
} from "../../config";
import { sendIframeMsg } from "../../libs/iframe";
import { saveRule } from "../../libs/rules";
import { tryClearCaches } from "../../libs";
import { tryClearCaches } from "../../libs/cache";
import { kissLog } from "../../libs/log";
import { parseUrlPattern } from "../../libs/utils";

View File

@@ -9,7 +9,7 @@ import { apiTranslate } from "../../apis";
import CopyBtn from "./CopyBtn";
import Typography from "@mui/material/Typography";
import Alert from "@mui/material/Alert";
import { tryDetectLang } from "../../libs";
import { tryDetectLang } from "../../libs/detect";
export default function TranCont({
text,
@@ -35,7 +35,7 @@ export default function TranCont({
let to = toLang;
if (fromLang === "auto" && toLang !== toLang2 && toLang2 !== "none") {
const detectLang = await tryDetectLang(text, true, langDetector);
const detectLang = await tryDetectLang(text, "true", langDetector);
if (detectLang === toLang) {
to = toLang2;
}