Compare commits

..

14 Commits

Author SHA1 Message Date
Gabe Yuan
7b4b3b020c v1.7.6 2023-10-07 15:09:12 +08:00
Gabe Yuan
3e96540b56 fix createCache options key 2023-10-07 15:08:10 +08:00
Gabe Yuan
88b791bd73 fix createCache options key 2023-10-07 15:01:23 +08:00
Gabe Yuan
7817019e70 fix createCache options key 2023-10-07 14:57:36 +08:00
Gabe Yuan
6013bbd32c v1.7.5 2023-09-28 16:19:39 +08:00
Gabe Yuan
40e0b96f39 fix GM.xmlHttpRequest response 2023-09-28 16:18:28 +08:00
Gabe Yuan
16560fbdf0 fix install links 2023-09-27 15:39:57 +08:00
Gabe Yuan
16fdd704aa v1.7.4 2023-09-27 15:08:45 +08:00
Gabe Yuan
44e84d9259 minor revision 2023-09-25 11:56:46 +08:00
Gabe Yuan
18d29461ce minor revision 2023-09-25 11:47:12 +08:00
Gabe Yuan
31fb749e93 minor revision 2023-09-25 11:43:14 +08:00
Gabe Yuan
e17931493b add fab for ext 2023-09-23 19:16:51 +08:00
Gabe Yuan
a395f0b31b change newline length to 20 2023-09-22 16:37:35 +08:00
Gabe Yuan
c819896b43 change newline length to 30 2023-09-22 16:33:00 +08:00
21 changed files with 169 additions and 110 deletions

2
.env
View File

@@ -2,7 +2,7 @@ GENERATE_SOURCEMAP=false
REACT_APP_NAME=KISS Translator REACT_APP_NAME=KISS Translator
REACT_APP_NAME_CN=简约翻译 REACT_APP_NAME_CN=简约翻译
REACT_APP_VERSION=1.7.3 REACT_APP_VERSION=1.7.6
REACT_APP_HOMEPAGE=https://github.com/fishjar/kiss-translator REACT_APP_HOMEPAGE=https://github.com/fishjar/kiss-translator

View File

