optimize Translator class & EVENT_KISS event

This commit is contained in:
Gabe Yuan
2023-08-09 13:22:10 +08:00
parent 5b38c38feb
commit 8bfd02bbc4
3 changed files with 69 additions and 57 deletions

View File

@@ -1,63 +1,26 @@
import { useEffect } from "react";
import { useState } from "react";
import { transPool } from "../libs/pool";
import { browser } from "../libs/browser";
import { MSG_TRANS_PUTRULE, EVENT_KISS } from "../config";
import { detectLang } from "../libs";
import { isExt } from "../libs/browser";
/**
* 翻译hook
* @param {*} q
* @param {*} rule
* @returns
*/
export function useTranslate(q, initRule) {
export function useTranslate(q, rule) {
const [text, setText] = useState("");
const [loading, setLoading] = useState(false);
const [sameLang, setSamelang] = useState(false);
const [rule, setRule] = useState(initRule);
const { translator, fromLang, toLang, textStyle, bgColor } = rule;
const handleMessage = ({ action, args }) => {
if (action === MSG_TRANS_PUTRULE) {
setRule((pre) => ({ ...pre, ...args }));
}
return true;
};
const handleKissEvent = (e) => {
const action = e?.detail?.action;
const args = e?.detail?.args || {};
switch (action) {
case MSG_TRANS_PUTRULE:
setRule((pre) => ({ ...pre, ...args }));
break;
default:
// console.log(`[popup] kissEvent action skip: ${action}`);
}
};
useEffect(() => {
if (isExt) {
browser?.runtime.onMessage.addListener(handleMessage);
} else {
window.addEventListener(EVENT_KISS, handleKissEvent);
}
return () => {
if (isExt) {
browser?.runtime.onMessage.removeListener(handleMessage);
} else {
window.removeEventListener(EVENT_KISS, handleKissEvent);
}
};
}, []);
const { translator, fromLang, toLang } = rule;
useEffect(() => {
(async () => {
try {
setLoading(true);
const deLang = await detectLang(q);
if (toLang.includes(deLang)) {
setSamelang(true);
@@ -79,5 +42,5 @@ export function useTranslate(q, initRule) {
})();
}, [q, translator, fromLang, toLang]);
return { text, sameLang, loading, textStyle, bgColor };
return { text, sameLang, loading };
}

View File

@@ -1,5 +1,11 @@
import { createRoot } from "react-dom/client";
import { APP_LCNAME, TRANS_MIN_LENGTH, TRANS_MAX_LENGTH } from "../config";
import {
APP_LCNAME,
TRANS_MIN_LENGTH,
TRANS_MAX_LENGTH,
EVENT_KISS,
MSG_TRANS_CURRULE,
} from "../config";
import { StoragesProvider } from "../hooks/Storage";
import { queryEls } from ".";
import Content from "../views/Content";
@@ -28,7 +34,7 @@ export class Translator {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
try {
queryEls(this._rule.selector, node).forEach((el) => {
queryEls(this.rule.selector, node).forEach((el) => {
this._interseObserver.observe(el);
});
} catch (err) {
@@ -39,26 +45,42 @@ export class Translator {
});
constructor(rule) {
this._rule = rule;
this.rule = rule;
if (rule.transOpen === "true") {
this._register();
}
}
get rule() {
// console.log("get rule", this._rule);
return this._rule;
}
set rule(rule) {
// console.log("set rule", rule);
this._rule = rule;
// 广播消息
window.dispatchEvent(
new CustomEvent(EVENT_KISS, {
detail: {
action: MSG_TRANS_CURRULE,
args: rule,
},
})
);
}
updateRule = (obj) => {
this._rule = { ...this._rule, ...obj };
this.rule = { ...this.rule, ...obj };
};
toggle = () => {
if (this._rule.transOpen === "true") {
this._rule = { ...this._rule, transOpen: "false" };
if (this.rule.transOpen === "true") {
this.rule = { ...this.rule, transOpen: "false" };
this._unRegister();
} else {
this._rule = { ...this._rule, transOpen: "true" };
this.rule = { ...this.rule, transOpen: "true" };
this._register();
}
};
@@ -71,7 +93,7 @@ export class Translator {
});
// 监听节点显示
queryEls(this._rule.selector).forEach((el) => {
queryEls(this.rule.selector).forEach((el) => {
this._interseObserver.observe(el);
});
};
@@ -81,7 +103,7 @@ export class Translator {
this._mutaObserver.disconnect();
// 解除节点显示监听
queryEls(this._rule.selector).forEach((el) =>
queryEls(this.rule.selector).forEach((el) =>
this._interseObserver.unobserve(el)
);
@@ -90,14 +112,19 @@ export class Translator {
};
_render = (el) => {
// 含子元素
if (el.querySelector(this.rule.selector)) {
return;
}
// 已翻译
if (el.querySelector(APP_LCNAME)) {
return;
}
// 除openai外保留code和a标签
// 太长或太短
const q = el.innerText.trim();
if (!q || q.length < TRANS_MIN_LENGTH || q.length > TRANS_MAX_LENGTH) {
// 太长或太短不翻译
return;
}
@@ -109,7 +136,7 @@ export class Translator {
const root = createRoot(span);
root.render(
<StoragesProvider>
<Content q={q} rule={this._rule} />
<Content q={q} translator={this} />
</StoragesProvider>
);
};

View File

@@ -1,4 +1,4 @@
import { useMemo, useState } from "react";
import { useMemo, useState, useEffect } from "react";
import LoadingIcon from "./LoadingIcon";
import {
OPT_STYLE_LINE,
@@ -8,12 +8,16 @@ import {
OPT_STYLE_FUZZY,
OPT_STYLE_HIGHTLIGHT,
DEFAULT_COLOR,
EVENT_KISS,
MSG_TRANS_CURRULE,
} from "../../config";
import { useTranslate } from "../../hooks/Translate";
export default function Content({ q, rule }) {
export default function Content({ q, translator }) {
const [rule, setRule] = useState(translator.rule);
const [hover, setHover] = useState(false);
const { text, sameLang, loading, textStyle, bgColor } = useTranslate(q, rule);
const { text, sameLang, loading } = useTranslate(q, rule);
const { textStyle, bgColor } = rule;
const handleMouseEnter = () => {
setHover(true);
@@ -23,6 +27,24 @@ export default function Content({ q, rule }) {
setHover(false);
};
const handleKissEvent = (e) => {
const { action, args } = e.detail;
switch (action) {
case MSG_TRANS_CURRULE:
setRule(args);
break;
default:
// console.log(`[popup] kissEvent action skip: ${action}`);
}
};
useEffect(() => {
window.addEventListener(EVENT_KISS, handleKissEvent);
return () => {
window.removeEventListener(EVENT_KISS, handleKissEvent);
};
}, []);
const style = useMemo(() => {
const lineColor = bgColor || "";
switch (textStyle) {