diff --git a/src/apis/baidu.js b/src/apis/baidu.js index 88c0b9e..92fa775 100644 --- a/src/apis/baidu.js +++ b/src/apis/baidu.js @@ -1,5 +1,5 @@ import queryString from "query-string"; -import { URL_BAIDU_TRANSAPI, DEFAULT_USER_AGENT } from "../config"; +import { DEFAULT_USER_AGENT } from "../config"; export const genBaidu = async ({ text, from, to }) => { const data = { @@ -9,6 +9,7 @@ export const genBaidu = async ({ text, from, to }) => { source: "txt", }; + const input = "https://fanyi.baidu.com/transapi"; const init = { headers: { // Origin: "https://fanyi.baidu.com", @@ -19,5 +20,5 @@ export const genBaidu = async ({ text, from, to }) => { body: queryString.stringify(data), }; - return [URL_BAIDU_TRANSAPI, init]; + return [input, init]; }; diff --git a/src/apis/deepl.js b/src/apis/deepl.js index fa45dd3..2259cc8 100644 --- a/src/apis/deepl.js +++ b/src/apis/deepl.js @@ -1,5 +1,3 @@ -import { URL_DEEPLFREE_TRAN } from "../config"; - let id = 1e4 * Math.round(1e4 * Math.random()); export const genDeeplFree = ({ text, from, to }) => { @@ -37,6 +35,7 @@ export const genDeeplFree = ({ text, from, to }) => { (id + 3) % 13 === 0 || (id + 5) % 29 === 0 ? 'method" : "' : 'method": "' ); + const input = "https://www2.deepl.com/jsonrpc"; const init = { headers: { "Content-Type": "application/json", @@ -54,5 +53,5 @@ export const genDeeplFree = ({ text, from, to }) => { body, }; - return [URL_DEEPLFREE_TRAN, init]; + return [input, init]; }; diff --git a/src/apis/index.js b/src/apis/index.js index f2d2599..452e6f6 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -3,7 +3,6 @@ import { fetchData } from "../libs/fetch"; import { URL_CACHE_TRAN, KV_SALT_SYNC, - URL_GOOGLE_TRAN, OPT_LANGS_BAIDU, OPT_LANGS_TENCENT, OPT_LANGS_SPECIAL, @@ -54,7 +53,7 @@ export const apiGoogleLangdetect = async (text) => { tl: "zh-CN", q: text, }; - const input = `${URL_GOOGLE_TRAN}?${queryString.stringify(params)}`; + const input = `https://translate.googleapis.com/translate_a/single?${queryString.stringify(params)}`; const init = { headers: { "Content-type": "application/json", diff --git a/src/apis/trans.js b/src/apis/trans.js index 47c8992..edb3ab5 100644 --- a/src/apis/trans.js +++ b/src/apis/trans.js @@ -26,9 +26,6 @@ import { OPT_TRANS_CUSTOMIZE_3, OPT_TRANS_CUSTOMIZE_4, OPT_TRANS_CUSTOMIZE_5, - URL_MICROSOFT_TRAN, - URL_TENCENT_TRANSMART, - URL_VOLCENGINE_TRAN, INPUT_PLACE_URL, INPUT_PLACE_FROM, INPUT_PLACE_TO, @@ -107,7 +104,7 @@ const genMicrosoft = async ({ text, from, to }) => { to, "api-version": "3.0", }; - const input = `${URL_MICROSOFT_TRAN}?${queryString.stringify(params)}`; + const input = `https://api-edge.cognitive.microsofttranslator.com/translate?${queryString.stringify(params)}`; const init = { headers: { "Content-type": "application/json", @@ -199,6 +196,7 @@ const genTencent = ({ text, from, to }) => { }, }; + const input = "https://transmart.qq.com/api/imt"; const init = { headers: { "Content-Type": "application/json", @@ -210,7 +208,7 @@ const genTencent = ({ text, from, to }) => { body: JSON.stringify(data), }; - return [URL_TENCENT_TRANSMART, init]; + return [input, init]; }; const genVolcengine = ({ text, from, to }) => { @@ -220,6 +218,7 @@ const genVolcengine = ({ text, from, to }) => { text: text, }; + const input = "https://translate.volcengine.com/crx/translate/v1"; const init = { headers: { "Content-type": "application/json", @@ -228,7 +227,7 @@ const genVolcengine = ({ text, from, to }) => { body: JSON.stringify(data), }; - return [URL_VOLCENGINE_TRAN, init]; + return [input, init]; }; const genOpenAI = ({ diff --git a/src/config/api.js b/src/config/api.js new file mode 100644 index 0000000..86f98c5 --- /dev/null +++ b/src/config/api.js @@ -0,0 +1,491 @@ +export const DEFAULT_HTTP_TIMEOUT = 10000; // 调用超时时间 +export const DEFAULT_FETCH_LIMIT = 10; // 默认最大任务数量 +export const DEFAULT_FETCH_INTERVAL = 100; // 默认任务间隔时间 + +export const INPUT_PLACE_URL = "{{url}}"; // 占位符 +export const INPUT_PLACE_FROM = "{{from}}"; // 占位符 +export const INPUT_PLACE_TO = "{{to}}"; // 占位符 +export const INPUT_PLACE_TEXT = "{{text}}"; // 占位符 +export const INPUT_PLACE_KEY = "{{key}}"; // 占位符 +export const INPUT_PLACE_MODEL = "{{model}}"; // 占位符 + +export const OPT_DICT_BAIDU = "Baidu"; + +export const OPT_TRANS_GOOGLE = "Google"; +export const OPT_TRANS_GOOGLE_2 = "Google2"; +export const OPT_TRANS_MICROSOFT = "Microsoft"; +export const OPT_TRANS_DEEPL = "DeepL"; +export const OPT_TRANS_DEEPLX = "DeepLX"; +export const OPT_TRANS_DEEPLFREE = "DeepLFree"; +export const OPT_TRANS_NIUTRANS = "NiuTrans"; +export const OPT_TRANS_BAIDU = "Baidu"; +export const OPT_TRANS_TENCENT = "Tencent"; +export const OPT_TRANS_VOLCENGINE = "Volcengine"; +export const OPT_TRANS_OPENAI = "OpenAI"; +export const OPT_TRANS_OPENAI_2 = "OpenAI2"; +export const OPT_TRANS_OPENAI_3 = "OpenAI3"; +export const OPT_TRANS_GEMINI = "Gemini"; +export const OPT_TRANS_GEMINI_2 = "Gemini2"; +export const OPT_TRANS_CLAUDE = "Claude"; +export const OPT_TRANS_CLOUDFLAREAI = "CloudflareAI"; +export const OPT_TRANS_OLLAMA = "Ollama"; +export const OPT_TRANS_OLLAMA_2 = "Ollama2"; +export const OPT_TRANS_OLLAMA_3 = "Ollama3"; +export const OPT_TRANS_OPENROUTER = "OpenRouter"; +export const OPT_TRANS_CUSTOMIZE = "Custom"; +export const OPT_TRANS_CUSTOMIZE_2 = "Custom2"; +export const OPT_TRANS_CUSTOMIZE_3 = "Custom3"; +export const OPT_TRANS_CUSTOMIZE_4 = "Custom4"; +export const OPT_TRANS_CUSTOMIZE_5 = "Custom5"; +export const OPT_TRANS_ALL = [ + OPT_TRANS_GOOGLE, + OPT_TRANS_GOOGLE_2, + OPT_TRANS_MICROSOFT, + OPT_TRANS_BAIDU, + OPT_TRANS_TENCENT, + OPT_TRANS_VOLCENGINE, + OPT_TRANS_DEEPL, + OPT_TRANS_DEEPLFREE, + OPT_TRANS_DEEPLX, + OPT_TRANS_NIUTRANS, + OPT_TRANS_OPENAI, + OPT_TRANS_OPENAI_2, + OPT_TRANS_OPENAI_3, + OPT_TRANS_GEMINI, + OPT_TRANS_GEMINI_2, + OPT_TRANS_CLAUDE, + OPT_TRANS_CLOUDFLAREAI, + OPT_TRANS_OLLAMA, + OPT_TRANS_OLLAMA_2, + OPT_TRANS_OLLAMA_3, + OPT_TRANS_OPENROUTER, + OPT_TRANS_CUSTOMIZE, + OPT_TRANS_CUSTOMIZE_2, + OPT_TRANS_CUSTOMIZE_3, + OPT_TRANS_CUSTOMIZE_4, + 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 - 简体中文"], + ["zh-TW", "Traditional Chinese - 繁體中文"], + ["ar", "Arabic - العربية"], + ["bg", "Bulgarian - Български"], + ["ca", "Catalan - Català"], + ["hr", "Croatian - Hrvatski"], + ["cs", "Czech - Čeština"], + ["da", "Danish - Dansk"], + ["nl", "Dutch - Nederlands"], + ["fi", "Finnish - Suomi"], + ["fr", "French - Français"], + ["de", "German - Deutsch"], + ["el", "Greek - Ελληνικά"], + ["hi", "Hindi - हिन्दी"], + ["hu", "Hungarian - Magyar"], + ["id", "Indonesian - Indonesia"], + ["it", "Italian - Italiano"], + ["ja", "Japanese - 日本語"], + ["ko", "Korean - 한국어"], + ["ms", "Malay - Melayu"], + ["mt", "Maltese - Malti"], + ["nb", "Norwegian - Norsk Bokmål"], + ["pl", "Polish - Polski"], + ["pt", "Portuguese - Português"], + ["ro", "Romanian - Română"], + ["ru", "Russian - Русский"], + ["sk", "Slovak - Slovenčina"], + ["sl", "Slovenian - Slovenščina"], + ["es", "Spanish - Español"], + ["sv", "Swedish - Svenska"], + ["ta", "Tamil - தமிழ்"], + ["te", "Telugu - తెలుగు"], + ["th", "Thai - ไทย"], + ["tr", "Turkish - Türkçe"], + ["uk", "Ukrainian - Українська"], + ["vi", "Vietnamese - Tiếng Việt"], +]; +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])), + [OPT_TRANS_MICROSOFT]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["auto", ""], + ["zh-CN", "zh-Hans"], + ["zh-TW", "zh-Hant"], + ]), + [OPT_TRANS_DEEPL]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), + ["auto", ""], + ["zh-CN", "ZH"], + ["zh-TW", "ZH"], + ]), + [OPT_TRANS_DEEPLFREE]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), + ["auto", "auto"], + ["zh-CN", "ZH"], + ["zh-TW", "ZH"], + ]), + [OPT_TRANS_DEEPLX]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), + ["auto", "auto"], + ["zh-CN", "ZH"], + ["zh-TW", "ZH"], + ]), + [OPT_TRANS_NIUTRANS]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["auto", "auto"], + ["zh-CN", "zh"], + ["zh-TW", "cht"], + ]), + [OPT_TRANS_VOLCENGINE]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["auto", "auto"], + ["zh-CN", "zh"], + ["zh-TW", "zh-Hant"], + ]), + [OPT_TRANS_BAIDU]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["zh-CN", "zh"], + ["zh-TW", "cht"], + ["ar", "ara"], + ["bg", "bul"], + ["ca", "cat"], + ["hr", "hrv"], + ["da", "dan"], + ["fi", "fin"], + ["fr", "fra"], + ["hi", "mai"], + ["ja", "jp"], + ["ko", "kor"], + ["ms", "may"], + ["mt", "mlt"], + ["nb", "nor"], + ["ro", "rom"], + ["ru", "ru"], + ["sl", "slo"], + ["es", "spa"], + ["sv", "swe"], + ["ta", "tam"], + ["te", "tel"], + ["uk", "ukr"], + ["vi", "vie"], + ]), + [OPT_TRANS_TENCENT]: new Map([ + ["auto", "auto"], + ["zh-CN", "zh"], + ["zh-TW", "zh"], + ["en", "en"], + ["ar", "ar"], + ["de", "de"], + ["ru", "ru"], + ["fr", "fr"], + ["fi", "fil"], + ["ko", "ko"], + ["ms", "ms"], + ["pt", "pt"], + ["ja", "ja"], + ["th", "th"], + ["tr", "tr"], + ["es", "es"], + ["it", "it"], + ["hi", "hi"], + ["id", "id"], + ["vi", "vi"], + ]), + [OPT_TRANS_OPENAI]: new Map( + OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) + ), + [OPT_TRANS_OPENAI_2]: new Map( + OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) + ), + [OPT_TRANS_OPENAI_3]: 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_OLLAMA_2]: new Map( + OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) + ), + [OPT_TRANS_OLLAMA_3]: 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]), + ["auto", ""], + ]), + [OPT_TRANS_CUSTOMIZE_2]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["auto", ""], + ]), + [OPT_TRANS_CUSTOMIZE_3]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["auto", ""], + ]), + [OPT_TRANS_CUSTOMIZE_4]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["auto", ""], + ]), + [OPT_TRANS_CUSTOMIZE_5]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key]), + ["auto", ""], + ]), +}; +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 defaultApi = { + apiSlug: "", // 唯一标识 + apiName: "", // 接口名称 + url: "", + key: "", + model: "", // 模型名称 + systemPrompt: `You are a professional, authentic machine translation engine.`, + userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`, + customHeader: "", + customBody: "", + reqHook: "", // request 钩子函数 + resHook: "", // response 钩子函数 + fetchLimit: DEFAULT_FETCH_LIMIT, // 最大请求数量 + fetchInterval: DEFAULT_FETCH_INTERVAL, // 请求间隔时间 + httpTimeout: DEFAULT_HTTP_TIMEOUT, // 请求超时时间 + temperature: 0, + maxTokens: 2048, + think: false, + thinkIgnore: "qwen3,deepseek-r1", + isDisabled: false, // 是否不显示 +}; +const defaultCustomApi = { + ...defaultApi, + reqHook: `// Request Hook +(text, from, to, url, key) => [ + url, + { + headers: { + "Content-Type": "application/json", + Authorization: \`Bearer \${key}\`, + }, + method: "GET", + body: JSON.stringify({ text, from, to }), + }, +];`, + resHook: `// Response Hook +(res, text, from, to) => [res.text, to === res.src];`, +}; +const defaultOpenaiApi = { + ...defaultApi, + url: "https://api.openai.com/v1/chat/completions", + model: "gpt-4", + fetchLimit: 1, +}; +const defaultOllamaApi = { + ...defaultApi, + url: "http://localhost:11434/api/generate", + model: "llama3.1", +}; +export const DEFAULT_TRANS_APIS = { + [OPT_TRANS_GOOGLE]: { + ...defaultApi, + apiSlug: OPT_TRANS_GOOGLE, + apiName: OPT_TRANS_GOOGLE, + url: "https://translate.googleapis.com/translate_a/single", + }, + [OPT_TRANS_GOOGLE_2]: { + ...defaultApi, + apiSlug: OPT_TRANS_GOOGLE_2, + apiName: OPT_TRANS_GOOGLE_2, + url: "https://translate-pa.googleapis.com/v1/translateHtml", + key: "AIzaSyATBXajvzQLTDHEQbcpq0Ihe0vWDHmO520", + }, + [OPT_TRANS_MICROSOFT]: { + ...defaultApi, + apiSlug: OPT_TRANS_MICROSOFT, + apiName: OPT_TRANS_MICROSOFT, + }, + [OPT_TRANS_BAIDU]: { + ...defaultApi, + apiSlug: OPT_TRANS_BAIDU, + apiName: OPT_TRANS_BAIDU, + }, + [OPT_TRANS_TENCENT]: { + ...defaultApi, + apiSlug: OPT_TRANS_TENCENT, + apiName: OPT_TRANS_TENCENT, + }, + [OPT_TRANS_VOLCENGINE]: { + ...defaultApi, + apiSlug: OPT_TRANS_VOLCENGINE, + apiName: OPT_TRANS_VOLCENGINE, + }, + [OPT_TRANS_DEEPL]: { + ...defaultApi, + apiSlug: OPT_TRANS_DEEPL, + apiName: OPT_TRANS_DEEPL, + url: "https://api-free.deepl.com/v2/translate", + fetchLimit: 1, + }, + [OPT_TRANS_DEEPLFREE]: { + ...defaultApi, + apiSlug: OPT_TRANS_DEEPLFREE, + apiName: OPT_TRANS_DEEPLFREE, + fetchLimit: 1, + }, + [OPT_TRANS_DEEPLX]: { + ...defaultApi, + apiSlug: OPT_TRANS_DEEPLX, + apiName: OPT_TRANS_DEEPLX, + url: "http://localhost:1188/translate", + fetchLimit: 1, + }, + [OPT_TRANS_NIUTRANS]: { + ...defaultApi, + apiSlug: OPT_TRANS_NIUTRANS, + apiName: OPT_TRANS_NIUTRANS, + url: "https://api.niutrans.com/NiuTransServer/translation", + dictNo: "", + memoryNo: "", + }, + [OPT_TRANS_OPENAI]: { + ...defaultOpenaiApi, + apiSlug: OPT_TRANS_OPENAI, + apiName: OPT_TRANS_OPENAI, + }, + [OPT_TRANS_OPENAI_2]: { + ...defaultOpenaiApi, + apiSlug: OPT_TRANS_OPENAI_2, + apiName: OPT_TRANS_OPENAI_2, + }, + [OPT_TRANS_OPENAI_3]: { + ...defaultOpenaiApi, + apiSlug: OPT_TRANS_OPENAI_3, + apiName: OPT_TRANS_OPENAI_3, + }, + [OPT_TRANS_GEMINI]: { + ...defaultApi, + apiSlug: OPT_TRANS_GEMINI, + apiName: OPT_TRANS_GEMINI, + url: `https://generativelanguage.googleapis.com/v1/models/${INPUT_PLACE_MODEL}:generateContent?key=${INPUT_PLACE_KEY}`, + model: "gemini-2.5-flash", + }, + [OPT_TRANS_GEMINI_2]: { + ...defaultApi, + apiSlug: OPT_TRANS_GEMINI_2, + apiName: OPT_TRANS_GEMINI_2, + url: `https://generativelanguage.googleapis.com/v1beta/openai/chat/completions`, + model: "gemini-2.0-flash", + }, + [OPT_TRANS_CLAUDE]: { + ...defaultApi, + apiSlug: OPT_TRANS_CLAUDE, + apiName: OPT_TRANS_CLAUDE, + url: "https://api.anthropic.com/v1/messages", + model: "claude-3-haiku-20240307", + }, + [OPT_TRANS_CLOUDFLAREAI]: { + ...defaultApi, + apiSlug: OPT_TRANS_CLOUDFLAREAI, + apiName: OPT_TRANS_CLOUDFLAREAI, + url: "https://api.cloudflare.com/client/v4/accounts/{{ACCOUNT_ID}}/ai/run/@cf/meta/m2m100-1.2b", + }, + [OPT_TRANS_OLLAMA]: { + ...defaultOllamaApi, + apiSlug: OPT_TRANS_OLLAMA, + apiName: OPT_TRANS_OLLAMA, + }, + [OPT_TRANS_OLLAMA_2]: { + ...defaultOllamaApi, + apiSlug: OPT_TRANS_OLLAMA_2, + apiName: OPT_TRANS_OLLAMA_2, + }, + [OPT_TRANS_OLLAMA_3]: { + ...defaultOllamaApi, + apiSlug: OPT_TRANS_OLLAMA_3, + apiName: OPT_TRANS_OLLAMA_3, + }, + [OPT_TRANS_OPENROUTER]: { + ...defaultApi, + apiSlug: OPT_TRANS_OPENROUTER, + apiName: "", + url: "https://openrouter.ai/api/v1/chat/completions", + model: "openai/gpt-4o", + }, + [OPT_TRANS_CUSTOMIZE]: { + ...defaultCustomApi, + apiSlug: OPT_TRANS_CUSTOMIZE, + apiName: OPT_TRANS_CUSTOMIZE, + }, + [OPT_TRANS_CUSTOMIZE_2]: { + ...defaultCustomApi, + apiSlug: OPT_TRANS_CUSTOMIZE_2, + apiName: OPT_TRANS_CUSTOMIZE_2, + }, + [OPT_TRANS_CUSTOMIZE_3]: { + ...defaultCustomApi, + apiSlug: OPT_TRANS_CUSTOMIZE_3, + apiName: OPT_TRANS_CUSTOMIZE_3, + }, + [OPT_TRANS_CUSTOMIZE_4]: { + ...defaultCustomApi, + apiSlug: OPT_TRANS_CUSTOMIZE_4, + apiName: OPT_TRANS_CUSTOMIZE_4, + }, + [OPT_TRANS_CUSTOMIZE_5]: { + ...defaultCustomApi, + apiSlug: OPT_TRANS_CUSTOMIZE_5, + apiName: OPT_TRANS_CUSTOMIZE_5, + }, +}; diff --git a/src/config/app.js b/src/config/app.js index 7122385..3b993dd 100644 --- a/src/config/app.js +++ b/src/config/app.js @@ -2,3 +2,6 @@ export const APP_NAME = process.env.REACT_APP_NAME.trim() .split(/\s+/) .join("-"); export const APP_LCNAME = APP_NAME.toLowerCase(); + +export const THEME_LIGHT = "light"; +export const THEME_DARK = "dark"; diff --git a/src/config/client.js b/src/config/client.js new file mode 100644 index 0000000..85ad3ba --- /dev/null +++ b/src/config/client.js @@ -0,0 +1,15 @@ +export const CLIENT_WEB = "web"; +export const CLIENT_CHROME = "chrome"; +export const CLIENT_EDGE = "edge"; +export const CLIENT_FIREFOX = "firefox"; +export const CLIENT_USERSCRIPT = "userscript"; +export const CLIENT_THUNDERBIRD = "thunderbird"; +export const CLIENT_EXTS = [ + CLIENT_CHROME, + CLIENT_EDGE, + CLIENT_FIREFOX, + CLIENT_THUNDERBIRD, +]; + +export const DEFAULT_USER_AGENT = + "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"; diff --git a/src/config/index.js b/src/config/index.js index 9cbdacb..93cba22 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -1,842 +1,9 @@ -import { - DEFAULT_SELECTOR, - DEFAULT_KEEP_SELECTOR, - GLOBAL_KEY, - REMAIN_KEY, - SHADOW_KEY, - DEFAULT_RULE, - DEFAULT_OW_RULE, - BUILTIN_RULES, -} from "./rules"; -import { APP_NAME, APP_LCNAME } from "./app"; -export { I18N, UI_LANGS } from "./i18n"; -export { - GLOBAL_KEY, - REMAIN_KEY, - SHADOW_KEY, - DEFAULT_RULE, - DEFAULT_OW_RULE, - BUILTIN_RULES, - APP_LCNAME, -}; - -export const STOKEY_MSAUTH = `${APP_NAME}_msauth`; -export const STOKEY_BDAUTH = `${APP_NAME}_bdauth`; -export const STOKEY_SETTING = `${APP_NAME}_setting`; -export const STOKEY_RULES = `${APP_NAME}_rules`; -export const STOKEY_WORDS = `${APP_NAME}_words`; -export const STOKEY_SYNC = `${APP_NAME}_sync`; -export const STOKEY_FAB = `${APP_NAME}_fab`; -export const STOKEY_RULESCACHE_PREFIX = `${APP_NAME}_rulescache_`; - -export const CMD_TOGGLE_TRANSLATE = "toggleTranslate"; -export const CMD_TOGGLE_STYLE = "toggleStyle"; -export const CMD_OPEN_OPTIONS = "openOptions"; -export const CMD_OPEN_TRANBOX = "openTranbox"; - -export const CLIENT_WEB = "web"; -export const CLIENT_CHROME = "chrome"; -export const CLIENT_EDGE = "edge"; -export const CLIENT_FIREFOX = "firefox"; -export const CLIENT_USERSCRIPT = "userscript"; -export const CLIENT_THUNDERBIRD = "thunderbird"; -export const CLIENT_EXTS = [ - CLIENT_CHROME, - CLIENT_EDGE, - CLIENT_FIREFOX, - CLIENT_THUNDERBIRD, -]; - -export const KV_RULES_KEY = "kiss-rules.json"; -export const KV_WORDS_KEY = "kiss-words.json"; -export const KV_RULES_SHARE_KEY = "kiss-rules-share.json"; -export const KV_SETTING_KEY = "kiss-setting.json"; -export const KV_SALT_SYNC = "KISS-Translator-SYNC"; -export const KV_SALT_SHARE = "KISS-Translator-SHARE"; - -export const CACHE_NAME = `${APP_NAME}_cache`; - -export const MSG_FETCH = "fetch"; -export const MSG_GET_HTTPCACHE = "get_httpcache"; -export const MSG_PUT_HTTPCACHE = "put_httpcache"; -export const MSG_OPEN_OPTIONS = "open_options"; -export const MSG_SAVE_RULE = "save_rule"; -export const MSG_TRANS_TOGGLE = "trans_toggle"; -export const MSG_TRANS_TOGGLE_STYLE = "trans_toggle_style"; -export const MSG_OPEN_TRANBOX = "open_tranbox"; -export const MSG_TRANS_GETRULE = "trans_getrule"; -export const MSG_TRANS_PUTRULE = "trans_putrule"; -export const MSG_TRANS_CURRULE = "trans_currule"; -export const MSG_CONTEXT_MENUS = "context_menus"; -export const MSG_COMMAND_SHORTCUTS = "command_shortcuts"; -export const MSG_INJECT_JS = "inject_js"; -export const MSG_INJECT_CSS = "inject_css"; -export const MSG_UPDATE_CSP = "update_csp"; - -export const THEME_LIGHT = "light"; -export const THEME_DARK = "dark"; - -export const URL_KISS_WORKER = "https://github.com/fishjar/kiss-worker"; -export const URL_KISS_PROXY = "https://github.com/fishjar/kiss-proxy"; -export const URL_KISS_RULES = "https://github.com/fishjar/kiss-rules"; -export const URL_KISS_RULES_NEW_ISSUE = - "https://github.com/fishjar/kiss-rules/issues/new"; -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_GOOGLE_TRAN2 = - "https://translate-pa.googleapis.com/v1/translateHtml"; -export const DEFAULT_GOOGLE_API_KEY = "AIzaSyATBXajvzQLTDHEQbcpq0Ihe0vWDHmO520"; - -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"; -export const URL_BAIDU_WEB = "https://fanyi.baidu.com/"; -export const URL_BAIDU_TRANSAPI = "https://fanyi.baidu.com/transapi"; -export const URL_BAIDU_TRANSAPI_V2 = "https://fanyi.baidu.com/v2transapi"; -export const URL_DEEPLFREE_TRAN = "https://www2.deepl.com/jsonrpc"; -export const URL_TENCENT_TRANSMART = "https://transmart.qq.com/api/imt"; -export const URL_VOLCENGINE_TRAN = - "https://translate.volcengine.com/crx/translate/v1"; -export const URL_NIUTRANS_REG = - "https://niutrans.com/login?active=3&userSource=kiss-translator"; - -export const DEFAULT_USER_AGENT = - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"; - -export const OPT_DICT_BAIDU = "Baidu"; - -export const OPT_TRANS_GOOGLE = "Google"; -export const OPT_TRANS_GOOGLE_2 = "Google2"; -export const OPT_TRANS_MICROSOFT = "Microsoft"; -export const OPT_TRANS_DEEPL = "DeepL"; -export const OPT_TRANS_DEEPLX = "DeepLX"; -export const OPT_TRANS_DEEPLFREE = "DeepLFree"; -export const OPT_TRANS_NIUTRANS = "NiuTrans"; -export const OPT_TRANS_BAIDU = "Baidu"; -export const OPT_TRANS_TENCENT = "Tencent"; -export const OPT_TRANS_VOLCENGINE = "Volcengine"; -export const OPT_TRANS_OPENAI = "OpenAI"; -export const OPT_TRANS_OPENAI_2 = "OpenAI2"; -export const OPT_TRANS_OPENAI_3 = "OpenAI3"; -export const OPT_TRANS_GEMINI = "Gemini"; -export const OPT_TRANS_GEMINI_2 = "Gemini2"; -export const OPT_TRANS_CLAUDE = "Claude"; -export const OPT_TRANS_CLOUDFLAREAI = "CloudflareAI"; -export const OPT_TRANS_OLLAMA = "Ollama"; -export const OPT_TRANS_OLLAMA_2 = "Ollama2"; -export const OPT_TRANS_OLLAMA_3 = "Ollama3"; -export const OPT_TRANS_OPENROUTER = "OpenRouter"; -export const OPT_TRANS_CUSTOMIZE = "Custom"; -export const OPT_TRANS_CUSTOMIZE_2 = "Custom2"; -export const OPT_TRANS_CUSTOMIZE_3 = "Custom3"; -export const OPT_TRANS_CUSTOMIZE_4 = "Custom4"; -export const OPT_TRANS_CUSTOMIZE_5 = "Custom5"; -export const OPT_TRANS_ALL = [ - OPT_TRANS_GOOGLE, - OPT_TRANS_GOOGLE_2, - OPT_TRANS_MICROSOFT, - OPT_TRANS_BAIDU, - OPT_TRANS_TENCENT, - OPT_TRANS_VOLCENGINE, - OPT_TRANS_DEEPL, - OPT_TRANS_DEEPLFREE, - OPT_TRANS_DEEPLX, - OPT_TRANS_NIUTRANS, - OPT_TRANS_OPENAI, - OPT_TRANS_OPENAI_2, - OPT_TRANS_OPENAI_3, - OPT_TRANS_GEMINI, - OPT_TRANS_GEMINI_2, - OPT_TRANS_CLAUDE, - OPT_TRANS_CLOUDFLAREAI, - OPT_TRANS_OLLAMA, - OPT_TRANS_OLLAMA_2, - OPT_TRANS_OLLAMA_3, - OPT_TRANS_OPENROUTER, - OPT_TRANS_CUSTOMIZE, - OPT_TRANS_CUSTOMIZE_2, - OPT_TRANS_CUSTOMIZE_3, - OPT_TRANS_CUSTOMIZE_4, - 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 - 简体中文"], - ["zh-TW", "Traditional Chinese - 繁體中文"], - ["ar", "Arabic - العربية"], - ["bg", "Bulgarian - Български"], - ["ca", "Catalan - Català"], - ["hr", "Croatian - Hrvatski"], - ["cs", "Czech - Čeština"], - ["da", "Danish - Dansk"], - ["nl", "Dutch - Nederlands"], - ["fi", "Finnish - Suomi"], - ["fr", "French - Français"], - ["de", "German - Deutsch"], - ["el", "Greek - Ελληνικά"], - ["hi", "Hindi - हिन्दी"], - ["hu", "Hungarian - Magyar"], - ["id", "Indonesian - Indonesia"], - ["it", "Italian - Italiano"], - ["ja", "Japanese - 日本語"], - ["ko", "Korean - 한국어"], - ["ms", "Malay - Melayu"], - ["mt", "Maltese - Malti"], - ["nb", "Norwegian - Norsk Bokmål"], - ["pl", "Polish - Polski"], - ["pt", "Portuguese - Português"], - ["ro", "Romanian - Română"], - ["ru", "Russian - Русский"], - ["sk", "Slovak - Slovenčina"], - ["sl", "Slovenian - Slovenščina"], - ["es", "Spanish - Español"], - ["sv", "Swedish - Svenska"], - ["ta", "Tamil - தமிழ்"], - ["te", "Telugu - తెలుగు"], - ["th", "Thai - ไทย"], - ["tr", "Turkish - Türkçe"], - ["uk", "Ukrainian - Українська"], - ["vi", "Vietnamese - Tiếng Việt"], -]; -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])), - [OPT_TRANS_MICROSOFT]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key]), - ["auto", ""], - ["zh-CN", "zh-Hans"], - ["zh-TW", "zh-Hant"], - ]), - [OPT_TRANS_DEEPL]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), - ["auto", ""], - ["zh-CN", "ZH"], - ["zh-TW", "ZH"], - ]), - [OPT_TRANS_DEEPLFREE]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), - ["auto", "auto"], - ["zh-CN", "ZH"], - ["zh-TW", "ZH"], - ]), - [OPT_TRANS_DEEPLX]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), - ["auto", "auto"], - ["zh-CN", "ZH"], - ["zh-TW", "ZH"], - ]), - [OPT_TRANS_NIUTRANS]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key]), - ["auto", "auto"], - ["zh-CN", "zh"], - ["zh-TW", "cht"], - ]), - [OPT_TRANS_VOLCENGINE]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key]), - ["auto", "auto"], - ["zh-CN", "zh"], - ["zh-TW", "zh-Hant"], - ]), - [OPT_TRANS_BAIDU]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key]), - ["zh-CN", "zh"], - ["zh-TW", "cht"], - ["ar", "ara"], - ["bg", "bul"], - ["ca", "cat"], - ["hr", "hrv"], - ["da", "dan"], - ["fi", "fin"], - ["fr", "fra"], - ["hi", "mai"], - ["ja", "jp"], - ["ko", "kor"], - ["ms", "may"], - ["mt", "mlt"], - ["nb", "nor"], - ["ro", "rom"], - ["ru", "ru"], - ["sl", "slo"], - ["es", "spa"], - ["sv", "swe"], - ["ta", "tam"], - ["te", "tel"], - ["uk", "ukr"], - ["vi", "vie"], - ]), - [OPT_TRANS_TENCENT]: new Map([ - ["auto", "auto"], - ["zh-CN", "zh"], - ["zh-TW", "zh"], - ["en", "en"], - ["ar", "ar"], - ["de", "de"], - ["ru", "ru"], - ["fr", "fr"], - ["fi", "fil"], - ["ko", "ko"], - ["ms", "ms"], - ["pt", "pt"], - ["ja", "ja"], - ["th", "th"], - ["tr", "tr"], - ["es", "es"], - ["it", "it"], - ["hi", "hi"], - ["id", "id"], - ["vi", "vi"], - ]), - [OPT_TRANS_OPENAI]: new Map( - OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) - ), - [OPT_TRANS_OPENAI_2]: new Map( - OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) - ), - [OPT_TRANS_OPENAI_3]: 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_OLLAMA_2]: new Map( - OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) - ), - [OPT_TRANS_OLLAMA_3]: 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]), - ["auto", ""], - ]), - [OPT_TRANS_CUSTOMIZE_2]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key]), - ["auto", ""], - ]), - [OPT_TRANS_CUSTOMIZE_3]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key]), - ["auto", ""], - ]), - [OPT_TRANS_CUSTOMIZE_4]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key]), - ["auto", ""], - ]), - [OPT_TRANS_CUSTOMIZE_5]: new Map([ - ...OPT_LANGS_FROM.map(([key]) => [key, key]), - ["auto", ""], - ]), -}; -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"); - -export const OPT_STYLE_NONE = "style_none"; // 无 -export const OPT_STYLE_LINE = "under_line"; // 下划线 -export const OPT_STYLE_DOTLINE = "dot_line"; // 点状线 -export const OPT_STYLE_DASHLINE = "dash_line"; // 虚线 -export const OPT_STYLE_DASHBOX = "dash_box"; // 虚线框 -export const OPT_STYLE_WAVYLINE = "wavy_line"; // 波浪线 -export const OPT_STYLE_FUZZY = "fuzzy"; // 模糊 -export const OPT_STYLE_HIGHLIGHT = "highlight"; // 高亮 -export const OPT_STYLE_BLOCKQUOTE = "blockquote"; // 引用 -export const OPT_STYLE_DIY = "diy_style"; // 自定义样式 -export const OPT_STYLE_ALL = [ - OPT_STYLE_NONE, - OPT_STYLE_LINE, - OPT_STYLE_DOTLINE, - OPT_STYLE_DASHLINE, - OPT_STYLE_DASHBOX, - OPT_STYLE_WAVYLINE, - OPT_STYLE_FUZZY, - OPT_STYLE_HIGHLIGHT, - OPT_STYLE_BLOCKQUOTE, - OPT_STYLE_DIY, -]; -export const OPT_STYLE_USE_COLOR = [ - OPT_STYLE_LINE, - OPT_STYLE_DOTLINE, - OPT_STYLE_DASHLINE, - OPT_STYLE_DASHBOX, - OPT_STYLE_WAVYLINE, - OPT_STYLE_HIGHLIGHT, - OPT_STYLE_BLOCKQUOTE, -]; - -export const OPT_TIMING_PAGESCROLL = "mk_pagescroll"; // 滚动加载翻译 -export const OPT_TIMING_PAGEOPEN = "mk_pageopen"; // 直接翻译到底 -export const OPT_TIMING_MOUSEOVER = "mk_mouseover"; -export const OPT_TIMING_CONTROL = "mk_ctrlKey"; -export const OPT_TIMING_SHIFT = "mk_shiftKey"; -export const OPT_TIMING_ALT = "mk_altKey"; -export const OPT_TIMING_ALL = [ - OPT_TIMING_PAGESCROLL, - OPT_TIMING_PAGEOPEN, - OPT_TIMING_MOUSEOVER, - OPT_TIMING_CONTROL, - OPT_TIMING_SHIFT, - OPT_TIMING_ALT, -]; - -export const DEFAULT_FETCH_LIMIT = 10; // 默认最大任务数量 -export const DEFAULT_FETCH_INTERVAL = 100; // 默认任务间隔时间 - -export const INPUT_PLACE_URL = "{{url}}"; // 占位符 -export const INPUT_PLACE_FROM = "{{from}}"; // 占位符 -export const INPUT_PLACE_TO = "{{to}}"; // 占位符 -export const INPUT_PLACE_TEXT = "{{text}}"; // 占位符 -export const INPUT_PLACE_KEY = "{{key}}"; // 占位符 -export const INPUT_PLACE_MODEL = "{{model}}"; // 占位符 - -export const DEFAULT_COLOR = "#209CEE"; // 默认高亮背景色/线条颜色 - -export const DEFAULT_TRANS_TAG = "font"; -export const DEFAULT_SELECT_STYLE = - "-webkit-line-clamp: unset; max-height: none; height: auto;"; - -// 全局规则 -export const GLOBLA_RULE = { - pattern: "*", // 匹配网址 - selector: DEFAULT_SELECTOR, // 选择器 - keepSelector: DEFAULT_KEEP_SELECTOR, // 保留元素选择器 - terms: "", // 专业术语 - translator: OPT_TRANS_MICROSOFT, // 翻译服务 - fromLang: "auto", // 源语言 - toLang: "zh-CN", // 目标语言 - textStyle: OPT_STYLE_DASHLINE, // 译文样式 - transOpen: "false", // 开启翻译 - bgColor: "", // 译文颜色 - textDiyStyle: "", // 自定义译文样式 - selectStyle: DEFAULT_SELECT_STYLE, // 选择器节点样式 - parentStyle: DEFAULT_SELECT_STYLE, // 选择器父节点样式 - injectJs: "", // 注入JS - injectCss: "", // 注入CSS - transOnly: "false", // 是否仅显示译文 - transTiming: OPT_TIMING_PAGESCROLL, // 翻译时机/鼠标悬停翻译 - transTag: DEFAULT_TRANS_TAG, // 译文元素标签 - transTitle: "false", // 是否同时翻译页面标题 - transSelected: "true", // 是否启用划词翻译 - detectRemote: "false", // 是否使用远程语言检测 - skipLangs: [], // 不翻译的语言 - fixerSelector: "", // 修复函数选择器 - fixerFunc: "-", // 修复函数 - transStartHook: "", // 钩子函数 - transEndHook: "", // 钩子函数 - transRemoveHook: "", // 钩子函数 -}; - -// 输入框翻译 -export const OPT_INPUT_TRANS_SIGNS = ["/", "//", "\\", "\\\\", ">", ">>"]; -export const DEFAULT_INPUT_SHORTCUT = ["AltLeft", "KeyI"]; -export const DEFAULT_INPUT_RULE = { - transOpen: true, - translator: OPT_TRANS_MICROSOFT, - fromLang: "auto", - toLang: "en", - triggerShortcut: DEFAULT_INPUT_SHORTCUT, - triggerCount: 1, - triggerTime: 200, - transSign: OPT_INPUT_TRANS_SIGNS[0], -}; - -// 划词翻译 -export const PHONIC_MAP = { - en_phonic: ["英", "uk"], - us_phonic: ["美", "en"], -}; -export const OPT_TRANBOX_TRIGGER_CLICK = "click"; -export const OPT_TRANBOX_TRIGGER_HOVER = "hover"; -export const OPT_TRANBOX_TRIGGER_SELECT = "select"; -export const OPT_TRANBOX_TRIGGER_ALL = [ - OPT_TRANBOX_TRIGGER_CLICK, - OPT_TRANBOX_TRIGGER_HOVER, - OPT_TRANBOX_TRIGGER_SELECT, -]; -export const DEFAULT_TRANBOX_SHORTCUT = ["AltLeft", "KeyS"]; -export const DEFAULT_TRANBOX_SETTING = { - // transOpen: true, // 是否启用划词翻译(作废,移至rule) - translator: OPT_TRANS_MICROSOFT, - fromLang: "auto", - toLang: "zh-CN", - toLang2: "en", - tranboxShortcut: DEFAULT_TRANBOX_SHORTCUT, - btnOffsetX: 10, - btnOffsetY: 10, - boxOffsetX: 0, - boxOffsetY: 10, - hideTranBtn: false, // 是否隐藏翻译按钮 - hideClickAway: false, // 是否点击外部关闭弹窗 - simpleStyle: false, // 是否简洁界面 - followSelection: false, // 翻译框是否跟随选中文本 - triggerMode: OPT_TRANBOX_TRIGGER_CLICK, // 触发翻译方式 - extStyles: "", // 附加样式 - enDict: OPT_DICT_BAIDU, // 英文词典 -}; - -// 订阅列表 -export const DEFAULT_SUBRULES_LIST = [ - { - url: process.env.REACT_APP_RULESURL, - selected: true, - }, - { - url: process.env.REACT_APP_RULESURL_ON, - selected: false, - }, - { - url: process.env.REACT_APP_RULESURL_OFF, - selected: false, - }, -]; - -export const DEFAULT_HTTP_TIMEOUT = 5000; // 调用超时时间 -export const DEFAULT_CACHE_TIMEOUT = 3600 * 24 * 7; // 缓存超时时间(7天) - -// 翻译接口 -const defaultCustomApi = { - url: "", - key: "", - customOption: "", // (作废) - reqHook: "", // request 钩子函数 - resHook: "", // response 钩子函数 - fetchLimit: DEFAULT_FETCH_LIMIT, - fetchInterval: DEFAULT_FETCH_INTERVAL, - apiName: "", - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, -}; -const defaultOpenaiApi = { - url: "https://api.openai.com/v1/chat/completions", - key: "", - model: "gpt-4", - systemPrompt: `You are a professional, authentic machine translation engine.`, - userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`, - customHeader: "", - customBody: "", - temperature: 0, - maxTokens: 256, - fetchLimit: 1, - fetchInterval: 500, - apiName: "", - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT * 2, -}; -const defaultOllamaApi = { - url: "http://localhost:11434/api/generate", - key: "", - model: "llama3.1", - systemPrompt: `You are a professional, authentic machine translation engine.`, - userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`, - customHeader: "", - customBody: "", - think: false, - thinkIgnore: `qwen3,deepseek-r1`, - fetchLimit: 1, - fetchInterval: 500, - apiName: "", - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT * 2, -}; -export const DEFAULT_TRANS_APIS = { - [OPT_TRANS_GOOGLE]: { - url: URL_GOOGLE_TRAN, - key: "", - fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量 - fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间 - apiName: OPT_TRANS_GOOGLE, // 接口自定义名称 - isDisabled: false, // 是否禁用 - httpTimeout: DEFAULT_HTTP_TIMEOUT, // 超时时间 - }, - [OPT_TRANS_GOOGLE_2]: { - url: URL_GOOGLE_TRAN2, - key: DEFAULT_GOOGLE_API_KEY, - fetchLimit: DEFAULT_FETCH_LIMIT, - fetchInterval: DEFAULT_FETCH_INTERVAL, - apiName: OPT_TRANS_GOOGLE_2, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_MICROSOFT]: { - fetchLimit: DEFAULT_FETCH_LIMIT, - fetchInterval: DEFAULT_FETCH_INTERVAL, - apiName: OPT_TRANS_MICROSOFT, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_BAIDU]: { - fetchLimit: DEFAULT_FETCH_LIMIT, - fetchInterval: DEFAULT_FETCH_INTERVAL, - apiName: OPT_TRANS_BAIDU, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_TENCENT]: { - fetchLimit: DEFAULT_FETCH_LIMIT, - fetchInterval: DEFAULT_FETCH_INTERVAL, - apiName: OPT_TRANS_TENCENT, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_VOLCENGINE]: { - fetchLimit: DEFAULT_FETCH_LIMIT, - fetchInterval: DEFAULT_FETCH_INTERVAL, - apiName: OPT_TRANS_VOLCENGINE, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_DEEPL]: { - url: "https://api-free.deepl.com/v2/translate", - key: "", - fetchLimit: 1, - fetchInterval: 500, - apiName: OPT_TRANS_DEEPL, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_DEEPLFREE]: { - fetchLimit: 1, - fetchInterval: 500, - apiName: OPT_TRANS_DEEPLFREE, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_DEEPLX]: { - url: "http://localhost:1188/translate", - key: "", - fetchLimit: 1, - fetchInterval: 500, - apiName: OPT_TRANS_DEEPLX, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_NIUTRANS]: { - url: "https://api.niutrans.com/NiuTransServer/translation", - key: "", - dictNo: "", - memoryNo: "", - fetchLimit: DEFAULT_FETCH_LIMIT, - fetchInterval: DEFAULT_FETCH_INTERVAL, - apiName: OPT_TRANS_NIUTRANS, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - }, - [OPT_TRANS_OPENAI]: defaultOpenaiApi, - [OPT_TRANS_OPENAI_2]: defaultOpenaiApi, - [OPT_TRANS_OPENAI_3]: defaultOpenaiApi, - [OPT_TRANS_GEMINI]: { - url: `https://generativelanguage.googleapis.com/v1/models/${INPUT_PLACE_MODEL}:generateContent?key=${INPUT_PLACE_KEY}`, - key: "", - model: "gemini-2.5-flash", - systemPrompt: `You are a professional, authentic machine translation engine.`, - userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`, - customHeader: "", - customBody: "", - temperature: 0, - maxTokens: 2048, - fetchLimit: 1, - fetchInterval: 500, - apiName: OPT_TRANS_GEMINI, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT * 2, - }, - [OPT_TRANS_GEMINI_2]: { - url: `https://generativelanguage.googleapis.com/v1beta/openai/chat/completions`, - key: "", - model: "gemini-2.0-flash", - systemPrompt: `You are a professional, authentic machine translation engine.`, - userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`, - customHeader: "", - customBody: "", - temperature: 0, - maxTokens: 2048, - fetchLimit: 1, - fetchInterval: 500, - apiName: OPT_TRANS_GEMINI_2, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT * 2, - }, - [OPT_TRANS_CLAUDE]: { - url: "https://api.anthropic.com/v1/messages", - key: "", - model: "claude-3-haiku-20240307", - systemPrompt: `You are a professional, authentic machine translation engine.`, - userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`, - customHeader: "", - customBody: "", - temperature: 0, - maxTokens: 1024, - fetchLimit: 1, - fetchInterval: 500, - apiName: OPT_TRANS_CLAUDE, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT * 2, - }, - [OPT_TRANS_CLOUDFLAREAI]: { - url: "https://api.cloudflare.com/client/v4/accounts/{{ACCOUNT_ID}}/ai/run/@cf/meta/m2m100-1.2b", - key: "", - fetchLimit: 1, - fetchInterval: 500, - apiName: OPT_TRANS_CLOUDFLAREAI, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT * 2, - }, - [OPT_TRANS_OLLAMA]: defaultOllamaApi, - [OPT_TRANS_OLLAMA_2]: defaultOllamaApi, - [OPT_TRANS_OLLAMA_3]: defaultOllamaApi, - [OPT_TRANS_OPENROUTER]: { - url: "https://openrouter.ai/api/v1/chat/completions", - key: "", - model: "openai/gpt-4o", - systemPrompt: `You are a professional, authentic machine translation engine.`, - userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`, - customHeader: "", - customBody: "", - temperature: 0, - maxTokens: 256, - fetchLimit: 1, - fetchInterval: 500, - apiName: OPT_TRANS_OPENROUTER, - isDisabled: false, - httpTimeout: DEFAULT_HTTP_TIMEOUT * 2, - }, - [OPT_TRANS_CUSTOMIZE]: defaultCustomApi, - [OPT_TRANS_CUSTOMIZE_2]: defaultCustomApi, - [OPT_TRANS_CUSTOMIZE_3]: defaultCustomApi, - [OPT_TRANS_CUSTOMIZE_4]: defaultCustomApi, - [OPT_TRANS_CUSTOMIZE_5]: defaultCustomApi, -}; - -// 默认快捷键 -export const OPT_SHORTCUT_TRANSLATE = "toggleTranslate"; -export const OPT_SHORTCUT_STYLE = "toggleStyle"; -export const OPT_SHORTCUT_POPUP = "togglePopup"; -export const OPT_SHORTCUT_SETTING = "openSetting"; -export const DEFAULT_SHORTCUTS = { - [OPT_SHORTCUT_TRANSLATE]: ["AltLeft", "KeyQ"], - [OPT_SHORTCUT_STYLE]: ["AltLeft", "KeyC"], - [OPT_SHORTCUT_POPUP]: ["AltLeft", "KeyK"], - [OPT_SHORTCUT_SETTING]: ["AltLeft", "KeyO"], -}; - -export const TRANS_MIN_LENGTH = 5; // 最短翻译长度 -export const TRANS_MAX_LENGTH = 5000; // 最长翻译长度 -export const TRANS_NEWLINE_LENGTH = 20; // 换行字符数 -export const DEFAULT_BLACKLIST = [ - "https://fishjar.github.io/kiss-translator/options.html", - "https://translate.google.com", - "https://www.deepl.com/translator", - "oapi.dingtalk.com", - "login.dingtalk.com", -]; // 禁用翻译名单 -export const DEFAULT_CSPLIST = ["https://github.com"]; // 禁用CSP名单 - -export const DEFAULT_SETTING = { - darkMode: false, // 深色模式 - uiLang: "en", // 界面语言 - // fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量(移至transApis,作废) - // fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间(移至transApis,作废) - minLength: TRANS_MIN_LENGTH, - maxLength: TRANS_MAX_LENGTH, - newlineLength: TRANS_NEWLINE_LENGTH, - httpTimeout: DEFAULT_HTTP_TIMEOUT, - clearCache: false, // 是否在浏览器下次启动时清除缓存 - injectRules: true, // 是否注入订阅规则 - // injectWebfix: true, // 是否注入修复补丁(作废) - // detectRemote: false, // 是否使用远程语言检测(移至rule,作废) - // contextMenus: true, // 是否添加右键菜单(作废) - contextMenuType: 1, // 右键菜单类型(0不显示,1简单菜单,2多级菜单) - // transTag: DEFAULT_TRANS_TAG, // 译文元素标签(移至rule,作废) - // transOnly: false, // 是否仅显示译文(移至rule,作废) - // transTitle: false, // 是否同时翻译页面标题(移至rule,作废) - subrulesList: DEFAULT_SUBRULES_LIST, // 订阅列表 - owSubrule: DEFAULT_OW_RULE, // 覆写订阅规则 - transApis: DEFAULT_TRANS_APIS, // 翻译接口 - // mouseKey: OPT_TIMING_PAGESCROLL, // 翻译时机/鼠标悬停翻译(移至rule,作废) - shortcuts: DEFAULT_SHORTCUTS, // 快捷键 - inputRule: DEFAULT_INPUT_RULE, // 输入框设置 - tranboxSetting: DEFAULT_TRANBOX_SETTING, // 划词翻译设置 - touchTranslate: 2, // 触屏翻译 - blacklist: DEFAULT_BLACKLIST.join(",\n"), // 禁用翻译名单 - csplist: DEFAULT_CSPLIST.join(",\n"), // 禁用CSP名单 - // disableLangs: [], // 不翻译的语言(移至rule,作废) - transInterval: 500, // 翻译间隔时间 - langDetector: OPT_TRANS_MICROSOFT, // 远程语言识别服务 -}; - -export const DEFAULT_RULES = [GLOBLA_RULE]; - -export const OPT_SYNCTYPE_WORKER = "KISS-Worker"; -export const OPT_SYNCTYPE_WEBDAV = "WebDAV"; -export const OPT_SYNCTYPE_ALL = [OPT_SYNCTYPE_WORKER, OPT_SYNCTYPE_WEBDAV]; - -export const DEFAULT_SYNC = { - syncType: OPT_SYNCTYPE_WORKER, // 同步方式 - syncUrl: "", // 数据同步接口 - syncUser: "", // 数据同步用户名 - syncKey: "", // 数据同步密钥 - syncMeta: {}, // 数据更新及同步信息 - subRulesSyncAt: 0, // 订阅规则同步时间 - dataCaches: {}, // 缓存同步时间 -}; +export * from "./app"; +export * from "./rules"; +export * from "./api"; +export * from "./setting"; +export * from "./i18n"; +export * from "./storage"; +export * from "./url"; +export * from "./msg"; +export * from "./client"; diff --git a/src/config/msg.js b/src/config/msg.js new file mode 100644 index 0000000..6903924 --- /dev/null +++ b/src/config/msg.js @@ -0,0 +1,21 @@ +export const CMD_TOGGLE_TRANSLATE = "toggleTranslate"; +export const CMD_TOGGLE_STYLE = "toggleStyle"; +export const CMD_OPEN_OPTIONS = "openOptions"; +export const CMD_OPEN_TRANBOX = "openTranbox"; + +export const MSG_FETCH = "fetch"; +export const MSG_GET_HTTPCACHE = "get_httpcache"; +export const MSG_PUT_HTTPCACHE = "put_httpcache"; +export const MSG_OPEN_OPTIONS = "open_options"; +export const MSG_SAVE_RULE = "save_rule"; +export const MSG_TRANS_TOGGLE = "trans_toggle"; +export const MSG_TRANS_TOGGLE_STYLE = "trans_toggle_style"; +export const MSG_OPEN_TRANBOX = "open_tranbox"; +export const MSG_TRANS_GETRULE = "trans_getrule"; +export const MSG_TRANS_PUTRULE = "trans_putrule"; +export const MSG_TRANS_CURRULE = "trans_currule"; +export const MSG_CONTEXT_MENUS = "context_menus"; +export const MSG_COMMAND_SHORTCUTS = "command_shortcuts"; +export const MSG_INJECT_JS = "inject_js"; +export const MSG_INJECT_CSS = "inject_css"; +export const MSG_UPDATE_CSP = "update_csp"; diff --git a/src/config/rules.js b/src/config/rules.js index a7bd131..a34bd28 100644 --- a/src/config/rules.js +++ b/src/config/rules.js @@ -1,9 +1,63 @@ import { FIXER_BR, FIXER_BN, FIXER_BR_DIV, FIXER_BN_DIV } from "../libs/webfix"; +import { OPT_TRANS_MICROSOFT } from "./api"; export const GLOBAL_KEY = "*"; export const REMAIN_KEY = "-"; export const SHADOW_KEY = ">>>"; +export const DEFAULT_COLOR = "#209CEE"; // 默认高亮背景色/线条颜色 + +export const DEFAULT_TRANS_TAG = "font"; +export const DEFAULT_SELECT_STYLE = + "-webkit-line-clamp: unset; max-height: none; height: auto;"; + +export const OPT_STYLE_NONE = "style_none"; // 无 +export const OPT_STYLE_LINE = "under_line"; // 下划线 +export const OPT_STYLE_DOTLINE = "dot_line"; // 点状线 +export const OPT_STYLE_DASHLINE = "dash_line"; // 虚线 +export const OPT_STYLE_DASHBOX = "dash_box"; // 虚线框 +export const OPT_STYLE_WAVYLINE = "wavy_line"; // 波浪线 +export const OPT_STYLE_FUZZY = "fuzzy"; // 模糊 +export const OPT_STYLE_HIGHLIGHT = "highlight"; // 高亮 +export const OPT_STYLE_BLOCKQUOTE = "blockquote"; // 引用 +export const OPT_STYLE_DIY = "diy_style"; // 自定义样式 +export const OPT_STYLE_ALL = [ + OPT_STYLE_NONE, + OPT_STYLE_LINE, + OPT_STYLE_DOTLINE, + OPT_STYLE_DASHLINE, + OPT_STYLE_DASHBOX, + OPT_STYLE_WAVYLINE, + OPT_STYLE_FUZZY, + OPT_STYLE_HIGHLIGHT, + OPT_STYLE_BLOCKQUOTE, + OPT_STYLE_DIY, +]; +export const OPT_STYLE_USE_COLOR = [ + OPT_STYLE_LINE, + OPT_STYLE_DOTLINE, + OPT_STYLE_DASHLINE, + OPT_STYLE_DASHBOX, + OPT_STYLE_WAVYLINE, + OPT_STYLE_HIGHLIGHT, + OPT_STYLE_BLOCKQUOTE, +]; + +export const OPT_TIMING_PAGESCROLL = "mk_pagescroll"; // 滚动加载翻译 +export const OPT_TIMING_PAGEOPEN = "mk_pageopen"; // 直接翻译到底 +export const OPT_TIMING_MOUSEOVER = "mk_mouseover"; +export const OPT_TIMING_CONTROL = "mk_ctrlKey"; +export const OPT_TIMING_SHIFT = "mk_shiftKey"; +export const OPT_TIMING_ALT = "mk_altKey"; +export const OPT_TIMING_ALL = [ + OPT_TIMING_PAGESCROLL, + OPT_TIMING_PAGEOPEN, + OPT_TIMING_MOUSEOVER, + OPT_TIMING_CONTROL, + OPT_TIMING_SHIFT, + OPT_TIMING_ALT, +]; + export const DEFAULT_SELECTOR = `:is(li, p, h1, h2, h3, h4, h5, h6, dd, blockquote, .kiss-p)`; export const DEFAULT_KEEP_SELECTOR = `code, img, svg, pre`; export const DEFAULT_RULE = { @@ -36,6 +90,39 @@ export const DEFAULT_RULE = { transRemoveHook: "", // 钩子函数 }; +// 全局规则 +export const GLOBLA_RULE = { + pattern: "*", // 匹配网址 + selector: DEFAULT_SELECTOR, // 选择器 + keepSelector: DEFAULT_KEEP_SELECTOR, // 保留元素选择器 + terms: "", // 专业术语 + translator: OPT_TRANS_MICROSOFT, // 翻译服务 + fromLang: "auto", // 源语言 + toLang: "zh-CN", // 目标语言 + textStyle: OPT_STYLE_DASHLINE, // 译文样式 + transOpen: "false", // 开启翻译 + bgColor: "", // 译文颜色 + textDiyStyle: "", // 自定义译文样式 + selectStyle: DEFAULT_SELECT_STYLE, // 选择器节点样式 + parentStyle: DEFAULT_SELECT_STYLE, // 选择器父节点样式 + injectJs: "", // 注入JS + injectCss: "", // 注入CSS + transOnly: "false", // 是否仅显示译文 + transTiming: OPT_TIMING_PAGESCROLL, // 翻译时机/鼠标悬停翻译 + transTag: DEFAULT_TRANS_TAG, // 译文元素标签 + transTitle: "false", // 是否同时翻译页面标题 + transSelected: "true", // 是否启用划词翻译 + detectRemote: "false", // 是否使用远程语言检测 + skipLangs: [], // 不翻译的语言 + fixerSelector: "", // 修复函数选择器 + fixerFunc: "-", // 修复函数 + transStartHook: "", // 钩子函数 + transEndHook: "", // 钩子函数 + transRemoveHook: "", // 钩子函数 +}; + +export const DEFAULT_RULES = [GLOBLA_RULE]; + const DEFAULT_DIY_STYLE = `color: #666; background: linear-gradient( 45deg, diff --git a/src/config/setting.js b/src/config/setting.js new file mode 100644 index 0000000..b6bc528 --- /dev/null +++ b/src/config/setting.js @@ -0,0 +1,142 @@ +import { + OPT_DICT_BAIDU, + DEFAULT_HTTP_TIMEOUT, + OPT_TRANS_MICROSOFT, + DEFAULT_TRANS_APIS, +} from "./api"; +import { DEFAULT_OW_RULE } from "./rules"; + +// 默认快捷键 +export const OPT_SHORTCUT_TRANSLATE = "toggleTranslate"; +export const OPT_SHORTCUT_STYLE = "toggleStyle"; +export const OPT_SHORTCUT_POPUP = "togglePopup"; +export const OPT_SHORTCUT_SETTING = "openSetting"; +export const DEFAULT_SHORTCUTS = { + [OPT_SHORTCUT_TRANSLATE]: ["AltLeft", "KeyQ"], + [OPT_SHORTCUT_STYLE]: ["AltLeft", "KeyC"], + [OPT_SHORTCUT_POPUP]: ["AltLeft", "KeyK"], + [OPT_SHORTCUT_SETTING]: ["AltLeft", "KeyO"], +}; + +export const TRANS_MIN_LENGTH = 5; // 最短翻译长度 +export const TRANS_MAX_LENGTH = 5000; // 最长翻译长度 +export const TRANS_NEWLINE_LENGTH = 20; // 换行字符数 +export const DEFAULT_BLACKLIST = [ + "https://fishjar.github.io/kiss-translator/options.html", + "https://translate.google.com", + "https://www.deepl.com/translator", + "oapi.dingtalk.com", + "login.dingtalk.com", +]; // 禁用翻译名单 +export const DEFAULT_CSPLIST = ["https://github.com"]; // 禁用CSP名单 + +// 同步设置 +export const OPT_SYNCTYPE_WORKER = "KISS-Worker"; +export const OPT_SYNCTYPE_WEBDAV = "WebDAV"; +export const OPT_SYNCTYPE_ALL = [OPT_SYNCTYPE_WORKER, OPT_SYNCTYPE_WEBDAV]; +export const DEFAULT_SYNC = { + syncType: OPT_SYNCTYPE_WORKER, // 同步方式 + syncUrl: "", // 数据同步接口 + syncUser: "", // 数据同步用户名 + syncKey: "", // 数据同步密钥 + syncMeta: {}, // 数据更新及同步信息 + subRulesSyncAt: 0, // 订阅规则同步时间 + dataCaches: {}, // 缓存同步时间 +}; + +// 输入框翻译 +export const OPT_INPUT_TRANS_SIGNS = ["/", "//", "\\", "\\\\", ">", ">>"]; +export const DEFAULT_INPUT_SHORTCUT = ["AltLeft", "KeyI"]; +export const DEFAULT_INPUT_RULE = { + transOpen: true, + translator: OPT_TRANS_MICROSOFT, + fromLang: "auto", + toLang: "en", + triggerShortcut: DEFAULT_INPUT_SHORTCUT, + triggerCount: 1, + triggerTime: 200, + transSign: OPT_INPUT_TRANS_SIGNS[0], +}; + +// 划词翻译 +export const PHONIC_MAP = { + en_phonic: ["英", "uk"], + us_phonic: ["美", "en"], +}; +export const OPT_TRANBOX_TRIGGER_CLICK = "click"; +export const OPT_TRANBOX_TRIGGER_HOVER = "hover"; +export const OPT_TRANBOX_TRIGGER_SELECT = "select"; +export const OPT_TRANBOX_TRIGGER_ALL = [ + OPT_TRANBOX_TRIGGER_CLICK, + OPT_TRANBOX_TRIGGER_HOVER, + OPT_TRANBOX_TRIGGER_SELECT, +]; +export const DEFAULT_TRANBOX_SHORTCUT = ["AltLeft", "KeyS"]; +export const DEFAULT_TRANBOX_SETTING = { + // transOpen: true, // 是否启用划词翻译(作废,移至rule) + translator: OPT_TRANS_MICROSOFT, + fromLang: "auto", + toLang: "zh-CN", + toLang2: "en", + tranboxShortcut: DEFAULT_TRANBOX_SHORTCUT, + btnOffsetX: 10, + btnOffsetY: 10, + boxOffsetX: 0, + boxOffsetY: 10, + hideTranBtn: false, // 是否隐藏翻译按钮 + hideClickAway: false, // 是否点击外部关闭弹窗 + simpleStyle: false, // 是否简洁界面 + followSelection: false, // 翻译框是否跟随选中文本 + triggerMode: OPT_TRANBOX_TRIGGER_CLICK, // 触发翻译方式 + extStyles: "", // 附加样式 + enDict: OPT_DICT_BAIDU, // 英文词典 +}; + +// 订阅列表 +export const DEFAULT_SUBRULES_LIST = [ + { + url: process.env.REACT_APP_RULESURL, + selected: true, + }, + { + url: process.env.REACT_APP_RULESURL_ON, + selected: false, + }, + { + url: process.env.REACT_APP_RULESURL_OFF, + selected: false, + }, +]; + +export const DEFAULT_SETTING = { + darkMode: false, // 深色模式 + uiLang: "en", // 界面语言 + // fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量(移至transApis,作废) + // fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间(移至transApis,作废) + minLength: TRANS_MIN_LENGTH, + maxLength: TRANS_MAX_LENGTH, + newlineLength: TRANS_NEWLINE_LENGTH, + httpTimeout: DEFAULT_HTTP_TIMEOUT, + clearCache: false, // 是否在浏览器下次启动时清除缓存 + injectRules: true, // 是否注入订阅规则 + // injectWebfix: true, // 是否注入修复补丁(作废) + // detectRemote: false, // 是否使用远程语言检测(移至rule,作废) + // contextMenus: true, // 是否添加右键菜单(作废) + contextMenuType: 1, // 右键菜单类型(0不显示,1简单菜单,2多级菜单) + // transTag: DEFAULT_TRANS_TAG, // 译文元素标签(移至rule,作废) + // transOnly: false, // 是否仅显示译文(移至rule,作废) + // transTitle: false, // 是否同时翻译页面标题(移至rule,作废) + subrulesList: DEFAULT_SUBRULES_LIST, // 订阅列表 + owSubrule: DEFAULT_OW_RULE, // 覆写订阅规则 + transApis: DEFAULT_TRANS_APIS, // 翻译接口 + // mouseKey: OPT_TIMING_PAGESCROLL, // 翻译时机/鼠标悬停翻译(移至rule,作废) + shortcuts: DEFAULT_SHORTCUTS, // 快捷键 + inputRule: DEFAULT_INPUT_RULE, // 输入框设置 + tranboxSetting: DEFAULT_TRANBOX_SETTING, // 划词翻译设置 + touchTranslate: 2, // 触屏翻译 + blacklist: DEFAULT_BLACKLIST.join(",\n"), // 禁用翻译名单 + csplist: DEFAULT_CSPLIST.join(",\n"), // 禁用CSP名单 + // disableLangs: [], // 不翻译的语言(移至rule,作废) + transInterval: 500, // 翻译间隔时间 + langDetector: OPT_TRANS_MICROSOFT, // 远程语言识别服务 +}; diff --git a/src/config/storage.js b/src/config/storage.js new file mode 100644 index 0000000..59423d1 --- /dev/null +++ b/src/config/storage.js @@ -0,0 +1,20 @@ +import { APP_NAME } from "./app"; + +export const KV_RULES_KEY = "kiss-rules.json"; +export const KV_WORDS_KEY = "kiss-words.json"; +export const KV_RULES_SHARE_KEY = "kiss-rules-share.json"; +export const KV_SETTING_KEY = "kiss-setting.json"; +export const KV_SALT_SYNC = "KISS-Translator-SYNC"; +export const KV_SALT_SHARE = "KISS-Translator-SHARE"; + +export const STOKEY_MSAUTH = `${APP_NAME}_msauth`; +export const STOKEY_BDAUTH = `${APP_NAME}_bdauth`; +export const STOKEY_SETTING = `${APP_NAME}_setting`; +export const STOKEY_RULES = `${APP_NAME}_rules`; +export const STOKEY_WORDS = `${APP_NAME}_words`; +export const STOKEY_SYNC = `${APP_NAME}_sync`; +export const STOKEY_FAB = `${APP_NAME}_fab`; +export const STOKEY_RULESCACHE_PREFIX = `${APP_NAME}_rulescache_`; + +export const CACHE_NAME = `${APP_NAME}_cache`; +export const DEFAULT_CACHE_TIMEOUT = 3600 * 24 * 7; // 缓存超时时间(7天) diff --git a/src/config/url.js b/src/config/url.js new file mode 100644 index 0000000..03b646a --- /dev/null +++ b/src/config/url.js @@ -0,0 +1,11 @@ +import { APP_LCNAME } from "./app"; + +export const URL_CACHE_TRAN = `https://${APP_LCNAME}/translate`; + +export const URL_KISS_WORKER = "https://github.com/fishjar/kiss-worker"; +export const URL_KISS_PROXY = "https://github.com/fishjar/kiss-proxy"; +export const URL_KISS_RULES = "https://github.com/fishjar/kiss-rules"; +export const URL_KISS_RULES_NEW_ISSUE = + "https://github.com/fishjar/kiss-rules/issues/new"; +export const URL_RAW_PREFIX = + "https://raw.githubusercontent.com/fishjar/kiss-translator/master"; diff --git a/src/libs/auth.js b/src/libs/auth.js index 51cfc23..ca2301c 100644 --- a/src/libs/auth.js +++ b/src/libs/auth.js @@ -1,5 +1,4 @@ import { getMsauth, setMsauth } from "./storage"; -import { URL_MICROSOFT_AUTH } from "../config"; import { fetchData } from "./fetch"; import { kissLog } from "./log"; @@ -35,7 +34,7 @@ const _msAuth = () => { } // 缓存没有或失效,查询接口 - token = await fetchData(URL_MICROSOFT_AUTH); + token = await fetchData("https://edge.microsoft.com/translate/auth"); exp = parseMSToken(token); await setMsauth({ token, exp }); return [token, exp]; diff --git a/src/libs/pool.js b/src/libs/pool.js index 845c055..1c64972 100644 --- a/src/libs/pool.js +++ b/src/libs/pool.js @@ -3,10 +3,9 @@ import { kissLog } from "./log"; /** * 任务池 - * @param {*} fn - * @param {*} preFn * @param {*} _interval * @param {*} _limit + * @param {*} _retryInteral * @returns */ const taskPool = (_interval = 100, _limit = 100, _retryInteral = 1000) => { @@ -80,6 +79,9 @@ let fetchPool; /** * 获取请求池实例 + * @param {*} interval + * @param {*} limit + * @returns */ export const getFetchPool = (interval, limit) => { if (!fetchPool) { diff --git a/src/views/Options/Apis.js b/src/views/Options/Apis.js index 4832153..be17fc6 100644 --- a/src/views/Options/Apis.js +++ b/src/views/Options/Apis.js @@ -31,7 +31,6 @@ import { OPT_TRANS_CUSTOMIZE_4, OPT_TRANS_CUSTOMIZE_5, OPT_TRANS_NIUTRANS, - URL_NIUTRANS_REG, DEFAULT_FETCH_LIMIT, DEFAULT_FETCH_INTERVAL, DEFAULT_HTTP_TIMEOUT, @@ -201,7 +200,10 @@ function ApiFields({ translator, api, updateApi, resetApi }) { translator === OPT_TRANS_NIUTRANS ? ( <> {i18n("mulkeys_help")} - + {i18n("reg_niutrans")} diff --git a/src/views/Selection/TranCont.js b/src/views/Selection/TranCont.js index d867406..8175a89 100644 --- a/src/views/Selection/TranCont.js +++ b/src/views/Selection/TranCont.js @@ -43,14 +43,14 @@ export default function TranCont({ const apiSetting = transApis[translator] || DEFAULT_TRANS_APIS[translator]; - const tranRes = await apiTranslate({ + const [trText] = await apiTranslate({ text, translator, fromLang, toLang: to, apiSetting, }); - setTrText(tranRes[0]); + setTrText(trText); } catch (err) { setError(err.message); } finally {