@@ -59,7 +59,7 @@ If you also like a little more simplicity, welcome to pick it up.
- Greasy Fork [Installation address](https://greasyfork.org/zh-CN/scripts/472840-kiss-translator) - Greasy Fork [Installation address](https://greasyfork.org/zh-CN/scripts/472840-kiss-translator)
- [x] iOS Safari ([Userscripts Safari](https://github.com/quoid/userscripts)) [Installation link 1](https://fishjar.github.io/kiss-translator/kiss-translator-ios-safari.user.js)、 [Installation link 2](https://kiss-translator.rayjar.com/kiss-translator.user-ios-safari.js) - [x] iOS Safari ([Userscripts Safari](https://github.com/quoid/userscripts)) [Installation link 1](https://fishjar.github.io/kiss-translator/kiss-translator-ios-safari.user.js)、 [Installation link 2](https://kiss-translator.rayjar.com/kiss-translator.user-ios-safari.js)
## Associated ProjectS ## Associated Projects
- Data synchronization service: [https://github.com/fishjar/kiss-worker](https://github.com/fishjar/kiss-worker) - Data synchronization service: [https://github.com/fishjar/kiss-worker](https://github.com/fishjar/kiss-worker)
- Data synchronization service available for this project. - Data synchronization service available for this project.

View File

@@ -1,7 +1,7 @@
{ {
"name": "kiss-translator", "name": "kiss-translator",
"description": "A minimalist bilingual translation Extension & Greasemonkey Script", "description": "A minimalist bilingual translation Extension & Greasemonkey Script",
"version": "1.7.3", "version": "1.7.6",
"author": "Gabe<yugang2002@gmail.com>", "author": "Gabe<yugang2002@gmail.com>",
"private": true, "private": true,
"dependencies": { "dependencies": {

View File

@@ -2,7 +2,7 @@
"manifest_version": 2, "manifest_version": 2,
"name": "__MSG_app_name__", "name": "__MSG_app_name__",
"description": "__MSG_app_description__", "description": "__MSG_app_description__",
"version": "1.7.3", "version": "1.7.6",
"default_locale": "en", "default_locale": "en",
"author": "Gabe<yugang2002@gmail.com>", "author": "Gabe<yugang2002@gmail.com>",
"homepage_url": "https://github.com/fishjar/kiss-translator", "homepage_url": "https://github.com/fishjar/kiss-translator",

View File

@@ -2,7 +2,7 @@
"manifest_version": 3, "manifest_version": 3,
"name": "__MSG_app_name__", "name": "__MSG_app_name__",
"description": "__MSG_app_description__", "description": "__MSG_app_description__",
"version": "1.7.3", "version": "1.7.6",
"default_locale": "en", "default_locale": "en",
"author": "Gabe<yugang2002@gmail.com>", "author": "Gabe<yugang2002@gmail.com>",
"homepage_url": "https://github.com/fishjar/kiss-translator", "homepage_url": "https://github.com/fishjar/kiss-translator",

View File

@@ -4,6 +4,8 @@ import {
MSG_FETCH_LIMIT, MSG_FETCH_LIMIT,
MSG_FETCH_CLEAR, MSG_FETCH_CLEAR,
MSG_TRANS_TOGGLE, MSG_TRANS_TOGGLE,
MSG_OPEN_OPTIONS,
MSG_SAVE_RULE,
MSG_TRANS_TOGGLE_STYLE, MSG_TRANS_TOGGLE_STYLE,
CMD_TOGGLE_TRANSLATE, CMD_TOGGLE_TRANSLATE,
CMD_TOGGLE_STYLE, CMD_TOGGLE_STYLE,
@@ -15,6 +17,7 @@ import { fetchData, fetchPool } from "./libs/fetch";
import { sendTabMsg } from "./libs/msg"; import { sendTabMsg } from "./libs/msg";
import { trySyncAllSubRules } from "./libs/subRules"; import { trySyncAllSubRules } from "./libs/subRules";
import { tryClearCaches } from "./libs"; import { tryClearCaches } from "./libs";
import { saveRule } from "./libs/rules";
globalThis.ContextType = "BACKGROUND"; globalThis.ContextType = "BACKGROUND";
@@ -69,6 +72,12 @@ browser.runtime.onMessage.addListener(
fetchPool.clear(); fetchPool.clear();
sendResponse({ data: "ok" }); sendResponse({ data: "ok" });
break; break;
case MSG_OPEN_OPTIONS:
browser.runtime.openOptionsPage();
break;
case MSG_SAVE_RULE:
saveRule(args);
break;
default: default:
sendResponse({ error: `message action is unavailable: ${action}` }); sendResponse({ error: `message action is unavailable: ${action}` });
} }

View File

@@ -50,20 +50,20 @@ const customApiHelpZH = `/// 自定义翻译源接口说明
method: "POST", method: "POST",
headers: { headers: {
"Content-type": "application/json", "Content-type": "application/json",
"Authorization" = "Bearer {{YOUR_KEY}}" "Authorization": "Bearer {{YOUR_KEY}}",
}, },
body: { body: {
text, // 需要翻译的文字 text: "", // 需要翻译的文字
from, // 源语言,可能为空,表示需要接口自动识别语言 from: "", // 源语言,可能为空,表示需要接口自动识别语言
to, // 目标语言 to: "", // 目标语言
} }
} }
// 返回Response数据需符合下面的JSON规范 // 返回Response数据需符合下面的JSON规范
{ {
text, // 翻译后的文字 text: "", // 翻译后的文字
from, // 识别的源语言 from: "", // 识别的源语言
to, // 目标语言(可选) to: "", // 目标语言(可选)
} }
// 支持的语言代码如下 // 支持的语言代码如下
@@ -78,20 +78,20 @@ const customApiHelpEN = `/// Custom translation source interface description
method: "POST", method: "POST",
headers: { headers: {
"Content-type": "application/json", "Content-type": "application/json",
"Authorization" = "Bearer {{YOUR_KEY}}" "Authorization": "Bearer {{YOUR_KEY}}",
}, },
body: { body: {
text, // text to be translated text: "", // text to be translated
from, // Source language, may be empty from: "", // Source language, may be empty
to, // Target language to: "", // Target language
} }
} }
// The returned data must conform to the following JSON specification // The returned data must conform to the following JSON specification
{ {
text, // translated text text: "", // translated text
from, // Recognized source language from: "", // Recognized source language
to, // Target language (optional) to: "", // Target language (optional)
} }
// The supported language codes are as follows // The supported language codes are as follows

View File

@@ -49,6 +49,8 @@ export const CACHE_NAME = `${APP_NAME}_cache`;
export const MSG_FETCH = "fetch"; export const MSG_FETCH = "fetch";
export const MSG_FETCH_LIMIT = "fetch_limit"; export const MSG_FETCH_LIMIT = "fetch_limit";
export const MSG_FETCH_CLEAR = "fetch_clear"; export const MSG_FETCH_CLEAR = "fetch_clear";
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 = "trans_toggle";
export const MSG_TRANS_TOGGLE_STYLE = "trans_toggle_style"; export const MSG_TRANS_TOGGLE_STYLE = "trans_toggle_style";
export const MSG_TRANS_GETRULE = "trans_getrule"; export const MSG_TRANS_GETRULE = "trans_getrule";
@@ -269,7 +271,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 = 40; // 换行字符数 export const TRANS_NEWLINE_LENGTH = 20; // 换行字符数
export const DEFAULT_SETTING = { export const DEFAULT_SETTING = {
darkMode: false, // 深色模式 darkMode: false, // 深色模式
@@ -287,7 +289,6 @@ export const DEFAULT_SETTING = {
transApis: DEFAULT_TRANS_APIS, // 翻译接口 transApis: DEFAULT_TRANS_APIS, // 翻译接口
mouseKey: OPT_MOUSEKEY_DISABLE, // 鼠标悬停翻译 mouseKey: OPT_MOUSEKEY_DISABLE, // 鼠标悬停翻译
shortcuts: DEFAULT_SHORTCUTS, // 快捷键 shortcuts: DEFAULT_SHORTCUTS, // 快捷键
hideFab: false, // 是否隐藏按钮
inputRule: DEFAULT_INPUT_RULE, // 输入框设置 inputRule: DEFAULT_INPUT_RULE, // 输入框设置
}; };
@@ -303,10 +304,6 @@ export const DEFAULT_SYNC = {
syncUser: "", // 数据同步用户名 syncUser: "", // 数据同步用户名
syncKey: "", // 数据同步密钥 syncKey: "", // 数据同步密钥
syncMeta: {}, // 数据更新及同步信息 syncMeta: {}, // 数据更新及同步信息
// settingUpdateAt: 0,
// settingSyncAt: 0,
// rulesUpdateAt: 0,
// rulesSyncAt: 0,
subRulesSyncAt: 0, // 订阅规则同步时间 subRulesSyncAt: 0, // 订阅规则同步时间
dataCaches: {}, // 缓存同步时间 dataCaches: {}, // 缓存同步时间
}; };

View File

@@ -1,11 +1,21 @@
import { browser } from "./libs/browser"; import { browser } from "./libs/browser";
import React from "react";
import ReactDOM from "react-dom/client";
import Action from "./views/Action";
import createCache from "@emotion/cache";
import { CacheProvider } from "@emotion/react";
import { import {
MSG_TRANS_TOGGLE, MSG_TRANS_TOGGLE,
MSG_TRANS_TOGGLE_STYLE, MSG_TRANS_TOGGLE_STYLE,
MSG_TRANS_GETRULE, MSG_TRANS_GETRULE,
MSG_TRANS_PUTRULE, MSG_TRANS_PUTRULE,
APP_LCNAME,
} from "./config"; } from "./config";
import { getSettingWithDefault, getRulesWithDefault } from "./libs/storage"; import {
getSettingWithDefault,
getRulesWithDefault,
getFabWithDefault,
} from "./libs/storage";
import { Translator } from "./libs/translator"; import { Translator } from "./libs/translator";
import { isIframe, sendIframeMsg, sendPrentMsg } from "./libs/iframe"; import { isIframe, sendIframeMsg, sendPrentMsg } from "./libs/iframe";
import { matchRule } from "./libs/rules"; import { matchRule } from "./libs/rules";
@@ -79,6 +89,31 @@ const init = async () => {
default: default:
} }
}); });
// 浮球按钮
const fab = await getFabWithDefault();
if (!fab.isHide) {
const $action = document.createElement("div");
$action.setAttribute("id", APP_LCNAME);
document.body.parentElement.appendChild($action);
const shadowContainer = $action.attachShadow({ mode: "closed" });
const emotionRoot = document.createElement("style");
const shadowRootElement = document.createElement("div");
shadowContainer.appendChild(emotionRoot);
shadowContainer.appendChild(shadowRootElement);
const cache = createCache({
key: APP_LCNAME,
prepend: true,
container: emotionRoot,
});
ReactDOM.createRoot(shadowRootElement).render(
<React.StrictMode>
<CacheProvider value={cache}>
<Action translator={translator} fab={fab} />
</CacheProvider>
</React.StrictMode>
);
}
}; };
(async () => { (async () => {

11
src/hooks/Fab.js Normal file
View File

@@ -0,0 +1,11 @@
import { STOKEY_FAB } from "../config";
import { useStorage } from "./Storage";
/**
* fab hook
* @returns
*/
export function useFab() {
const { data, update } = useStorage(STOKEY_FAB);
return { fab: data, updateFab: update };
}

View File

@@ -32,25 +32,23 @@ function App() {
href={process.env.REACT_APP_HOMEPAGE} href={process.env.REACT_APP_HOMEPAGE}
>{`KISS Translator v${process.env.REACT_APP_VERSION}`}</Link> >{`KISS Translator v${process.env.REACT_APP_VERSION}`}</Link>
</Divider> </Divider>
<Stack spacing={2} direction="row" useFlexGap flexWrap="wrap"> <Stack spacing={2}>
<Link href={process.env.REACT_APP_USERSCRIPT_DOWNLOADURL}> <Link href={process.env.REACT_APP_USERSCRIPT_DOWNLOADURL}>
Install Userscript 1 Install/Update Userscript for Tampermonkey/Violentmonkey
</Link>
<Link href={process.env.REACT_APP_USERSCRIPT_DOWNLOADURL2}>
Install Userscript 2
</Link> </Link>
{/* <Link href={process.env.REACT_APP_USERSCRIPT_DOWNLOADURL2}>
Install/Update Userscript for Tampermonkey/Violentmonkey 2
</Link> */}
<Link href={process.env.REACT_APP_USERSCRIPT_IOS_DOWNLOADURL}> <Link href={process.env.REACT_APP_USERSCRIPT_IOS_DOWNLOADURL}>
Install Userscript Safari 1 Install/Update Userscript for iOS Safari
</Link> </Link>
<Link href={process.env.REACT_APP_USERSCRIPT_IOS_DOWNLOADURL2}> {/* <Link href={process.env.REACT_APP_USERSCRIPT_IOS_DOWNLOADURL2}>
Install Userscript Safari 2 Install/Update Userscript for iOS Safari 2
</Link> </Link> */}
<Link href={process.env.REACT_APP_OPTIONSPAGE}> <Link href={process.env.REACT_APP_OPTIONSPAGE}>Open Options Page</Link>
Open Options Page 1 {/* <Link href={process.env.REACT_APP_OPTIONSPAGE2}>
</Link>
<Link href={process.env.REACT_APP_OPTIONSPAGE2}>
Open Options Page 2 Open Options Page 2
</Link> </Link> */}
</Stack> </Stack>
{loading ? ( {loading ? (

View File

@@ -28,19 +28,21 @@ export const fetchGM = async (input, { method = "GET", headers, body } = {}) =>
url: input, url: input,
headers, headers,
data: body, data: body,
onload: (response) => { onload: ({ response, responseHeaders, status, statusText }) => {
if (response.status < 300) {
const headers = new Headers(); const headers = new Headers();
response.responseHeaders.split("\n").forEach((line) => { responseHeaders.split("\n").forEach((line) => {
const [name, value] = line.split(":").map((item) => item.trim()); const [name, value] = line.split(":").map((item) => item.trim());
if (name && value) { if (name && value) {
headers.append(name, value); headers.append(name, value);
} }
}); });
resolve(new Response(response.response, { headers })); resolve(
} else { new Response(response, {
reject(new Error(`[${response.status}] ${response.responseText}`)); headers,
} status,
statusText,
})
);
}, },
onerror: reject, onerror: reject,
}); });

View File

@@ -119,6 +119,7 @@ export const setWebfix = (url, val) =>
export const getFab = () => getObj(STOKEY_FAB); export const getFab = () => getObj(STOKEY_FAB);
export const getFabWithDefault = async () => (await getFab()) || {}; export const getFabWithDefault = async () => (await getFab()) || {};
export const setFab = (obj) => setObj(STOKEY_FAB, obj); export const setFab = (obj) => setObj(STOKEY_FAB, obj);
export const updateFab = (obj) => putObj(STOKEY_FAB, obj);
/** /**
* 数据同步 * 数据同步

View File

@@ -15,6 +15,7 @@ import {
MSG_TRANS_TOGGLE_STYLE, MSG_TRANS_TOGGLE_STYLE,
MSG_TRANS_GETRULE, MSG_TRANS_GETRULE,
MSG_TRANS_PUTRULE, MSG_TRANS_PUTRULE,
APP_LCNAME,
} from "./config"; } from "./config";
import { isIframe, sendIframeMsg, sendPrentMsg } from "./libs/iframe"; import { isIframe, sendIframeMsg, sendPrentMsg } from "./libs/iframe";
import { handlePing, injectScript } from "./libs/gm"; import { handlePing, injectScript } from "./libs/gm";
@@ -98,7 +99,7 @@ const init = async () => {
// 浮球按钮 // 浮球按钮
const fab = await getFabWithDefault(); const fab = await getFabWithDefault();
const $action = document.createElement("div"); const $action = document.createElement("div");
$action.setAttribute("id", "kiss-translator"); $action.setAttribute("id", APP_LCNAME);
document.body.parentElement.appendChild($action); document.body.parentElement.appendChild($action);
const shadowContainer = $action.attachShadow({ mode: "closed" }); const shadowContainer = $action.attachShadow({ mode: "closed" });
const emotionRoot = document.createElement("style"); const emotionRoot = document.createElement("style");
@@ -106,7 +107,7 @@ const init = async () => {
shadowContainer.appendChild(emotionRoot); shadowContainer.appendChild(emotionRoot);
shadowContainer.appendChild(shadowRootElement); shadowContainer.appendChild(shadowRootElement);
const cache = createCache({ const cache = createCache({
key: "css", key: APP_LCNAME,
prepend: true, prepend: true,
container: emotionRoot, container: emotionRoot,
}); });

View File

@@ -1,7 +1,7 @@
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { limitNumber } from "../../libs/utils"; import { limitNumber } from "../../libs/utils";
import { isMobile } from "../../libs/mobile"; import { isMobile } from "../../libs/mobile";
import { setFab } from "../../libs/storage"; import { updateFab } from "../../libs/storage";
import { debounce } from "../../libs/utils"; import { debounce } from "../../libs/utils";
import Paper from "@mui/material/Paper"; import Paper from "@mui/material/Paper";
@@ -61,7 +61,7 @@ export default function Draggable({
const [hover, setHover] = useState(false); const [hover, setHover] = useState(false);
const [origin, setOrigin] = useState(null); const [origin, setOrigin] = useState(null);
const [position, setPosition] = useState({ x: left, y: top }); const [position, setPosition] = useState({ x: left, y: top });
const setFabPosition = useMemo(() => debounce(setFab, 500), []); const setFabPosition = useMemo(() => debounce(updateFab, 500), []);
const handlePointerDown = (e) => { const handlePointerDown = (e) => {
!isMobile && e.target.setPointerCapture(e.pointerId); !isMobile && e.target.setPointerCapture(e.pointerId);

View File

@@ -55,6 +55,10 @@ export default function Action({ translator, fab }) {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (!isGm) {
return;
}
// 注册快捷键 // 注册快捷键
const shortcuts = translator.setting.shortcuts || DEFAULT_SHORTCUTS; const shortcuts = translator.setting.shortcuts || DEFAULT_SHORTCUTS;
const clearShortcuts = [ const clearShortcuts = [
@@ -198,7 +202,7 @@ export default function Action({ translator, fab }) {
key="fab" key="fab"
snapEdge snapEdge
{...fabProps} {...fabProps}
show={translator.setting.hideFab ? false : !showPopup} show={fab.isHide ? false : !showPopup}
onStart={handleStart} onStart={handleStart}
onMove={handleMove} onMove={handleMove}
handler={ handler={

View File

@@ -120,7 +120,7 @@ export default function Content({ q, translator }) {
if (loading) { if (loading) {
return ( return (
<> <>
{q.length > newlineLength ? <br /> : " "} {q.length >= newlineLength ? <br /> : " "}
<LoadingIcon /> <LoadingIcon />
</> </>
); );
@@ -129,7 +129,7 @@ export default function Content({ q, translator }) {
if (text && !sameLang) { if (text && !sameLang) {
return ( return (
<> <>
{q.length > newlineLength ? <br /> : " "} {q.length >= newlineLength ? <br /> : " "}
<StyledSpan <StyledSpan
textStyle={textStyle} textStyle={textStyle}
textDiyStyle={textDiyStyle} textDiyStyle={textDiyStyle}

View File

@@ -554,7 +554,7 @@ function UserRules({ subRules }) {
<UploadButton text={i18n("import")} onChange={handleImport} /> <UploadButton text={i18n("import")} onChange={handleImport} />
<DownloadButton <DownloadButton
data={JSON.stringify([...rules.list].reverse(), null, "\t")} data={JSON.stringify([...rules.list].reverse(), null, 2)}
text={i18n("export")} text={i18n("export")}
/> />

View File

@@ -26,6 +26,7 @@ import {
} from "../../config"; } from "../../config";
import { useShortcut } from "../../hooks/Shortcut"; import { useShortcut } from "../../hooks/Shortcut";
import ShortcutInput from "./ShortcutInput"; import ShortcutInput from "./ShortcutInput";
import { useFab } from "../../hooks/Fab";
function ShortcutItem({ action, label }) { function ShortcutItem({ action, label }) {
const { shortcut, setShortcut } = useShortcut(action); const { shortcut, setShortcut } = useShortcut(action);
@@ -38,6 +39,7 @@ export default function Settings() {
const i18n = useI18n(); const i18n = useI18n();
const { setting, updateSetting } = useSetting(); const { setting, updateSetting } = useSetting();
const alert = useAlert(); const alert = useAlert();
const { fab, updateFab } = useFab();
const handleChange = (e) => { const handleChange = (e) => {
e.preventDefault(); e.preventDefault();
@@ -83,8 +85,8 @@ export default function Settings() {
clearCache, clearCache,
newlineLength = TRANS_NEWLINE_LENGTH, newlineLength = TRANS_NEWLINE_LENGTH,
mouseKey = OPT_MOUSEKEY_DISABLE, mouseKey = OPT_MOUSEKEY_DISABLE,
hideFab = false,
} = setting; } = setting;
const { isHide = false } = fab || {};
return ( return (
<Box> <Box>
@@ -166,6 +168,21 @@ export default function Settings() {
</Select> </Select>
</FormControl> </FormControl>
<FormControl size="small">
<InputLabel>{i18n("hide_fab_button")}</InputLabel>
<Select
name="isHide"
value={isHide}
label={i18n("hide_fab_button")}
onChange={(e) => {
updateFab({ isHide: e.target.value });
}}
>
<MenuItem value={false}>{i18n("show")}</MenuItem>
<MenuItem value={true}>{i18n("hide")}</MenuItem>
</Select>
</FormControl>
{isExt ? ( {isExt ? (
<FormControl size="small"> <FormControl size="small">
<InputLabel>{i18n("if_clear_cache")}</InputLabel> <InputLabel>{i18n("if_clear_cache")}</InputLabel>
@@ -186,19 +203,6 @@ export default function Settings() {
</FormControl> </FormControl>
) : ( ) : (
<> <>
<FormControl size="small">
<InputLabel>{i18n("hide_fab_button")}</InputLabel>
<Select
name="hideFab"
value={hideFab}
label={i18n("hide_fab_button")}
onChange={handleChange}
>
<MenuItem value={false}>{i18n("show")}</MenuItem>
<MenuItem value={true}>{i18n("hide")}</MenuItem>
</Select>
</FormControl>
<Box> <Box>
<Grid container spacing={2} columns={12}> <Grid container spacing={2} columns={12}>
<Grid item xs={12} sm={12} md={3} lg={3}> <Grid item xs={12} sm={12} md={3} lg={3}>

View File

@@ -37,7 +37,7 @@ export default function Options() {
// 检查版本是否一致 // 检查版本是否一致
if (version !== process.env.REACT_APP_VERSION) { if (version !== process.env.REACT_APP_VERSION) {
setError( setError(
`The version is inconsistent, please check whether the script(v${version}) is the latest version(v${process.env.REACT_APP_VERSION}). (版本不一致,请检查脚本(v${version})是否为最新版(v${process.env.REACT_APP_VERSION}))` `The version of the local script(v${version}) is not the latest version(v${process.env.REACT_APP_VERSION}). 本地脚本之版本(v${version})最新版(v${process.env.REACT_APP_VERSION})`
); );
break; break;
} }
@@ -54,7 +54,9 @@ export default function Options() {
} }
if (++i > 8) { if (++i > 8) {
setError("Time out. (连接超时)"); setError(
"Time out. Please confirm whether to install or enable KISS Translator GreaseMonkey script? 连接超时,请检查是否安装或启用简约翻译油猴脚本。"
);
break; break;
} }
@@ -71,39 +73,25 @@ export default function Options() {
if (error) { if (error) {
return ( return (
<center> <center>
<Alert severity="error">{error}</Alert>
<Divider> <Divider>
<Link <Link
href={process.env.REACT_APP_HOMEPAGE} href={process.env.REACT_APP_HOMEPAGE}
>{`KISS Translator v${process.env.REACT_APP_VERSION}`}</Link> >{`KISS Translator v${process.env.REACT_APP_VERSION}`}</Link>
</Divider> </Divider>
<h2> <Alert severity="error">{error}</Alert>
Please confirm whether to install or enable KISS Translator
GreaseMonkey script? (请检查是否安装或启用简约翻译油猴脚本)
</h2>
<Stack spacing={2}> <Stack spacing={2}>
<Link href={process.env.REACT_APP_USERSCRIPT_DOWNLOADURL}> <Link href={process.env.REACT_APP_USERSCRIPT_DOWNLOADURL}>
Install Userscript for Tampermonkey/Violentmonkey 1 (油猴脚本 Install/Update Userscript for Tampermonkey/Violentmonkey
安装地址 1)
</Link>
<Link href={process.env.REACT_APP_USERSCRIPT_DOWNLOADURL2}>
Install Userscript for Tampermonkey/Violentmonkey 2 (油猴脚本
安装地址 2)
</Link> </Link>
{/* <Link href={process.env.REACT_APP_USERSCRIPT_DOWNLOADURL2}>
Install/Update Userscript for Tampermonkey/Violentmonkey 2
</Link> */}
<Link href={process.env.REACT_APP_USERSCRIPT_IOS_DOWNLOADURL}> <Link href={process.env.REACT_APP_USERSCRIPT_IOS_DOWNLOADURL}>
Install Userscript for iOS Safari 1 (油猴脚本 iOS Safari专用 Install/Update Userscript for iOS Safari
安装地址 1)
</Link>
<Link href={process.env.REACT_APP_USERSCRIPT_IOS_DOWNLOADURL2}>
Install Userscript for iOS Safari 2 (油猴脚本 iOS Safari专用
安装地址 2)
</Link>
<Link href={process.env.REACT_APP_OPTIONSPAGE}>
Open Options Page 1 (打开设置页面 1)
</Link>
<Link href={process.env.REACT_APP_OPTIONSPAGE2}>
Open Options Page 2 (打开设置页面 2)
</Link> </Link>
{/* <Link href={process.env.REACT_APP_USERSCRIPT_IOS_DOWNLOADURL2}>
Install/Update Userscript for iOS Safari 2
</Link> */}
</Stack> </Stack>
</center> </center>
); );

View File

@@ -5,7 +5,7 @@ import MenuItem from "@mui/material/MenuItem";
import FormControlLabel from "@mui/material/FormControlLabel"; import FormControlLabel from "@mui/material/FormControlLabel";
import Switch from "@mui/material/Switch"; import Switch from "@mui/material/Switch";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import { sendTabMsg, getTabInfo } from "../../libs/msg"; import { sendBgMsg, sendTabMsg, getTabInfo } from "../../libs/msg";
import { browser } from "../../libs/browser"; import { browser } from "../../libs/browser";
import { isExt } from "../../libs/client"; import { isExt } from "../../libs/client";
import { useI18n } from "../../hooks/I18n"; import { useI18n } from "../../hooks/I18n";
@@ -16,6 +16,8 @@ import {
MSG_TRANS_TOGGLE, MSG_TRANS_TOGGLE,
MSG_TRANS_GETRULE, MSG_TRANS_GETRULE,
MSG_TRANS_PUTRULE, MSG_TRANS_PUTRULE,
MSG_OPEN_OPTIONS,
MSG_SAVE_RULE,
OPT_TRANS_ALL, OPT_TRANS_ALL,
OPT_LANGS_FROM, OPT_LANGS_FROM,
OPT_LANGS_TO, OPT_LANGS_TO,
@@ -31,8 +33,10 @@ export default function Popup({ setShowPopup, translator: tran }) {
const [rule, setRule] = useState(tran?.rule); const [rule, setRule] = useState(tran?.rule);
const handleOpenSetting = () => { const handleOpenSetting = () => {
if (isExt) { if (!tran) {
browser?.runtime.openOptionsPage(); browser?.runtime.openOptionsPage();
} else if (isExt) {
sendBgMsg(MSG_OPEN_OPTIONS);
} else { } else {
window.open(process.env.REACT_APP_OPTIONSPAGE, "_blank"); window.open(process.env.REACT_APP_OPTIONSPAGE, "_blank");
} }
@@ -43,7 +47,7 @@ export default function Popup({ setShowPopup, translator: tran }) {
try { try {
setRule({ ...rule, transOpen: e.target.checked ? "true" : "false" }); setRule({ ...rule, transOpen: e.target.checked ? "true" : "false" });
if (isExt) { if (!tran) {
await sendTabMsg(MSG_TRANS_TOGGLE); await sendTabMsg(MSG_TRANS_TOGGLE);
} else { } else {
tran.toggle(); tran.toggle();
@@ -59,7 +63,7 @@ export default function Popup({ setShowPopup, translator: tran }) {
const { name, value } = e.target; const { name, value } = e.target;
setRule((pre) => ({ ...pre, [name]: value })); setRule((pre) => ({ ...pre, [name]: value }));
if (isExt) { if (!tran) {
await sendTabMsg(MSG_TRANS_PUTRULE, { [name]: value }); await sendTabMsg(MSG_TRANS_PUTRULE, { [name]: value });
} else { } else {
tran.updateRule({ [name]: value }); tran.updateRule({ [name]: value });
@@ -77,18 +81,23 @@ export default function Popup({ setShowPopup, translator: tran }) {
const handleSaveRule = async () => { const handleSaveRule = async () => {
try { try {
let href = window.location.href; let href = window.location.href;
if (isExt) { if (!tran) {
const tab = await getTabInfo(); const tab = await getTabInfo();
href = tab.url; href = tab.url;
} }
saveRule({ ...rule, pattern: href }); const newRule = { ...rule, pattern: href };
if (isExt && tran) {
sendBgMsg(MSG_SAVE_RULE, newRule);
} else {
saveRule(newRule);
}
} catch (err) { } catch (err) {
console.log("[save rule]", err); console.log("[save rule]", err);
} }
}; };
useEffect(() => { useEffect(() => {
if (!isExt) { if (tran) {
return; return;
} }
(async () => { (async () => {
@@ -101,12 +110,12 @@ export default function Popup({ setShowPopup, translator: tran }) {
console.log("[query rule]", err); console.log("[query rule]", err);
} }
})(); })();
}, []); }, [tran]);
if (!rule) { if (!rule) {
return ( return (
<Box minWidth={300}> <Box minWidth={300}>
{isExt && ( {!tran && (
<> <>
<Header /> <Header />
<Divider /> <Divider />
@@ -125,7 +134,7 @@ export default function Popup({ setShowPopup, translator: tran }) {
return ( return (
<Box minWidth={300}> <Box minWidth={300}>
{isExt && ( {!tran && (
<> <>
<Header /> <Header />
<Divider /> <Divider />