Compare commits

..

12 Commits

Author SHA1 Message Date
Gabe Yuan
e0b7c60099 v1.6.4 2023-09-02 20:07:24 +08:00
Gabe Yuan
536b58bf67 fix fuzzy style hover bug 2023-09-02 19:55:26 +08:00
Gabe Yuan
6bb742f828 v1.6.3 2023-09-02 19:16:14 +08:00
Gabe Yuan
72742e5e12 fix build:script 2023-09-02 19:09:12 +08:00
Gabe Yuan
3667e0a509 update readme 2023-09-02 18:14:42 +08:00
Gabe Yuan
c2d7668ba7 v1.6.2 2023-09-02 17:26:37 +08:00
Gabe Yuan
aa830f5e20 update readme 2023-09-02 17:22:35 +08:00
Gabe Yuan
b593fa4146 add deepl api 2023-09-02 16:57:09 +08:00
Gabe Yuan
b00b906484 optimize inject script 2023-09-02 15:54:51 +08:00
Gabe Yuan
c1bd6a1be6 use random eventname 2023-09-02 14:14:27 +08:00
Gabe Yuan
36739f04b3 add more shortcut 2023-09-02 13:14:27 +08:00
Gabe Yuan
23eb92853e register a shortcut for userscript 2023-09-02 00:42:15 +08:00
19 changed files with 264 additions and 85 deletions

2
.env
View File

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

View File

