Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Gabe
2025-05-17 23:22:09 +08:00
11 changed files with 206 additions and 52 deletions

View File

@@ -7,28 +7,28 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
with: with:
version: 8.7.6 version: latest
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: "18.17.0" node-version: latest
cache: "pnpm" cache: "pnpm"
- run: pnpm install - run: pnpm install
- run: pnpm build - run: pnpm build
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
with: with:
name: build-artifacts name: build-artifacts
path: build path: build
deploy-web: deploy-web:
needs: build needs: build
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: build-artifacts name: build-artifacts
path: build path: build
@@ -37,7 +37,8 @@ jobs:
with: with:
folder: build/web folder: build/web
create-release: create-release:
runs-on: ubuntu-22.04 needs: build
runs-on: ubuntu-latest
outputs: outputs:
upload_url: ${{ steps.create-release.outputs.upload_url }} upload_url: ${{ steps.create-release.outputs.upload_url }}
steps: steps:
@@ -55,10 +56,10 @@ jobs:
strategy: strategy:
matrix: matrix:
client: ["chrome", "edge", "firefox", "userscript"] client: ["chrome", "edge", "firefox", "userscript"]
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: build-artifacts name: build-artifacts
path: build path: build

View File

@@ -26,13 +26,14 @@
"start:userscript": "REACT_APP_CLIENT=userscript react-app-rewired start", "start:userscript": "REACT_APP_CLIENT=userscript react-app-rewired start",
"build:chrome": "rm -rf build/chrome && BUILD_PATH=./build/chrome REACT_APP_CLIENT=chrome react-app-rewired build && rm build/chrome/content.html", "build:chrome": "rm -rf build/chrome && BUILD_PATH=./build/chrome REACT_APP_CLIENT=chrome react-app-rewired build && rm build/chrome/content.html",
"build:edge": "rm -rf build/edge && cp -r build/chrome build/edge", "build:edge": "rm -rf build/edge && cp -r build/chrome build/edge",
"build:thunderbird": "rm -rf build/thunderbird && BUILD_PATH=./build/thunderbird REACT_APP_CLIENT=thunderbird react-app-rewired build && rm build/thunderbird/content.html && cp ./build/thunderbird/manifest.thunderbird.json ./build/thunderbird/manifest.json && rm build/*/manifest.thunderbird.json",
"build:firefox": "rm -rf build/firefox && cp -r build/chrome build/firefox && cat ./build/firefox/manifest.firefox.json > ./build/firefox/manifest.json && rm build/*/manifest.firefox.json", "build:firefox": "rm -rf build/firefox && cp -r build/chrome build/firefox && cat ./build/firefox/manifest.firefox.json > ./build/firefox/manifest.json && rm build/*/manifest.firefox.json",
"build:web": "rm -rf build/web && BUILD_PATH=./build/web REACT_APP_CLIENT=userscript react-app-rewired build", "build:web": "rm -rf build/web && BUILD_PATH=./build/web REACT_APP_CLIENT=userscript react-app-rewired build",
"build:userscript-ios": "file1=build/web/kiss-translator.user.js file2=build/web/kiss-translator-ios-safari.user.js && cp $file1 $file2 && sed -i 's|// @grant unsafeWindow|// @inject-into content|g' $file2", "build:userscript-ios": "file1=build/web/kiss-translator.user.js file2=build/web/kiss-translator-ios-safari.user.js && cp $file1 $file2 && sed -i 's|// @grant unsafeWindow|// @inject-into content|g' $file2",
"build:userscript": "rm -rf build/userscript && mkdir build/userscript && cp build/web/*.user.js build/userscript/", "build:userscript": "rm -rf build/userscript && mkdir build/userscript && cp build/web/*.user.js build/userscript/",
"build:rules": "babel-node src/rules.js", "build:rules": "babel-node src/rules.js",
"build": "pnpm build:chrome && pnpm build:edge && pnpm build:firefox && pnpm build:web && pnpm build:userscript-ios && pnpm build:userscript && pnpm build:rules", "build": "pnpm build:chrome && pnpm build:edge && pnpm build:thunderbird && pnpm build:firefox && pnpm build:web && pnpm build:userscript-ios && pnpm build:userscript && pnpm build:rules",
"zip": "cd build && zip -r chrome.zip chrome && zip -r edge.zip edge && cd firefox && zip -r ../firefox.zip .", "zip": "cd build && zip -r chrome.zip chrome && zip -r edge.zip edge && (cd firefox && zip -r ../firefox.zip .) && (cd thunderbird && zip -r ../thunderbird.zip .)",
"test": "react-app-rewired test", "test": "react-app-rewired test",
"eject": "react-scripts eject" "eject": "react-scripts eject"
}, },

