diff --git a/src/apis/index.js b/src/apis/index.js
index 57a3c3f..31d3af5 100644
--- a/src/apis/index.js
+++ b/src/apis/index.js
@@ -3,6 +3,7 @@ import { fetchData } from "../libs/fetch";
import {
URL_CACHE_TRAN,
URL_CACHE_DELANG,
+ URL_CACHE_BINGDICT,
KV_SALT_SYNC,
OPT_LANGS_TO_SPEC,
OPT_LANGS_SPEC_DEFAULT,
@@ -107,6 +108,60 @@ export const apiMicrosoftLangdetect = async (text) => {
return "";
};
+/**
+ * Microsoft词典
+ * @param {*} text
+ * @returns
+ */
+export const apiMicrosoftDict = async (text) => {
+ const cacheOpts = { text };
+ const cacheInput = `${URL_CACHE_BINGDICT}?${queryString.stringify(cacheOpts)}`;
+ const cache = await getHttpCachePolyfill(cacheInput);
+ if (cache) {
+ return cache;
+ }
+
+ const host = "https://cn.bing.com";
+ const url = `${host}/dict/search?q=${text}`;
+ const str = await fetchData(url, {}, { useCache: false });
+
+ const parser = new DOMParser();
+ const doc = parser.parseFromString(str, "text/html");
+
+ const word = doc.querySelector("#headword > h1").textContent.trim();
+ if (!word) {
+ return null;
+ }
+
+ const trs = [];
+ doc.querySelectorAll("div.qdef > ul > li").forEach(($li) => {
+ const pos = $li.querySelector(".pos")?.textContent?.trim();
+ const def = $li.querySelector(".def")?.textContent?.trim();
+ trs.push({ pos, def });
+ });
+
+ const aus = [];
+ const $audioUS = doc.querySelector("#bigaud_us");
+ const $audioUK = doc.querySelector("#bigaud_uk");
+ if ($audioUS) {
+ const audioUS = host + $audioUS?.dataset?.mp3link;
+ const $phoneticUS = $audioUS.parentElement?.previousElementSibling;
+ const phoneticUS = $phoneticUS?.textContent?.trim();
+ aus.push({ key: "US", audio: audioUS, phonetic: phoneticUS });
+ }
+ if ($audioUK) {
+ const audioUK = host + $audioUK?.dataset?.mp3link;
+ const $phoneticUK = $audioUK.parentElement?.previousElementSibling;
+ const phoneticUK = $phoneticUK?.textContent?.trim();
+ aus.push({ key: "UK", audio: audioUK, phonetic: phoneticUK });
+ }
+
+ const res = { word, trs, aus };
+ putHttpCachePolyfill(cacheInput, null, res);
+
+ return res;
+};
+
/**
* 百度语言识别
* @param {*} text
diff --git a/src/config/api.js b/src/config/api.js
index 6fa0e96..5c7c512 100644
--- a/src/config/api.js
+++ b/src/config/api.js
@@ -14,8 +14,9 @@ export const INPUT_PLACE_KEY = "{{key}}"; // 占位符
export const INPUT_PLACE_MODEL = "{{model}}"; // 占位符
export const OPT_DICT_BAIDU = "Baidu";
+export const OPT_DICT_BING = "Bing";
export const OPT_DICT_YOUDAO = "Youdao";
-export const OPT_DICT_ALL = [OPT_DICT_BAIDU, OPT_DICT_YOUDAO];
+export const OPT_DICT_ALL = [OPT_DICT_BING, OPT_DICT_YOUDAO];
export const OPT_DICT_MAP = new Set(OPT_DICT_ALL);
export const OPT_SUG_BAIDU = "Baidu";
diff --git a/src/config/url.js b/src/config/url.js
index 9b03e60..83b8bac 100644
--- a/src/config/url.js
+++ b/src/config/url.js
@@ -2,6 +2,7 @@ import { APP_LCNAME } from "./app";
export const URL_CACHE_TRAN = `https://${APP_LCNAME}/translate`;
export const URL_CACHE_DELANG = `https://${APP_LCNAME}/detectlang`;
+export const URL_CACHE_BINGDICT = `https://${APP_LCNAME}/bingdict`;
export const URL_KISS_WORKER = "https://github.com/fishjar/kiss-worker";
export const URL_KISS_PROXY = "https://github.com/fishjar/kiss-proxy";
diff --git a/src/views/Options/FavWords.js b/src/views/Options/FavWords.js
index 5200371..9d70bc0 100644
--- a/src/views/Options/FavWords.js
+++ b/src/views/Options/FavWords.js
@@ -22,6 +22,7 @@ import { apiTranslate } from "../../apis";
import { OPT_TRANS_BAIDU, PHONIC_MAP } from "../../config";
import { useConfirm } from "../../hooks/Confirm";
import { useSetting } from "../../hooks/Setting";
+import { DICT_MAP } from "../Selection/DictMap";
function FavAccordion({ word, index }) {
const [expanded, setExpanded] = useState(false);
@@ -55,6 +56,7 @@ function FavAccordion({ word, index }) {
export default function FavWords() {
const i18n = useI18n();
const { favList, wordList, mergeWords, clearWords } = useFavWords();
+ const { setting } = useSetting();
const confirm = useConfirm();
const handleImport = (data) => {
@@ -80,41 +82,22 @@ export default function FavWords() {
};
const handleTranslation = async () => {
+ const { enDict } = setting?.tranboxSetting;
+ const dict = DICT_MAP[enDict];
+ if (!dict) return "";
+
const tranList = [];
- for (const text of wordList) {
+ for (const word of wordList) {
try {
- // todo: 修复
- const dictRes = await apiTranslate({
- text,
- translator: OPT_TRANS_BAIDU,
- fromLang: "en",
- toLang: "zh-CN",
- });
- if (dictRes[2]?.type === 1) {
- tranList.push(JSON.parse(dictRes[2].result));
- }
+ const data = await dict.apiFn(word);
+ const tran = dict.toText(data);
+ tranList.push([word, tran].join("\n"));
} catch (err) {
// skip
}
}
- return tranList
- .map((dictResult) =>
- [
- `## ${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\n")
- )
- .join("\n\n");
+ return tranList.join("\n\n");
};
return (
diff --git a/src/views/Selection/AudioBtn.js b/src/views/Selection/AudioBtn.js
index 3d5d052..17810bb 100644
--- a/src/views/Selection/AudioBtn.js
+++ b/src/views/Selection/AudioBtn.js
@@ -1,9 +1,9 @@
import IconButton from "@mui/material/IconButton";
import VolumeUpIcon from "@mui/icons-material/VolumeUp";
-import { useTextAudio } from "../../hooks/Audio";
+import { useAudio } from "../../hooks/Audio";
-export default function AudioBtn({ text, lan = "uk" }) {
- const { error, ready, playing, onPlay } = useTextAudio(text, lan);
+export default function AudioBtn({ src }) {
+ const { error, ready, playing, onPlay } = useAudio(src);
if (error || !ready) {
return (
diff --git a/src/views/Selection/DictCont.js b/src/views/Selection/DictCont.js
index e3b893b..06e714e 100644
--- a/src/views/Selection/DictCont.js
+++ b/src/views/Selection/DictCont.js
@@ -1,90 +1,28 @@
-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";
-import AudioBtn from "./AudioBtn";
import CircularProgress from "@mui/material/CircularProgress";
import Divider from "@mui/material/Divider";
import Alert from "@mui/material/Alert";
-import { OPT_DICT_BAIDU, OPT_DICT_YOUDAO, PHONIC_MAP } from "../../config";
import CopyBtn from "./CopyBtn";
import { useAsyncNow } from "../../hooks/Fetch";
-import { apiYoudaoDict } from "../../apis";
+import { DICT_MAP } from "./DictMap";
-function DictBaidu({ text, setCopyText }) {
- // useEffect(() => {
- // if (!data) {
- // return;
- // }
-
- // const copyText = [
- // data.src,
- // data.voice
- // ?.map(Object.entries)
- // .map((item) => item[0])
- // .map(([key, val]) => `${PHONIC_MAP[key]?.[0] || key} ${val}`)
- // .join(" "),
- // data.content[0].mean
- // .map(({ pre, cont }) => {
- // return `${pre ? `[${pre}] ` : ""}${Object.keys(cont).join("; ")}`;
- // })
- // .join("\n"),
- // ].join("\n");
-
- // setCopyText(copyText);
- // }, [data, setCopyText]);
-
- return baidu dict not supported yet;
-
- {
- /* {dictResult && (
-
-
- {dictResult.voice
- ?.map(Object.entries)
- .map((item) => item[0])
- .map(([key, val]) => (
-
- {`${PHONIC_MAP[key]?.[0] || key} ${val}`}
-
-
- ))}
-
-
-
- {dictResult.content[0].mean.map(({ pre, cont }, idx) => (
-
- {pre && `[${pre}] `}
- {Object.keys(cont).join("; ")}
-
- ))}
-
-
- )} */
- }
-}
-
-function DictYoudao({ text, setCopyText }) {
- const { loading, error, data } = useAsyncNow(apiYoudaoDict, text);
+function DictBody({ text, setCopyText, dict }) {
+ const { loading, error, data } = useAsyncNow(dict.apiFn, text);
useEffect(() => {
if (!data) {
return;
}
- const copyText = [
- text,
- data?.ec?.word?.trs
- ?.map(({ pos, tran }) => `${pos ? `[${pos}] ` : ""}${tran}`)
- .join("\n"),
- ].join("\n");
-
+ const copyText = [text, dict.toText(data)].join("\n");
setCopyText(copyText);
- }, [data, setCopyText]);
+ }, [data, text, dict, setCopyText]);
+
+ const uiAudio = useMemo(() => dict.uiAudio(data), [data, dict]);
+ const uiTrans = useMemo(() => dict.uiTrans(data), [data, dict]);
if (loading) {
return ;
@@ -95,30 +33,20 @@ function DictYoudao({ text, setCopyText }) {
}
if (!data) {
- return;
+ return Empty result;
}
return (
-
- {data?.ec?.word?.trs?.map(({ pos, tran }, idx) => (
-
- {pos && `[${pos}] `}
- {tran}
-
- ))}
-
+ {uiAudio}
+ {uiTrans}
);
}
export default function DictCont({ text, enDict }) {
const [copyText, setCopyText] = useState(text);
-
- const dictMap = {
- [OPT_DICT_BAIDU]: ,
- [OPT_DICT_YOUDAO]: ,
- };
+ const dict = DICT_MAP[enDict];
return (
@@ -136,7 +64,7 @@ export default function DictCont({ text, enDict }) {
- {dictMap[enDict] || Dict not support}
+ {dict && }
);
}
diff --git a/src/views/Selection/DictMap.js b/src/views/Selection/DictMap.js
new file mode 100644
index 0000000..2d29eaa
--- /dev/null
+++ b/src/views/Selection/DictMap.js
@@ -0,0 +1,56 @@
+import Typography from "@mui/material/Typography";
+import AudioBtn from "./AudioBtn";
+import { OPT_DICT_BING, OPT_DICT_YOUDAO } from "../../config";
+import { apiMicrosoftDict, apiYoudaoDict } from "../../apis";
+
+export const DICT_MAP = {
+ [OPT_DICT_BING]: {
+ apiFn: apiMicrosoftDict,
+ toText: (data) =>
+ data.trs
+ ?.map(({ pos, def }) => `${pos ? `[${pos}] ` : ""}${def}`)
+ .join("\n"),
+ uiAudio: (data) => (
+
+ {data?.aus.map(({ key, audio, phonetic }) => (
+
+ {phonetic}
+
+
+ ))}
+
+ ),
+ uiTrans: (data) => (
+
+ {data?.trs?.map(({ pos, def }, idx) => (
+
+ {pos && `[${pos}] `}
+ {def}
+
+ ))}
+
+ ),
+ },
+ [OPT_DICT_YOUDAO]: {
+ apiFn: apiYoudaoDict,
+ toText: (data) =>
+ data?.ec?.word?.trs
+ ?.map(({ pos, tran }) => `${pos ? `[${pos}] ` : ""}${tran}`)
+ .join("\n"),
+ uiAudio: () => null,
+ uiTrans: (data) => (
+
+ {data?.ec?.word?.trs?.map(({ pos, tran }, idx) => (
+
+ {pos && `[${pos}] `}
+ {tran}
+
+ ))}
+
+ ),
+ },
+};