@@ -1,10 +1,10 @@
## KISS Translator
# KISS Translator
A minimalist [bilingual translation Extension & Greasemonkey Script](https://github.com/fishjar/kiss-translator).
[kiss-translator.webm](https://github.com/fishjar/kiss-translator/assets/1157624/f7ba8a5c-e4a8-4d5a-823a-5c5c67a0a47f)
### Inspiration
## Inspiration
The inspiration for this project comes from [Immersive Translate](https://github.com/immersive-translate/immersive-translate). After trying it out, I found that it can be used together with the [Webpage Word Translation Extension](https://github.com/fishjar/kiss-dictionary) developed by me earlier, which just forms a very good supplement.
@@ -14,11 +14,11 @@ It just so happens that I am obsessed with translation tools. Based on the conce
If you also like a little more simplicity, welcome to pick it up.
### Features
## Features
- Keep it simple, smart
### Schedule
## Schedule
- [x] Provide trial installation package
- [x] Adapt browser
@@ -31,7 +31,7 @@ If you also like a little more simplicity, welcome to pick it up.
- [x] Google
- [x] Microsoft
- [x] OpenAI
- [ ] DeepL
- [x] DeepL
- [x] Upload to app Store
- [x] Chrome [Install Link](https://chrome.google.com/webstore/detail/kiss-translator/bdiifdefkgmcblbcghdlonllpjhhjgof)
- [x] Edge [Install Link](https://microsoftedge.microsoft.com/addons/detail/kiss-translator/jemckldkclkinpjighnoilpbldbdmmlh)
@@ -42,9 +42,10 @@ If you also like a little more simplicity, welcome to pick it up.
- [x] Data Synchronization Function
- [x] Greasemonkey Script ([Setting Page 1](https://fishjar.github.io/kiss-translator/options.html)、[Setting Page 2](https://kiss-translator.rayjar.com/options))
- [x] [Tampermonkey](https://www.tampermonkey.net/) (Chrome/Edge/Firefox) [Install Link 1](https://fishjar.github.io/kiss-translator/kiss-translator.user.js)、[Install Link 2](https://kiss-translator.rayjar.com/kiss-translator.user.js)
- [x] [Violentmonkey](https://violentmonkey.github.io/) (Chrome/Edge/Firefox) [Install Link 1](https://fishjar.github.io/kiss-translator/kiss-translator.user.js)、[Install Link 2](https://kiss-translator.rayjar.com/kiss-translator.user.js)
- [x] [Userscripts Safari](https://github.com/quoid/userscripts) (iOS Safari) [Install Link 1](https://fishjar.github.io/kiss-translator/kiss-translator-ios-safari.user.js)、[Install Link 2](https://kiss-translator.rayjar.com/kiss-translator.user-ios-safari.js)
### Guide
## Guide
```sh
git clone https://github.com/fishjar/kiss-translator.git
@@ -53,10 +54,10 @@ yarn install
yarn build
```
### Data Sync
## Data Sync
Goto: [https://github.com/fishjar/kiss-worker](https://github.com/fishjar/kiss-worker)
### Discussion
## Discussion
- Join [Telegram Group](https://t.me/+RRCu_4oNwrM2NmFl)

View File

@@ -1,10 +1,10 @@
## 简约翻译
# 简约翻译
一个简约的 [双语网页翻译扩展 & 油猴脚本](https://github.com/fishjar/kiss-translator)。
[kiss-translator.webm](https://github.com/fishjar/kiss-translator/assets/1157624/f7ba8a5c-e4a8-4d5a-823a-5c5c67a0a47f)
### 缘由
## 缘由
本项目灵感来源于 [Immersive Translate](https://github.com/immersive-translate/immersive-translate),在试用了后,发现搭配本人早前开发的 [网页划词翻译扩展](https://github.com/fishjar/kiss-dictionary) 一起使用,刚好形成很好补充。
@@ -14,11 +14,11 @@
如果你也喜欢简约一点的,欢迎自取。
### 特点
## 特点
- 保持简约
### 进度
## 进度
- [x] 提供试用安装包
- [x] 适配浏览器
@@ -31,7 +31,7 @@
- [x] Google
- [x] Microsoft
- [x] OpenAI
- [ ] DeepL
- [x] DeepL
- [x] 上架应用市场
- [x] Chrome [安装地址](https://chrome.google.com/webstore/detail/kiss-translator/bdiifdefkgmcblbcghdlonllpjhhjgof?hl=zh-CN)
- [x] Edge [安装地址](https://microsoftedge.microsoft.com/addons/detail/%E7%AE%80%E7%BA%A6%E7%BF%BB%E8%AF%91/jemckldkclkinpjighnoilpbldbdmmlh?hl=zh-CN)
@@ -42,9 +42,10 @@
- [x] 数据同步功能
- [x] 油猴脚本 ([设置页面 1](https://fishjar.github.io/kiss-translator/options.html)、[设置页面 2](https://kiss-translator.rayjar.com/options))
- [x] [Tampermonkey](https://www.tampermonkey.net/) (Chrome/Edge/Firefox) [安装链接 1](https://fishjar.github.io/kiss-translator/kiss-translator.user.js)、[安装链接 2](https://kiss-translator.rayjar.com/kiss-translator.user.js)
- [x] [Violentmonkey](https://violentmonkey.github.io/) (Chrome/Edge/Firefox) [安装链接 1](https://fishjar.github.io/kiss-translator/kiss-translator.user.js)、[安装链接 2](https://kiss-translator.rayjar.com/kiss-translator.user.js)
- [x] [Userscripts Safari](https://github.com/quoid/userscripts) (iOS Safari) [安装链接 1](https://fishjar.github.io/kiss-translator/kiss-translator-ios-safari.user.js)、[安装链接 2](https://kiss-translator.rayjar.com/kiss-translator.user-ios-safari.js)
### 指引
## 指引
```sh
git clone https://github.com/fishjar/kiss-translator.git
@@ -53,10 +54,10 @@ yarn install
yarn build
```
### 数据同步
## 数据同步
移步: [https://github.com/fishjar/kiss-worker](https://github.com/fishjar/kiss-worker)
### 交流
## 交流
- 加入 [Telegram 群](https://t.me/+RRCu_4oNwrM2NmFl)

View File

@@ -1,7 +1,7 @@
{
"name": "kiss-translator",
"description": "A minimalist bilingual translation Extension & Greasemonkey Script",
"version": "1.6.1",
"version": "1.6.4",
"author": "Gabe<yugang2002@gmail.com>",
"private": true,
"dependencies": {
@@ -9,6 +9,7 @@
"@emotion/styled": "^11.10.8",
"@mui/icons-material": "^5.11.11",
"@mui/material": "^5.11.12",
"@violentmonkey/shortcut": "^1.3.0",
"query-string": "^8.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@@ -25,10 +26,10 @@
"build:edge": "rm -rf build/edge && cp -r build/chrome build/edge",
"build:firefox": "rm -rf build/firefox && cp -r build/chrome build/firefox && cat ./build/firefox/manifest.firefox.json > ./build/firefox/manifest.json",
"build:web": "rm -rf build/web && BUILD_PATH=./build/web REACT_APP_CLIENT=userscript react-app-rewired build",
"build:userscript": "rm -rf build/userscript && mkdir build/userscript && cp build/web/kiss-translator.user.js build/userscript/kiss-translator.user.js",
"build:userscript-ios": "file1=build/userscript/kiss-translator.user.js file2=build/userscript/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:rules": "babel-node src/rules.js",
"build": "yarn build:chrome && yarn build:edge && yarn build:firefox && yarn build:web && yarn build:userscript && yarn build:userscript-ios && yarn build:rules",
"build": "yarn build:chrome && yarn build:edge && yarn build:firefox && yarn build:web && yarn build:userscript-ios && yarn build:userscript && yarn build:rules",
"deploy:web": "wrangler pages deploy ./build/web --project-name kiss-translator",
"test": "react-app-rewired test",
"eject": "react-scripts eject"

View File

@@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "__MSG_app_name__",
"description": "__MSG_app_description__",
"version": "1.6.1",
"version": "1.6.4",
"default_locale": "en",
"author": "Gabe<yugang2002@gmail.com>",
"homepage_url": "https://github.com/fishjar/kiss-translator",
@@ -17,6 +17,11 @@
}
],
"commands": {
"_execute_browser_action": {
"suggested_key": {
"default": "Alt+K"
}
},
"toggleTranslate": {
"suggested_key": {
"default": "Alt+Q"

View File

@@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "__MSG_app_name__",
"description": "__MSG_app_description__",
"version": "1.6.1",
"version": "1.6.4",
"default_locale": "en",
"author": "Gabe<yugang2002@gmail.com>",
"homepage_url": "https://github.com/fishjar/kiss-translator",
@@ -18,6 +18,11 @@
}
],
"commands": {
"_execute_action": {
"suggested_key": {
"default": "Alt+K"
}
},
"toggleTranslate": {
"suggested_key": {
"default": "Alt+Q"

View File

@@ -3,6 +3,7 @@ import { fetchPolyfill } from "../libs/fetch";
import {
OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPL,
OPT_TRANS_OPENAI,
URL_MICROSOFT_TRANS,
OPT_LANGS_SPECIAL,
@@ -95,6 +96,36 @@ const apiMicrosoftTranslate = (translator, text, to, from) => {
});
};
/**
* DeepL翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiDeepLTranslate = (translator, text, to, from, setting) => {
const { deeplUrl, deeplKey } = setting;
const data = {
text: [text],
target_lang: to,
split_sentences: "0",
};
if (from) {
data.source_lang = from;
}
return fetchPolyfill(deeplUrl, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
useCache: true,
usePool: true,
translator,
token: deeplKey,
});
};
/**
* OpenAI 翻译
* @param {*} text
@@ -160,6 +191,10 @@ export const apiTranslate = async ({
const res = await apiMicrosoftTranslate(translator, q, to, from);
trText = res[0].translations[0].text;
isSame = to === res[0].detectedLanguage.language;
} else if (translator === OPT_TRANS_DEEPL) {
const res = await apiDeepLTranslate(translator, q, to, from, setting);
trText = res.translations.map((item) => item.text).join(" ");
isSame = to === res.translations[0].detected_source_language;
} else if (translator === OPT_TRANS_OPENAI) {
const res = await apiOpenaiTranslate(translator, q, to, from, setting);
trText = res?.choices?.[0].message.content;

View File

@@ -260,6 +260,14 @@ export const I18N = {
zh: `请检查url地址是否正确或稍后再试。`,
en: `Please check if the url address is correct or try again later.`,
},
deepl_api: {
zh: `DeepL 接口`,
en: `DeepL API`,
},
deepl_key: {
zh: `DeepL 密钥`,
en: `DeepL Key`,
},
openai_api: {
zh: `OpenAI 接口`,
en: `OpenAI API`,

View File

@@ -53,8 +53,6 @@ export const MSG_TRANS_GETRULE = "trans_getrule";
export const MSG_TRANS_PUTRULE = "trans_putrule";
export const MSG_TRANS_CURRULE = "trans_currule";
export const EVENT_KISS = "kissEvent";
export const THEME_LIGHT = "light";
export const THEME_DARK = "dark";
@@ -68,10 +66,12 @@ export const URL_MICROSOFT_TRANS =
export const OPT_TRANS_GOOGLE = "Google";
export const OPT_TRANS_MICROSOFT = "Microsoft";
export const OPT_TRANS_DEEPL = "DeepL";
export const OPT_TRANS_OPENAI = "OpenAI";
export const OPT_TRANS_ALL = [
OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPL,
OPT_TRANS_OPENAI,
];
@@ -121,6 +121,12 @@ export const OPT_LANGS_SPECIAL = {
["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_OPENAI]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
),
@@ -202,6 +208,8 @@ export const DEFAULT_SETTING = {
subrulesList: DEFAULT_SUBRULES_LIST, // 订阅列表
owSubrule: DEFAULT_OW_RULE, // 覆写订阅规则
googleUrl: "https://translate.googleapis.com/translate_a/single", // 谷歌翻译接口
deeplUrl: "https://api-free.deepl.com/v2/translate",
deeplKey: "",
openaiUrl: "https://api.openai.com/v1/chat/completions",
openaiKey: "",
openaiModel: "gpt-4",

View File

@@ -7,6 +7,7 @@ import {
MSG_FETCH_CLEAR,
CACHE_NAME,
OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPL,
OPT_TRANS_OPENAI,
DEFAULT_FETCH_INTERVAL,
DEFAULT_FETCH_LIMIT,
@@ -67,9 +68,11 @@ const newCacheReq = async (request) => {
*/
const fetchApi = async ({ input, init = {}, translator, token }) => {
if (translator === OPT_TRANS_MICROSOFT) {
init.headers["Authorization"] = `Bearer ${token}`;
init.headers["Authorization"] = `Bearer ${token}`; // Microsoft
} else if (translator === OPT_TRANS_DEEPL) {
init.headers["Authorization"] = `DeepL-Auth-Key ${token}`; // DeepL
} else if (translator === OPT_TRANS_OPENAI) {
init.headers["Authorization"] = `Bearer ${token}`; // // OpenAI
init.headers["Authorization"] = `Bearer ${token}`; // OpenAI
init.headers["api-key"] = token; // Azure OpenAI
}

View File

@@ -1,20 +1,31 @@
import { fetchGM } from "./fetch";
import { genEventName } from "./utils";
const MSG_GM_xmlHttpRequest = "xmlHttpRequest";
const MSG_GM_setValue = "setValue";
const MSG_GM_getValue = "getValue";
const MSG_GM_deleteValue = "deleteValue";
const MSG_GM_info = "info";
/**
* 注入页面的脚本请求并接受GM接口信息
* @param {*} param0
*/
export const injectScript = (ping) => {
const MSG_GM_xmlHttpRequest = "xmlHttpRequest";
const MSG_GM_setValue = "setValue";
const MSG_GM_getValue = "getValue";
const MSG_GM_deleteValue = "deleteValue";
const MSG_GM_info = "info";
let GM_info;
window.APP_INFO = {
name: process.env.REACT_APP_NAME,
version: process.env.REACT_APP_VERSION,
eventName: ping,
};
};
/**
* 适配GM脚本
*/
export const adaptScript = (ping) => {
const promiseGM = (action, args, timeout = 5000) =>
new Promise((resolve, reject) => {
const pong = btoa(Math.random()).slice(3, 11);
const pong = genEventName();
const handleEvent = (e) => {
window.removeEventListener(pong, handleEvent);
const { data, error } = e.detail;
@@ -41,14 +52,13 @@ export const injectScript = (ping) => {
setValue: (key, val) => promiseGM(MSG_GM_setValue, { key, val }),
getValue: (key) => promiseGM(MSG_GM_getValue, { key }),
deleteValue: (key) => promiseGM(MSG_GM_deleteValue, { key }),
getInfo: () => {
if (GM_info) {
return GM_info;
getInfo: async () => {
if (!window.GM_info) {
window.GM_info = await promiseGM(MSG_GM_info);
}
return promiseGM(MSG_GM_info);
return window.GM_info;
},
};
window.APP_NAME = process.env.REACT_APP_NAME;
};
/**
@@ -56,11 +66,6 @@ export const injectScript = (ping) => {
* @param {*} param0
*/
export const handlePing = async (e) => {
const MSG_GM_xmlHttpRequest = "xmlHttpRequest";
const MSG_GM_setValue = "setValue";
const MSG_GM_getValue = "getValue";
const MSG_GM_deleteValue = "deleteValue";
const MSG_GM_info = "info";
const { action, args, pong } = e.detail;
let res;
try {

View File

@@ -3,7 +3,6 @@ import {
APP_LCNAME,
TRANS_MIN_LENGTH,
TRANS_MAX_LENGTH,
EVENT_KISS,
MSG_TRANS_CURRULE,
OPT_STYLE_DASHLINE,
OPT_STYLE_FUZZY,
@@ -11,7 +10,7 @@ import {
} from "../config";
import Content from "../views/Content";
import { updateFetchPool, clearFetchPool } from "./fetch";
import { debounce } from "./utils";
import { debounce, genEventName } from "./utils";
/**
* 翻译类
@@ -37,6 +36,7 @@ export class Translator {
"script",
"iframe",
];
_eventName = genEventName();
// 显示
_interseObserver = new IntersectionObserver(
@@ -105,6 +105,10 @@ export class Translator {
return this._setting;
}
get eventName() {
return this._eventName;
}
get rule() {
// console.log("get rule", this._rule);
return this._rule;
@@ -115,8 +119,9 @@ export class Translator {
this._rule = rule;
// 广播消息
const eventName = this._eventName;
window.dispatchEvent(
new CustomEvent(EVENT_KISS, {
new CustomEvent(eventName, {
detail: {
action: MSG_TRANS_CURRULE,
args: rule,

View File

@@ -116,3 +116,9 @@ export const sha256 = async (text, salt) => {
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
};
/**
* 生成随机事件名称
* @returns
*/
export const genEventName = () => btoa(Math.random()).slice(3, 11);

View File

@@ -10,11 +10,11 @@ import {
} from "./libs/storage";
import { Translator } from "./libs/translator";
import { trySyncAllSubRules } from "./libs/subRules";
import { isGm } from "./libs/client";
import { MSG_TRANS_TOGGLE, MSG_TRANS_PUTRULE } from "./config";
import { isIframe } from "./libs/iframe";
import { handlePing, injectScript } from "./libs/gm";
import { matchRule } from "./libs/rules";
import { genEventName } from "./libs/utils";
/**
* 入口函数
@@ -28,9 +28,12 @@ const init = async () => {
) {
if (GM?.info?.script?.grant?.includes("unsafeWindow")) {
unsafeWindow.GM = GM;
unsafeWindow.APP_NAME = process.env.REACT_APP_NAME;
unsafeWindow.APP_INFO = {
name: process.env.REACT_APP_NAME,
version: process.env.REACT_APP_VERSION,
};
} else {
const ping = btoa(Math.random()).slice(3, 11);
const ping = genEventName();
window.addEventListener(ping, handlePing);
// window.eval(`(${injectScript})("${ping}")`); // eslint-disable-line
const script = document.createElement("script");
@@ -88,28 +91,6 @@ const init = async () => {
</React.StrictMode>
);
// 注册菜单
if (isGm) {
try {
GM.registerMenuCommand(
"Toggle Translate",
(event) => {
translator.toggle();
},
"Q"
);
GM.registerMenuCommand(
"Toggle Style",
(event) => {
translator.toggleStyle();
},
"C"
);
} catch (err) {
console.log("[registerMenuCommand]", err);
}
}
// 同步订阅规则
trySyncAllSubRules(setting);
};

View File

@@ -11,6 +11,8 @@ import { useEffect, useState, useMemo, useCallback } from "react";
import { SettingProvider } from "../../hooks/Setting";
import Popup from "../Popup";
import { debounce } from "../../libs/utils";
import * as shortcut from "@violentmonkey/shortcut";
import { isGm } from "../../libs/client";
export default function Action({ translator, fab }) {
const fabWidth = 40;
@@ -44,6 +46,73 @@ export default function Action({ translator, fab }) {
setMoved(true);
}, []);
useEffect(() => {
// 注册快捷键
shortcut.register("a-q", () => {
translator.toggle();
setShowPopup(false);
});
shortcut.register("a-c", () => {
translator.toggleStyle();
setShowPopup(false);
});
shortcut.register("a-k", () => {
setShowPopup((pre) => !pre);
});
return () => {
shortcut.disable();
};
}, [translator]);
useEffect(() => {
// 注册菜单
const menuCommandIds = [];
if (isGm) {
try {
menuCommandIds.push(
GM.registerMenuCommand(
"Toggle Translate",
(event) => {
translator.toggle();
setShowPopup(false);
},
"Q"
),
GM.registerMenuCommand(
"Toggle Style",
(event) => {
translator.toggleStyle();
setShowPopup(false);
},
"C"
),
GM.registerMenuCommand(
"Open Menu",
(event) => {
setShowPopup((pre) => !pre);
},
"K"
)
);
} catch (err) {
console.log("[registerMenuCommand]", err);
}
}
return () => {
if (isGm) {
try {
menuCommandIds.forEach((id) => {
GM.unregisterMenuCommand(id);
});
} catch (err) {
//
}
}
};
}, [translator]);
useEffect(() => {
window.addEventListener("resize", handleWindowResize);
return () => {
@@ -53,6 +122,7 @@ export default function Action({ translator, fab }) {
useEffect(() => {
window.addEventListener("click", handleWindowClick);
return () => {
window.removeEventListener("click", handleWindowClick);
};

View File

@@ -9,7 +9,6 @@ import {
OPT_STYLE_HIGHLIGHT,
OPT_STYLE_DIY,
DEFAULT_COLOR,
EVENT_KISS,
MSG_TRANS_CURRULE,
TRANS_NEWLINE_LENGTH,
} from "../../config";
@@ -18,6 +17,7 @@ import styled from "styled-components";
const LineSpan = styled.span`
opacity: 0.6;
-webkit-opacity: 0.6;
text-decoration-line: underline;
text-decoration-style: ${(props) => props.$lineStyle};
text-decoration-color: ${(props) => props.$lineColor};
@@ -30,23 +30,22 @@ const LineSpan = styled.span`
-webkit-text-underline-offset: 0.3em;
&:hover {
opacity: 1;
-webkit-opacity: 1;
}
`;
const FuzzySpan = styled.span`
filter: blur(5px);
transition: filter 0.2s ease-in-out;
&hover: {
-webkit-filter: blur(5px);
&:hover {
filter: none;
-webkit-filter: none;
}
`;
const HighlightSpan = styled.span`
color: #fff;
background-color: ${(props) => props.$bgColor};
&hover: {
filter: none;
}
`;
const DiySpan = styled.span`
@@ -112,11 +111,11 @@ export default function Content({ q, translator }) {
};
useEffect(() => {
window.addEventListener(EVENT_KISS, handleKissEvent);
window.addEventListener(translator.eventName, handleKissEvent);
return () => {
window.removeEventListener(EVENT_KISS, handleKissEvent);
window.removeEventListener(translator.eventName, handleKissEvent);
};
}, []);
}, [translator.eventName]);
if (loading) {
return (

View File

@@ -49,6 +49,8 @@ export default function Settings() {
minLength,
maxLength,
openaiUrl,
deeplUrl = "",
deeplKey = "",
openaiKey,
openaiModel,
openaiPrompt,
@@ -144,6 +146,22 @@ export default function Settings() {
}
/>
<TextField
size="small"
label={i18n("deepl_api")}
name="deeplUrl"
value={deeplUrl}
onChange={handleChange}
/>
<TextField
size="small"
label={i18n("deepl_key")}
name="deeplKey"
value={deeplKey}
onChange={handleChange}
/>
<TextField
size="small"
label={i18n("openai_api")}

View File

@@ -15,9 +15,11 @@ import { AlertProvider } from "../../hooks/Alert";
import Link from "@mui/material/Link";
import Divider from "@mui/material/Divider";
import Stack from "@mui/material/Stack";
import { adaptScript } from "../../libs/gm";
import Alert from "@mui/material/Alert";
export default function Options() {
const [error, setError] = useState(false);
const [error, setError] = useState("");
const [ready, setReady] = useState(false);
useEffect(() => {
@@ -26,7 +28,22 @@ export default function Options() {
// 等待GM注入
let i = 0;
for (;;) {
if (window.APP_NAME === process.env.REACT_APP_NAME) {
if (window?.APP_INFO?.name === process.env.REACT_APP_NAME) {
const { version, eventName } = window.APP_INFO;
// 检查版本是否一致
if (version !== process.env.REACT_APP_VERSION) {
setError(
`The version of the script(v${version}) and this page(v${process.env.REACT_APP_VERSION}) are inconsistent.`
);
break;
}
if (eventName) {
// 注入GM接口
adaptScript(eventName);
}
// 同步数据
await trySyncSettingAndRules();
setReady(true);
@@ -34,7 +51,7 @@ export default function Options() {
}
if (++i > 8) {
setError(true);
setError("Time out.");
break;
}
@@ -51,6 +68,7 @@ export default function Options() {
if (error) {
return (
<center>
<Alert severity="error">{error}</Alert>
<Divider>
<Link
href={process.env.REACT_APP_HOMEPAGE}

View File

@@ -1663,7 +1663,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.22.10, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7":
"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.22.10, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7":
version: 7.22.11
resolution: "@babel/runtime@npm:7.22.11"
dependencies:
@@ -3841,6 +3841,15 @@ __metadata:
languageName: node
linkType: hard
"@violentmonkey/shortcut@npm:^1.3.0":
version: 1.3.0
resolution: "@violentmonkey/shortcut@npm:1.3.0"
dependencies:
"@babel/runtime": ^7.20.1
checksum: 5c839c0193014ff29d000337c8cb03f950e5386379a5cc7c845b9e4c566126dc1cfc431b71bc591e30ce7b8a5e82c2fc38396d52b705352252eb0376a7d18fd3
languageName: node
linkType: hard
"@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5":
version: 1.11.6
resolution: "@webassemblyjs/ast@npm:1.11.6"
@@ -9516,6 +9525,7 @@ __metadata:
"@emotion/styled": ^11.10.8
"@mui/icons-material": ^5.11.11
"@mui/material": ^5.11.12
"@violentmonkey/shortcut": ^1.3.0
query-string: ^8.1.0
react: ^18.2.0
react-app-rewired: ^2.2.1