View File

@@ -0,0 +1,78 @@
{
"manifest_version": 2,
"name": "__MSG_app_name__",
"description": "__MSG_app_description__",
"version": "1.8.11",
"default_locale": "en",
"author": "Gabe<yugang2002@gmail.com>",
"homepage_url": "https://github.com/fishjar/kiss-translator",
"browser_specific_settings": {
"gecko": {
"id": "yugang2002@gmail.com",
"strict_min_version": "78.0"
}
},
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"js": ["content.js"],
"matches": ["<all_urls>"],
"all_frames": true
}
],
"commands": {
"_execute_browser_action": {
"suggested_key": {
"default": "Alt+K"
}
},
"toggleTranslate": {
"suggested_key": {
"default": "Alt+Q"
},
"description": "__MSG_toggle_translate__"
},
"openTranbox": {
"suggested_key": {
"default": "Alt+S"
},
"description": "__MSG_open_tranbox__"
},
"toggleStyle": {
"suggested_key": {
"default": "Alt+C"
},
"description": "__MSG_toggle_style__"
},
"openOptions": {
"description": "__MSG_open_options__"
}
},
"permissions": [
"<all_urls>",
"storage",
"menus",
"messagesModify",
"scripting",
"declarativeNetRequest"
],
"icons": {
"16": "images/logo16.png",
"32": "images/logo32.png",
"48": "images/logo48.png",
"128": "images/logo128.png"
},
"browser_action": {
"default_icon": {
"128": "images/logo128.png"
},
"default_title": "__MSG_app_name__",
"default_popup": "popup.html"
},
"options_ui": {
"page": "options.html",
"open_in_tab": true
}
}

View File

