diff --git a/src/background.js b/src/background.js
index 4812cda..e5d371e 100644
--- a/src/background.js
+++ b/src/background.js
@@ -20,7 +20,7 @@ import { fetchData, fetchPool } from "./libs/fetch";
* 插件安装
*/
browser.runtime.onInstalled.addListener(() => {
- console.log("onInstalled");
+ console.log("KISS Translator onInstalled");
storage.trySetObj(STOKEY_SETTING, DEFAULT_SETTING);
storage.trySetObj(STOKEY_RULES, DEFAULT_RULES);
storage.trySetObj(STOKEY_SYNC, DEFAULT_SYNC);
@@ -30,7 +30,7 @@ browser.runtime.onInstalled.addListener(() => {
* 浏览器启动
*/
browser.runtime.onStartup.addListener(async () => {
- console.log("onStartup");
+ console.log("browser onStartup");
// 同步数据
await syncAll();
diff --git a/src/hooks/Rules.js b/src/hooks/Rules.js
index e1ad5a9..72f571c 100644
--- a/src/hooks/Rules.js
+++ b/src/hooks/Rules.js
@@ -25,11 +25,7 @@ export function useRules() {
const updateAt = sync.opt?.rulesUpdateAt ? Date.now() : 0;
await storage.setObj(STOKEY_RULES, rules);
await sync.update({ rulesUpdateAt: updateAt });
- try {
- await syncRules();
- } catch (err) {
- console.log("[sync rules]", err);
- }
+ syncRules();
};
const add = async (rule) => {
diff --git a/src/hooks/Setting.js b/src/hooks/Setting.js
index a5cc8d7..ad19a9c 100644
--- a/src/hooks/Setting.js
+++ b/src/hooks/Setting.js
@@ -2,6 +2,7 @@ import { STOKEY_SETTING } from "../config";
import storage from "../libs/storage";
import { useStorages } from "./Storage";
import { useSync } from "./Sync";
+import { syncSetting } from "../libs/sync";
/**
* 设置hook
@@ -22,5 +23,6 @@ export function useSettingUpdate() {
const updateAt = sync.opt?.settingUpdateAt ? Date.now() : 0;
await storage.putObj(STOKEY_SETTING, obj);
await sync.update({ settingUpdateAt: updateAt });
+ syncSetting();
};
}
diff --git a/src/libs/sync.js b/src/libs/sync.js
index 38d590e..4c7a848 100644
--- a/src/libs/sync.js
+++ b/src/libs/sync.js
@@ -13,62 +13,66 @@ import { apiSyncData } from "../apis";
const loadOpt = async () => (await storage.getObj(STOKEY_SYNC)) || DEFAULT_SYNC;
export const syncSetting = async () => {
- const { syncUrl, syncKey, settingUpdateAt } = await loadOpt();
- if (!syncUrl || !syncKey) {
- return;
- }
+ try {
+ const { syncUrl, syncKey, settingUpdateAt } = await loadOpt();
+ if (!syncUrl || !syncKey) {
+ return;
+ }
- const setting = await getSetting();
- const res = await apiSyncData(syncUrl, syncKey, {
- key: KV_SETTING_KEY,
- value: setting,
- updateAt: settingUpdateAt,
- });
+ const setting = await getSetting();
+ const res = await apiSyncData(syncUrl, syncKey, {
+ key: KV_SETTING_KEY,
+ value: setting,
+ updateAt: settingUpdateAt,
+ });
- if (res && res.updateAt > settingUpdateAt) {
- await storage.putObj(STOKEY_SYNC, {
- settingUpdateAt: res.updateAt,
- settingSyncAt: res.updateAt,
- });
- await storage.setObj(STOKEY_SETTING, res.value);
- } else {
- await storage.putObj(STOKEY_SYNC, {
- settingSyncAt: res.updateAt,
- });
+ if (res && res.updateAt > settingUpdateAt) {
+ await storage.putObj(STOKEY_SYNC, {
+ settingUpdateAt: res.updateAt,
+ settingSyncAt: res.updateAt,
+ });
+ await storage.setObj(STOKEY_SETTING, res.value);
+ } else {
+ await storage.putObj(STOKEY_SYNC, {
+ settingSyncAt: res.updateAt,
+ });
+ }
+ } catch (err) {
+ console.log("[sync setting]", err);
}
};
export const syncRules = async () => {
- const { syncUrl, syncKey, rulesUpdateAt } = await loadOpt();
- if (!syncUrl || !syncKey) {
- return;
- }
+ try {
+ const { syncUrl, syncKey, rulesUpdateAt } = await loadOpt();
+ if (!syncUrl || !syncKey) {
+ return;
+ }
- const rules = await getRules();
- const res = await apiSyncData(syncUrl, syncKey, {
- key: KV_RULES_KEY,
- value: rules,
- updateAt: rulesUpdateAt,
- });
+ const rules = await getRules();
+ const res = await apiSyncData(syncUrl, syncKey, {
+ key: KV_RULES_KEY,
+ value: rules,
+ updateAt: rulesUpdateAt,
+ });
- if (res && res.updateAt > rulesUpdateAt) {
- await storage.putObj(STOKEY_SYNC, {
- rulesUpdateAt: res.updateAt,
- rulesSyncAt: res.updateAt,
- });
- await storage.setObj(STOKEY_RULES, res.value);
- } else {
- await storage.putObj(STOKEY_SYNC, {
- rulesSyncAt: res.updateAt,
- });
+ if (res && res.updateAt > rulesUpdateAt) {
+ await storage.putObj(STOKEY_SYNC, {
+ rulesUpdateAt: res.updateAt,
+ rulesSyncAt: res.updateAt,
+ });
+ await storage.setObj(STOKEY_RULES, res.value);
+ } else {
+ await storage.putObj(STOKEY_SYNC, {
+ rulesSyncAt: res.updateAt,
+ });
+ }
+ } catch (err) {
+ console.log("[sync rules]", err);
}
};
export const syncAll = async () => {
- try {
- await syncSetting();
- await syncRules();
- } catch (err) {
- console.log("[sync all]", err);
- }
+ await syncSetting();
+ await syncRules();
};
diff --git a/src/views/Action/Draggable.js b/src/views/Action/Draggable.js
index bc3c494..b70bd18 100644
--- a/src/views/Action/Draggable.js
+++ b/src/views/Action/Draggable.js
@@ -30,6 +30,8 @@ const getEdgePosition = (
edge = "top";
top = 0;
}
+ left = limitNumber(left, 0, windowWidth - width);
+ top = limitNumber(top, 0, windowHeight - height);
return { x: left, y: top, edge, hide: false };
};
diff --git a/src/views/Options/Layout.js b/src/views/Options/Layout.js
index 8a98419..b811f47 100644
--- a/src/views/Options/Layout.js
+++ b/src/views/Options/Layout.js
@@ -6,7 +6,6 @@ import Box from "@mui/material/Box";
import Navigator from "./Navigator";
import Header from "./Header";
import { useTheme } from "@mui/material/styles";
-import { syncAll } from "../../libs/sync";
export default function Layout() {
const navWidth = 256;
@@ -21,7 +20,6 @@ export default function Layout() {
useEffect(() => {
setOpen(false);
- syncAll();
}, [location]);
return (
diff --git a/src/views/Options/Rules.js b/src/views/Options/Rules.js
index ac1630a..6e18d24 100644
--- a/src/views/Options/Rules.js
+++ b/src/views/Options/Rules.js
@@ -122,6 +122,7 @@ function RuleFields({ rule, rules, setShow }) {
disabled={rule?.pattern === "*" || disabled}
onChange={handleChange}
onFocus={handleFocus}
+ multiline
/>
@@ -301,6 +300,25 @@ function RuleFields({ rule, rules, setShow }) {
);
}
+function RuleAccordion({ rule, rules }) {
+ const [expanded, setExpanded] = useState(false);
+
+ const handleChange = (e) => {
+ setExpanded((pre) => !pre);
+ };
+
+ return (
+
+ }>
+ {rule.pattern}
+
+
+ {expanded && }
+
+
+ );
+}
+
function DownloadButton({ data, text, fileName }) {
const handleClick = (e) => {
e.preventDefault();
@@ -405,14 +423,7 @@ export default function Rules() {
{rules.list.map((rule) => (
-
- }>
- {rule.pattern}
-
-
-
-
-
+
))}
diff --git a/src/views/Options/Setting.js b/src/views/Options/Setting.js
index c84d201..ff4180e 100644
--- a/src/views/Options/Setting.js
+++ b/src/views/Options/Setting.js
@@ -6,15 +6,37 @@ import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
import { useSetting, useSettingUpdate } from "../../hooks/Setting";
-import { limitNumber } from "../../libs/utils";
+import { limitNumber, debounce } from "../../libs/utils";
import { useI18n } from "../../hooks/I18n";
import { UI_LANGS } from "../../config";
+import { useMemo } from "react";
export default function Settings() {
const i18n = useI18n();
const setting = useSetting();
const updateSetting = useSettingUpdate();
+ const handleChange = useMemo(
+ () =>
+ debounce((e) => {
+ e.preventDefault();
+ let { name, value } = e.target;
+ switch (name) {
+ case "fetchLimit":
+ value = limitNumber(value, 1, 100);
+ break;
+ case "fetchInterval":
+ value = limitNumber(value, 0, 5000);
+ break;
+ default:
+ }
+ updateSetting({
+ [name]: value,
+ });
+ }, 500),
+ [updateSetting]
+ );
+
if (!setting) {
return;
}
@@ -37,13 +59,10 @@ export default function Settings() {
{i18n("ui_lang")}
diff --git a/src/views/Options/SyncSetting.js b/src/views/Options/SyncSetting.js
index 9805a89..cbe7330 100644
--- a/src/views/Options/SyncSetting.js
+++ b/src/views/Options/SyncSetting.js
@@ -3,23 +3,33 @@ import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField";
import { useI18n } from "../../hooks/I18n";
import { useSync } from "../../hooks/Sync";
-import { syncAll } from "../../libs/sync";
import Alert from "@mui/material/Alert";
import Link from "@mui/material/Link";
import { URL_KISS_WORKER } from "../../config";
+import { debounce } from "../../libs/utils";
+import { useMemo } from "react";
export default function SyncSetting() {
const i18n = useI18n();
const sync = useSync();
+ const handleChange = useMemo(
+ () =>
+ debounce((e) => {
+ e.preventDefault();
+ const { name, value } = e.target;
+ sync.update({
+ [name]: value,
+ });
+ }, 500),
+ [sync]
+ );
+
if (!sync.opt) {
return;
}
const { syncUrl, syncKey } = sync.opt;
- const handleSyncBlur = () => {
- syncAll();
- };
return (
@@ -29,13 +39,9 @@ export default function SyncSetting() {
{
- sync.update({
- syncUrl: e.target.value,
- });
- }}
- onBlur={handleSyncBlur}
+ onChange={handleChange}
helperText={
{i18n("about_sync_api")}
}
@@ -45,13 +51,9 @@ export default function SyncSetting() {
size="small"
type="password"
label={i18n("data_sync_key")}
+ name="syncKey"
defaultValue={syncKey}
- onChange={(e) => {
- sync.update({
- syncKey: e.target.value,
- });
- }}
- onBlur={handleSyncBlur}
+ onChange={handleChange}
/>
diff --git a/src/views/Options/index.js b/src/views/Options/index.js
index cebd928..32064d5 100644
--- a/src/views/Options/index.js
+++ b/src/views/Options/index.js
@@ -10,31 +10,34 @@ import { useEffect, useState } from "react";
import { isGm } from "../../libs/browser";
import { sleep } from "../../libs/utils";
import CircularProgress from "@mui/material/CircularProgress";
+import { syncAll } from "../../libs/sync";
export default function Options() {
const [error, setError] = useState(false);
const [ready, setReady] = useState(false);
useEffect(() => {
- if (!isGm) {
- return;
- }
-
(async () => {
- let i = 0;
- for (;;) {
- if (window.APP_NAME === process.env.REACT_APP_NAME) {
- setReady(true);
- break;
- }
+ if (isGm) {
+ // 等待GM注入
+ let i = 0;
+ for (;;) {
+ if (window.APP_NAME === process.env.REACT_APP_NAME) {
+ setReady(true);
+ break;
+ }
- if (++i > 8) {
- setError(true);
- break;
- }
+ if (++i > 8) {
+ setError(true);
+ break;
+ }
- await sleep(1000);
+ await sleep(1000);
+ }
}
+
+ // 同步数据
+ syncAll();
})();
}, []);