@@ -39,6 +39,7 @@ import {
import { sha256 } from "../libs/utils"; import { sha256 } from "../libs/utils";
import interpreter from "../libs/interpreter"; import interpreter from "../libs/interpreter";
import { msAuth } from "../libs/auth"; import { msAuth } from "../libs/auth";
import {getSettingWithDefault } from "../libs/storage";
/** /**
* 同步数据 * 同步数据
@@ -255,10 +256,19 @@ export const apiTranslate = async ({
); );
switch (translator) { switch (translator) {
case OPT_TRANS_GOOGLE: case OPT_TRANS_GOOGLE: {
trText = res.sentences.map((item) => item.trans).join(" "); if (!res || !Array.isArray(res) || res.length < 2) {
isSame = to === res.src; console.error("Unexpected response structure:", res);
trText = "Error: Invalid response structure";
isSame = false;
} else {
const translatedText = Array.isArray(res[0]) ? res[0].join(" ") : "Translation unavailable";
const isTranslationComplete = to === (Array.isArray(res[1]) ? res[1][0] : undefined);
trText = translatedText;
isSame = isTranslationComplete;
}
break; break;
}
case OPT_TRANS_MICROSOFT: case OPT_TRANS_MICROSOFT:
trText = res trText = res
.map((item) => item.translations.map((item) => item.text).join(" ")) .map((item) => item.translations.map((item) => item.text).join(" "))
@@ -323,7 +333,13 @@ export const apiTranslate = async ({
case OPT_TRANS_OLLAMA: case OPT_TRANS_OLLAMA:
case OPT_TRANS_OLLAMA_2: case OPT_TRANS_OLLAMA_2:
case OPT_TRANS_OLLAMA_3: case OPT_TRANS_OLLAMA_3:
trText = res?.response; let deepModels = (await getSettingWithDefault()).transApis[translator]?.thinkIgnore || '';
deepModels = deepModels.split(',').filter(model => model.trim() !== '');
if (deepModels.some(model => res?.model?.startsWith(model))) {
trText = res?.response.replace(/<think>[\s\S]*<\/think>/i, '');
}else{
trText = res?.response;
}
isSame = text === trText; isSame = text === trText;
break; break;
case OPT_TRANS_CUSTOMIZE: case OPT_TRANS_CUSTOMIZE:

View File

@@ -58,26 +58,16 @@ const keyPick = (translator, key = "", cacheMap) => {
}; };
const genGoogle = ({ text, from, to, url, key }) => { const genGoogle = ({ text, from, to, url, key }) => {
const params = { const body = JSON.stringify([[ [text], from, to ], "wt_lib"]);
client: "gtx",
dt: "t",
dj: 1,
ie: "UTF-8",
sl: from,
tl: to,
q: text,
};
const input = `${url}?${queryString.stringify(params)}`;
const init = { const init = {
method: "POST",
headers: { headers: {
"Content-type": "application/json", "Content-Type": "application/json+protobuf",
"X-Goog-API-Key": key,
}, },
body,
}; };
if (key) { return [url, init];
init.headers.Authorization = `Bearer ${key}`;
}
return [input, init];
}; };
const genMicrosoft = async ({ text, from, to }) => { const genMicrosoft = async ({ text, from, to }) => {

View File

@@ -1,3 +1,4 @@
/* global messenger */
import browser from "webextension-polyfill"; import browser from "webextension-polyfill";
import { import {
MSG_FETCH, MSG_FETCH,
@@ -44,41 +45,41 @@ const REMOVE_HEADERS = [
async function addContextMenus(contextMenuType = 1) { async function addContextMenus(contextMenuType = 1) {
// 添加前先删除,避免重复ID的错误 // 添加前先删除,避免重复ID的错误
try { try {
await browser.contextMenus.removeAll(); await browser.menus.removeAll();
} catch (err) { } catch (err) {
// //
} }
switch (contextMenuType) { switch (contextMenuType) {
case 1: case 1:
browser.contextMenus.create({ browser.menus.create({
id: CMD_TOGGLE_TRANSLATE, id: CMD_TOGGLE_TRANSLATE,
title: browser.i18n.getMessage("app_name"), title: browser.i18n.getMessage("app_name"),
contexts: ["page", "selection"], contexts: ["page", "selection"],
}); });
break; break;
case 2: case 2:
browser.contextMenus.create({ browser.menus.create({
id: CMD_TOGGLE_TRANSLATE, id: CMD_TOGGLE_TRANSLATE,
title: browser.i18n.getMessage("toggle_translate"), title: browser.i18n.getMessage("toggle_translate"),
contexts: ["page", "selection"], contexts: ["page", "selection"],
}); });
browser.contextMenus.create({ browser.menus.create({
id: CMD_TOGGLE_STYLE, id: CMD_TOGGLE_STYLE,
title: browser.i18n.getMessage("toggle_style"), title: browser.i18n.getMessage("toggle_style"),
contexts: ["page", "selection"], contexts: ["page", "selection"],
}); });
browser.contextMenus.create({ browser.menus.create({
id: CMD_OPEN_TRANBOX, id: CMD_OPEN_TRANBOX,
title: browser.i18n.getMessage("open_tranbox"), title: browser.i18n.getMessage("open_tranbox"),
contexts: ["page", "selection"], contexts: ["page", "selection"],
}); });
browser.contextMenus.create({ browser.menus.create({
id: "options_separator", id: "options_separator",
type: "separator", type: "separator",
contexts: ["page", "selection"], contexts: ["page", "selection"],
}); });
browser.contextMenus.create({ browser.menus.create({
id: CMD_OPEN_OPTIONS, id: CMD_OPEN_OPTIONS,
title: browser.i18n.getMessage("open_options"), title: browser.i18n.getMessage("open_options"),
contexts: ["page", "selection"], contexts: ["page", "selection"],
@@ -123,12 +124,26 @@ async function updateCspRules(csplist = DEFAULT_CSPLIST.join(",\n")) {
} }
} }
/**
* 注册邮件显示脚本
*/
async function registerMsgDisplayScript() {
await messenger.messageDisplayScripts.register({
js: [{file: "/content.js"}]
});
}
/** /**
* 插件安装 * 插件安装
*/ */
browser.runtime.onInstalled.addListener(() => { browser.runtime.onInstalled.addListener(() => {
tryInitDefaultData(); tryInitDefaultData();
//在thunderbird中注册脚本
if (process.env.REACT_APP_CLIENT === "thunderbird") {
registerMsgDisplayScript();
}
// 右键菜单 // 右键菜单
addContextMenus(); addContextMenus();
@@ -151,6 +166,11 @@ browser.runtime.onStartup.addListener(async () => {
tryClearCaches(); tryClearCaches();
} }
//在thunderbird中注册脚本
if (process.env.REACT_APP_CLIENT === "thunderbird") {
registerMsgDisplayScript();
}
// 右键菜单 // 右键菜单
// firefox重启后菜单会消失,故重复添加 // firefox重启后菜单会消失,故重复添加
addContextMenus(contextMenuType); addContextMenus(contextMenuType);

View File

@@ -186,6 +186,10 @@ export const I18N = {
zh: `最大并发请求数量 (1-100)`, zh: `最大并发请求数量 (1-100)`,
en: `Maximum Number Of Concurrent Requests (1-100)`, en: `Maximum Number Of Concurrent Requests (1-100)`,
}, },
think_ignore: {
zh: `忽略以下模型的<think>输出,逗号(,)分割`,
en: `Ignore the <think> block for the following models, comma (,) separated`,
},
fetch_interval: { fetch_interval: {
zh: `每次请求间隔时间 (0-5000ms)`, zh: `每次请求间隔时间 (0-5000ms)`,
en: `Time Between Requests (0-5000ms)`, en: `Time Between Requests (0-5000ms)`,
@@ -194,6 +198,10 @@ export const I18N = {
zh: `重新翻译间隔时间 (100-5000ms)`, zh: `重新翻译间隔时间 (100-5000ms)`,
en: `Retranslation Interval (100-5000ms)`, en: `Retranslation Interval (100-5000ms)`,
}, },
http_timeout: {
zh: `请求超时时间 (5000-30000ms)`,
en: `Request Timeout Time (5000-30000ms)`,
},
min_translate_length: { min_translate_length: {
zh: `最小翻译字符数 (1-100)`, zh: `最小翻译字符数 (1-100)`,
en: `Minimum number Of Translated Characters (1-100)`, en: `Minimum number Of Translated Characters (1-100)`,

View File

@@ -39,7 +39,8 @@ export const CLIENT_CHROME = "chrome";
export const CLIENT_EDGE = "edge"; export const CLIENT_EDGE = "edge";
export const CLIENT_FIREFOX = "firefox"; export const CLIENT_FIREFOX = "firefox";
export const CLIENT_USERSCRIPT = "userscript"; export const CLIENT_USERSCRIPT = "userscript";
export const CLIENT_EXTS = [CLIENT_CHROME, CLIENT_EDGE, CLIENT_FIREFOX]; 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_RULES_KEY = "kiss-rules.json";
export const KV_WORDS_KEY = "kiss-words.json"; export const KV_WORDS_KEY = "kiss-words.json";
@@ -86,8 +87,10 @@ export const URL_MICROSOFT_AUTH = "https://edge.microsoft.com/translate/auth";
export const URL_MICROSOFT_LANGDETECT = export const URL_MICROSOFT_LANGDETECT =
"https://api-edge.cognitive.microsofttranslator.com/detect?api-version=3.0"; "https://api-edge.cognitive.microsofttranslator.com/detect?api-version=3.0";
export const URL_GOOGLE_TRAN = export const URL_GOOGLE_TRAN = "https://translate-pa.googleapis.com/v1/translateHtml";
"https://translate.googleapis.com/translate_a/single";
export const DEFAULT_GOOGLE_API_KEY = "AIzaSyATBXajvzQLTDHEQbcpq0Ihe0vWDHmO520";
export const URL_BAIDU_LANGDETECT = "https://fanyi.baidu.com/langdetect"; export const URL_BAIDU_LANGDETECT = "https://fanyi.baidu.com/langdetect";
export const URL_BAIDU_SUGGEST = "https://fanyi.baidu.com/sug"; export const URL_BAIDU_SUGGEST = "https://fanyi.baidu.com/sug";
export const URL_BAIDU_TTS = "https://fanyi.baidu.com/gettts"; export const URL_BAIDU_TTS = "https://fanyi.baidu.com/gettts";
@@ -540,13 +543,14 @@ const defaultOllamaApi = {
model: "llama3.1", model: "llama3.1",
systemPrompt: `You are a professional, authentic machine translation engine.`, 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:`, 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:`,
thinkIgnore:`qwen3,deepseek-r1`,
fetchLimit: 1, fetchLimit: 1,
fetchInterval: 500, fetchInterval: 500,
}; };
export const DEFAULT_TRANS_APIS = { export const DEFAULT_TRANS_APIS = {
[OPT_TRANS_GOOGLE]: { [OPT_TRANS_GOOGLE]: {
url: URL_GOOGLE_TRAN, url: URL_GOOGLE_TRAN,
key: "", key: DEFAULT_GOOGLE_API_KEY,
fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量 fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量
fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间 fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间
}, },
@@ -640,6 +644,7 @@ export const DEFAULT_SHORTCUTS = {
export const TRANS_MIN_LENGTH = 5; // 最短翻译长度 export const TRANS_MIN_LENGTH = 5; // 最短翻译长度
export const TRANS_MAX_LENGTH = 5000; // 最长翻译长度 export const TRANS_MAX_LENGTH = 5000; // 最长翻译长度
export const TRANS_NEWLINE_LENGTH = 20; // 换行字符数 export const TRANS_NEWLINE_LENGTH = 20; // 换行字符数
export const HTTP_TIMEOUT = 5000; // 调用超时时间
export const DEFAULT_BLACKLIST = [ export const DEFAULT_BLACKLIST = [
"https://fishjar.github.io/kiss-translator/options.html", "https://fishjar.github.io/kiss-translator/options.html",
"https://translate.google.com", "https://translate.google.com",
@@ -657,6 +662,7 @@ export const DEFAULT_SETTING = {
minLength: TRANS_MIN_LENGTH, minLength: TRANS_MIN_LENGTH,
maxLength: TRANS_MAX_LENGTH, maxLength: TRANS_MAX_LENGTH,
newlineLength: TRANS_NEWLINE_LENGTH, newlineLength: TRANS_NEWLINE_LENGTH,
httpTimeout: HTTP_TIMEOUT,
clearCache: false, // 是否在浏览器下次启动时清除缓存 clearCache: false, // 是否在浏览器下次启动时清除缓存
injectRules: true, // 是否注入订阅规则 injectRules: true, // 是否注入订阅规则
// injectWebfix: true, // 是否注入修复补丁(作废) // injectWebfix: true, // 是否注入修复补丁(作废)

View File

@@ -1,19 +1,23 @@
import { isExt, isGm } from "./client"; import { isExt, isGm } from "./client";
import { sendBgMsg } from "./msg"; import { sendBgMsg } from "./msg";
import { taskPool } from "./pool"; import { taskPool } from "./pool";
import { storage,getSettingWithDefault } from "./storage";
import { import {
MSG_FETCH, MSG_FETCH,
MSG_GET_HTTPCACHE, MSG_GET_HTTPCACHE,
CACHE_NAME, CACHE_NAME,
DEFAULT_FETCH_INTERVAL, DEFAULT_FETCH_INTERVAL,
DEFAULT_FETCH_LIMIT, DEFAULT_FETCH_LIMIT,
HTTP_TIMEOUT,
} from "../config"; } from "../config";
import { isBg } from "./browser"; import { isBg } from "./browser";
import { genTransReq } from "../apis/trans"; import { genTransReq } from "../apis/trans";
import { kissLog } from "./log"; import { kissLog } from "./log";
import { blobToBase64 } from "./utils"; import { blobToBase64 } from "./utils";
const TIMEOUT = 5000; let TIMEOUT = HTTP_TIMEOUT;
/** /**
* 构造缓存 request * 构造缓存 request
@@ -39,7 +43,8 @@ const newCacheReq = async (input, init) => {
* @param {*} init * @param {*} init
* @returns * @returns
*/ */
export const fetchGM = async (input, { method = "GET", headers, body } = {}) => export const fetchGM = async (input, { method = "GET", headers, body } = {}) =>{
TIMEOUT = (await getSettingWithDefault()).httpTimeout;
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
GM.xmlHttpRequest({ GM.xmlHttpRequest({
method, method,
@@ -66,7 +71,7 @@ export const fetchGM = async (input, { method = "GET", headers, body } = {}) =>
onerror: reject, onerror: reject,
}); });
}); });
}
/** /**
* 发起请求 * 发起请求
* @param {*} param0 * @param {*} param0
@@ -108,7 +113,11 @@ export const fetchPatcher = async (input, init, transOpts, apiSetting) => {
} }
} }
if (AbortSignal?.timeout) { //const kiss_setting = await storage.get("KISS-Translator_setting");
//TIMEOUT = JSON.parse(kiss_setting)?.httpTimeout || TIMEOUT;
TIMEOUT = (await getSettingWithDefault()).httpTimeout;
console.log("TIMEOUT", TIMEOUT);
if (AbortSignal?.timeout && !init.signal) {
Object.assign(init, { signal: AbortSignal.timeout(TIMEOUT) }); Object.assign(init, { signal: AbortSignal.timeout(TIMEOUT) });
} }

View File

@@ -117,6 +117,7 @@ function ApiFields({ translator }) {
model = "", model = "",
systemPrompt = "", systemPrompt = "",
userPrompt = "", userPrompt = "",
thinkIgnore = "",
fetchLimit = DEFAULT_FETCH_LIMIT, fetchLimit = DEFAULT_FETCH_LIMIT,
fetchInterval = DEFAULT_FETCH_INTERVAL, fetchInterval = DEFAULT_FETCH_INTERVAL,
dictNo = "", dictNo = "",
@@ -246,6 +247,18 @@ function ApiFields({ translator }) {
</> </>
)} )}
{(translator.startsWith(OPT_TRANS_OLLAMA)) && (
<>
<TextField
size="small"
label={i18n("think_ignore")}
name="thinkIgnore"
value={thinkIgnore}
onChange={handleChange}
/>
</>
)}
{(translator.startsWith(OPT_TRANS_OPENAI) || {(translator.startsWith(OPT_TRANS_OPENAI) ||
translator === OPT_TRANS_CLAUDE) && ( translator === OPT_TRANS_CLAUDE) && (
<> <>

View File

@@ -27,6 +27,7 @@ import {
DEFAULT_CSPLIST, DEFAULT_CSPLIST,
MSG_CONTEXT_MENUS, MSG_CONTEXT_MENUS,
MSG_UPDATE_CSP, MSG_UPDATE_CSP,
HTTP_TIMEOUT,
} from "../../config"; } from "../../config";
import { useShortcut } from "../../hooks/Shortcut"; import { useShortcut } from "../../hooks/Shortcut";
import ShortcutInput from "./ShortcutInput"; import ShortcutInput from "./ShortcutInput";
@@ -71,6 +72,9 @@ export default function Settings() {
case "newlineLength": case "newlineLength":
value = limitNumber(value, 1, 1000); value = limitNumber(value, 1, 1000);
break; break;
case "httpTimeout":
value = limitNumber(value, 5000, 30000);
break;
case "touchTranslate": case "touchTranslate":
value = limitNumber(value, 0, 4); value = limitNumber(value, 0, 4);
break; break;
@@ -110,6 +114,7 @@ export default function Settings() {
maxLength, maxLength,
clearCache, clearCache,
newlineLength = TRANS_NEWLINE_LENGTH, newlineLength = TRANS_NEWLINE_LENGTH,
httpTimeout = HTTP_TIMEOUT,
contextMenuType = 1, contextMenuType = 1,
touchTranslate = 2, touchTranslate = 2,
blacklist = DEFAULT_BLACKLIST.join(",\n"), blacklist = DEFAULT_BLACKLIST.join(",\n"),
@@ -188,7 +193,14 @@ export default function Settings() {
defaultValue={transInterval} defaultValue={transInterval}
onChange={handleChange} onChange={handleChange}
/> />
<TextField
size="small"
label={i18n("http_timeout")}
type="number"
name="httpTimeout"
defaultValue={httpTimeout}
onChange={handleChange}
/>
<FormControl size="small"> <FormControl size="small">
<InputLabel>{i18n("touch_translate_shortcut")}</InputLabel> <InputLabel>{i18n("touch_translate_shortcut")}</InputLabel>
<Select <Select