optimize debounce form & sync data
This commit is contained in:
@@ -20,7 +20,7 @@ import { fetchData, fetchPool } from "./libs/fetch";
|
|||||||
* 插件安装
|
* 插件安装
|
||||||
*/
|
*/
|
||||||
browser.runtime.onInstalled.addListener(() => {
|
browser.runtime.onInstalled.addListener(() => {
|
||||||
console.log("onInstalled");
|
console.log("KISS Translator onInstalled");
|
||||||
storage.trySetObj(STOKEY_SETTING, DEFAULT_SETTING);
|
storage.trySetObj(STOKEY_SETTING, DEFAULT_SETTING);
|
||||||
storage.trySetObj(STOKEY_RULES, DEFAULT_RULES);
|
storage.trySetObj(STOKEY_RULES, DEFAULT_RULES);
|
||||||
storage.trySetObj(STOKEY_SYNC, DEFAULT_SYNC);
|
storage.trySetObj(STOKEY_SYNC, DEFAULT_SYNC);
|
||||||
@@ -30,7 +30,7 @@ browser.runtime.onInstalled.addListener(() => {
|
|||||||
* 浏览器启动
|
* 浏览器启动
|
||||||
*/
|
*/
|
||||||
browser.runtime.onStartup.addListener(async () => {
|
browser.runtime.onStartup.addListener(async () => {
|
||||||
console.log("onStartup");
|
console.log("browser onStartup");
|
||||||
|
|
||||||
// 同步数据
|
// 同步数据
|
||||||
await syncAll();
|
await syncAll();
|
||||||
|
|||||||
@@ -25,11 +25,7 @@ export function useRules() {
|
|||||||
const updateAt = sync.opt?.rulesUpdateAt ? Date.now() : 0;
|
const updateAt = sync.opt?.rulesUpdateAt ? Date.now() : 0;
|
||||||
await storage.setObj(STOKEY_RULES, rules);
|
await storage.setObj(STOKEY_RULES, rules);
|
||||||
await sync.update({ rulesUpdateAt: updateAt });
|
await sync.update({ rulesUpdateAt: updateAt });
|
||||||
try {
|
syncRules();
|
||||||
await syncRules();
|
|
||||||
} catch (err) {
|
|
||||||
console.log("[sync rules]", err);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const add = async (rule) => {
|
const add = async (rule) => {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { STOKEY_SETTING } from "../config";
|
|||||||
import storage from "../libs/storage";
|
import storage from "../libs/storage";
|
||||||
import { useStorages } from "./Storage";
|
import { useStorages } from "./Storage";
|
||||||
import { useSync } from "./Sync";
|
import { useSync } from "./Sync";
|
||||||
|
import { syncSetting } from "../libs/sync";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置hook
|
* 设置hook
|
||||||
@@ -22,5 +23,6 @@ export function useSettingUpdate() {
|
|||||||
const updateAt = sync.opt?.settingUpdateAt ? Date.now() : 0;
|
const updateAt = sync.opt?.settingUpdateAt ? Date.now() : 0;
|
||||||
await storage.putObj(STOKEY_SETTING, obj);
|
await storage.putObj(STOKEY_SETTING, obj);
|
||||||
await sync.update({ settingUpdateAt: updateAt });
|
await sync.update({ settingUpdateAt: updateAt });
|
||||||
|
syncSetting();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,62 +13,66 @@ import { apiSyncData } from "../apis";
|
|||||||
const loadOpt = async () => (await storage.getObj(STOKEY_SYNC)) || DEFAULT_SYNC;
|
const loadOpt = async () => (await storage.getObj(STOKEY_SYNC)) || DEFAULT_SYNC;
|
||||||
|
|
||||||
export const syncSetting = async () => {
|
export const syncSetting = async () => {
|
||||||
const { syncUrl, syncKey, settingUpdateAt } = await loadOpt();
|
try {
|
||||||
if (!syncUrl || !syncKey) {
|
const { syncUrl, syncKey, settingUpdateAt } = await loadOpt();
|
||||||
return;
|
if (!syncUrl || !syncKey) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const setting = await getSetting();
|
const setting = await getSetting();
|
||||||
const res = await apiSyncData(syncUrl, syncKey, {
|
const res = await apiSyncData(syncUrl, syncKey, {
|
||||||
key: KV_SETTING_KEY,
|
key: KV_SETTING_KEY,
|
||||||
value: setting,
|
value: setting,
|
||||||
updateAt: settingUpdateAt,
|
updateAt: settingUpdateAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res && res.updateAt > settingUpdateAt) {
|
if (res && res.updateAt > settingUpdateAt) {
|
||||||
await storage.putObj(STOKEY_SYNC, {
|
await storage.putObj(STOKEY_SYNC, {
|
||||||
settingUpdateAt: res.updateAt,
|
settingUpdateAt: res.updateAt,
|
||||||
settingSyncAt: res.updateAt,
|
settingSyncAt: res.updateAt,
|
||||||
});
|
});
|
||||||
await storage.setObj(STOKEY_SETTING, res.value);
|
await storage.setObj(STOKEY_SETTING, res.value);
|
||||||
} else {
|
} else {
|
||||||
await storage.putObj(STOKEY_SYNC, {
|
await storage.putObj(STOKEY_SYNC, {
|
||||||
settingSyncAt: res.updateAt,
|
settingSyncAt: res.updateAt,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("[sync setting]", err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const syncRules = async () => {
|
export const syncRules = async () => {
|
||||||
const { syncUrl, syncKey, rulesUpdateAt } = await loadOpt();
|
try {
|
||||||
if (!syncUrl || !syncKey) {
|
const { syncUrl, syncKey, rulesUpdateAt } = await loadOpt();
|
||||||
return;
|
if (!syncUrl || !syncKey) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const rules = await getRules();
|
const rules = await getRules();
|
||||||
const res = await apiSyncData(syncUrl, syncKey, {
|
const res = await apiSyncData(syncUrl, syncKey, {
|
||||||
key: KV_RULES_KEY,
|
key: KV_RULES_KEY,
|
||||||
value: rules,
|
value: rules,
|
||||||
updateAt: rulesUpdateAt,
|
updateAt: rulesUpdateAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res && res.updateAt > rulesUpdateAt) {
|
if (res && res.updateAt > rulesUpdateAt) {
|
||||||
await storage.putObj(STOKEY_SYNC, {
|
await storage.putObj(STOKEY_SYNC, {
|
||||||
rulesUpdateAt: res.updateAt,
|
rulesUpdateAt: res.updateAt,
|
||||||
rulesSyncAt: res.updateAt,
|
rulesSyncAt: res.updateAt,
|
||||||
});
|
});
|
||||||
await storage.setObj(STOKEY_RULES, res.value);
|
await storage.setObj(STOKEY_RULES, res.value);
|
||||||
} else {
|
} else {
|
||||||
await storage.putObj(STOKEY_SYNC, {
|
await storage.putObj(STOKEY_SYNC, {
|
||||||
rulesSyncAt: res.updateAt,
|
rulesSyncAt: res.updateAt,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("[sync rules]", err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const syncAll = async () => {
|
export const syncAll = async () => {
|
||||||
try {
|
await syncSetting();
|
||||||
await syncSetting();
|
await syncRules();
|
||||||
await syncRules();
|
|
||||||
} catch (err) {
|
|
||||||
console.log("[sync all]", err);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ const getEdgePosition = (
|
|||||||
edge = "top";
|
edge = "top";
|
||||||
top = 0;
|
top = 0;
|
||||||
}
|
}
|
||||||
|
left = limitNumber(left, 0, windowWidth - width);
|
||||||
|
top = limitNumber(top, 0, windowHeight - height);
|
||||||
return { x: left, y: top, edge, hide: false };
|
return { x: left, y: top, edge, hide: false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import Box from "@mui/material/Box";
|
|||||||
import Navigator from "./Navigator";
|
import Navigator from "./Navigator";
|
||||||
import Header from "./Header";
|
import Header from "./Header";
|
||||||
import { useTheme } from "@mui/material/styles";
|
import { useTheme } from "@mui/material/styles";
|
||||||
import { syncAll } from "../../libs/sync";
|
|
||||||
|
|
||||||
export default function Layout() {
|
export default function Layout() {
|
||||||
const navWidth = 256;
|
const navWidth = 256;
|
||||||
@@ -21,7 +20,6 @@ export default function Layout() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
syncAll();
|
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ function RuleFields({ rule, rules, setShow }) {
|
|||||||
disabled={rule?.pattern === "*" || disabled}
|
disabled={rule?.pattern === "*" || disabled}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
onFocus={handleFocus}
|
onFocus={handleFocus}
|
||||||
|
multiline
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
@@ -134,8 +135,6 @@ function RuleFields({ rule, rules, setShow }) {
|
|||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
onFocus={handleFocus}
|
onFocus={handleFocus}
|
||||||
multiline
|
multiline
|
||||||
minRows={2}
|
|
||||||
maxRows={10}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
@@ -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 (
|
||||||
|
<Accordion expanded={expanded} onChange={handleChange}>
|
||||||
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
|
<Typography>{rule.pattern}</Typography>
|
||||||
|
</AccordionSummary>
|
||||||
|
<AccordionDetails>
|
||||||
|
{expanded && <RuleFields rule={rule} rules={rules} />}
|
||||||
|
</AccordionDetails>
|
||||||
|
</Accordion>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function DownloadButton({ data, text, fileName }) {
|
function DownloadButton({ data, text, fileName }) {
|
||||||
const handleClick = (e) => {
|
const handleClick = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -405,14 +423,7 @@ export default function Rules() {
|
|||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
{rules.list.map((rule) => (
|
{rules.list.map((rule) => (
|
||||||
<Accordion key={rule.pattern}>
|
<RuleAccordion key={rule.pattern} rule={rule} rules={rules} />
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
|
||||||
<Typography>{rule.pattern}</Typography>
|
|
||||||
</AccordionSummary>
|
|
||||||
<AccordionDetails>
|
|
||||||
<RuleFields rule={rule} rules={rules} />
|
|
||||||
</AccordionDetails>
|
|
||||||
</Accordion>
|
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -6,15 +6,37 @@ import MenuItem from "@mui/material/MenuItem";
|
|||||||
import FormControl from "@mui/material/FormControl";
|
import FormControl from "@mui/material/FormControl";
|
||||||
import Select from "@mui/material/Select";
|
import Select from "@mui/material/Select";
|
||||||
import { useSetting, useSettingUpdate } from "../../hooks/Setting";
|
import { useSetting, useSettingUpdate } from "../../hooks/Setting";
|
||||||
import { limitNumber } from "../../libs/utils";
|
import { limitNumber, debounce } from "../../libs/utils";
|
||||||
import { useI18n } from "../../hooks/I18n";
|
import { useI18n } from "../../hooks/I18n";
|
||||||
import { UI_LANGS } from "../../config";
|
import { UI_LANGS } from "../../config";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const setting = useSetting();
|
const setting = useSetting();
|
||||||
const updateSetting = useSettingUpdate();
|
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) {
|
if (!setting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -37,13 +59,10 @@ export default function Settings() {
|
|||||||
<FormControl size="small">
|
<FormControl size="small">
|
||||||
<InputLabel>{i18n("ui_lang")}</InputLabel>
|
<InputLabel>{i18n("ui_lang")}</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
|
name="uiLang"
|
||||||
value={uiLang}
|
value={uiLang}
|
||||||
label={i18n("ui_lang")}
|
label={i18n("ui_lang")}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
uiLang: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{UI_LANGS.map(([lang, name]) => (
|
{UI_LANGS.map(([lang, name]) => (
|
||||||
<MenuItem key={lang} value={lang}>
|
<MenuItem key={lang} value={lang}>
|
||||||
@@ -57,36 +76,27 @@ export default function Settings() {
|
|||||||
size="small"
|
size="small"
|
||||||
label={i18n("fetch_limit")}
|
label={i18n("fetch_limit")}
|
||||||
type="number"
|
type="number"
|
||||||
|
name="fetchLimit"
|
||||||
defaultValue={fetchLimit}
|
defaultValue={fetchLimit}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
fetchLimit: limitNumber(e.target.value, 1, 100),
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label={i18n("fetch_interval")}
|
label={i18n("fetch_interval")}
|
||||||
type="number"
|
type="number"
|
||||||
|
name="fetchInterval"
|
||||||
defaultValue={fetchInterval}
|
defaultValue={fetchInterval}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
fetchInterval: limitNumber(e.target.value, 0, 5000),
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormControl size="small">
|
<FormControl size="small">
|
||||||
<InputLabel>{i18n("clear_cache")}</InputLabel>
|
<InputLabel>{i18n("clear_cache")}</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
|
name="clearCache"
|
||||||
value={clearCache}
|
value={clearCache}
|
||||||
label={i18n("clear_cache")}
|
label={i18n("clear_cache")}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
clearCache: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<MenuItem value={false}>{i18n("clear_cache_never")}</MenuItem>
|
<MenuItem value={false}>{i18n("clear_cache_never")}</MenuItem>
|
||||||
<MenuItem value={true}>{i18n("clear_cache_restart")}</MenuItem>
|
<MenuItem value={true}>{i18n("clear_cache_restart")}</MenuItem>
|
||||||
@@ -96,60 +106,43 @@ export default function Settings() {
|
|||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label={i18n("google_api")}
|
label={i18n("google_api")}
|
||||||
|
name="googleUrl"
|
||||||
defaultValue={googleUrl}
|
defaultValue={googleUrl}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
googleUrl: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label={i18n("openai_api")}
|
label={i18n("openai_api")}
|
||||||
|
name="openaiUrl"
|
||||||
defaultValue={openaiUrl}
|
defaultValue={openaiUrl}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
openaiUrl: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
type="password"
|
type="password"
|
||||||
label={i18n("openai_key")}
|
label={i18n("openai_key")}
|
||||||
|
name="openaiKey"
|
||||||
defaultValue={openaiKey}
|
defaultValue={openaiKey}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
openaiKey: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label={i18n("openai_model")}
|
label={i18n("openai_model")}
|
||||||
|
name="openaiModel"
|
||||||
defaultValue={openaiModel}
|
defaultValue={openaiModel}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
openaiModel: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label={i18n("openai_prompt")}
|
label={i18n("openai_prompt")}
|
||||||
|
name="openaiPrompt"
|
||||||
defaultValue={openaiPrompt}
|
defaultValue={openaiPrompt}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
updateSetting({
|
|
||||||
openaiPrompt: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
multiline
|
multiline
|
||||||
minRows={2}
|
|
||||||
maxRows={10}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -3,23 +3,33 @@ import Stack from "@mui/material/Stack";
|
|||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import { useI18n } from "../../hooks/I18n";
|
import { useI18n } from "../../hooks/I18n";
|
||||||
import { useSync } from "../../hooks/Sync";
|
import { useSync } from "../../hooks/Sync";
|
||||||
import { syncAll } from "../../libs/sync";
|
|
||||||
import Alert from "@mui/material/Alert";
|
import Alert from "@mui/material/Alert";
|
||||||
import Link from "@mui/material/Link";
|
import Link from "@mui/material/Link";
|
||||||
import { URL_KISS_WORKER } from "../../config";
|
import { URL_KISS_WORKER } from "../../config";
|
||||||
|
import { debounce } from "../../libs/utils";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
|
||||||
export default function SyncSetting() {
|
export default function SyncSetting() {
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const sync = useSync();
|
const sync = useSync();
|
||||||
|
|
||||||
|
const handleChange = useMemo(
|
||||||
|
() =>
|
||||||
|
debounce((e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const { name, value } = e.target;
|
||||||
|
sync.update({
|
||||||
|
[name]: value,
|
||||||
|
});
|
||||||
|
}, 500),
|
||||||
|
[sync]
|
||||||
|
);
|
||||||
|
|
||||||
if (!sync.opt) {
|
if (!sync.opt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { syncUrl, syncKey } = sync.opt;
|
const { syncUrl, syncKey } = sync.opt;
|
||||||
const handleSyncBlur = () => {
|
|
||||||
syncAll();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
@@ -29,13 +39,9 @@ export default function SyncSetting() {
|
|||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label={i18n("data_sync_url")}
|
label={i18n("data_sync_url")}
|
||||||
|
name="syncUrl"
|
||||||
defaultValue={syncUrl}
|
defaultValue={syncUrl}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
sync.update({
|
|
||||||
syncUrl: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
onBlur={handleSyncBlur}
|
|
||||||
helperText={
|
helperText={
|
||||||
<Link href={URL_KISS_WORKER}>{i18n("about_sync_api")}</Link>
|
<Link href={URL_KISS_WORKER}>{i18n("about_sync_api")}</Link>
|
||||||
}
|
}
|
||||||
@@ -45,13 +51,9 @@ export default function SyncSetting() {
|
|||||||
size="small"
|
size="small"
|
||||||
type="password"
|
type="password"
|
||||||
label={i18n("data_sync_key")}
|
label={i18n("data_sync_key")}
|
||||||
|
name="syncKey"
|
||||||
defaultValue={syncKey}
|
defaultValue={syncKey}
|
||||||
onChange={(e) => {
|
onChange={handleChange}
|
||||||
sync.update({
|
|
||||||
syncKey: e.target.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
onBlur={handleSyncBlur}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -10,31 +10,34 @@ import { useEffect, useState } from "react";
|
|||||||
import { isGm } from "../../libs/browser";
|
import { isGm } from "../../libs/browser";
|
||||||
import { sleep } from "../../libs/utils";
|
import { sleep } from "../../libs/utils";
|
||||||
import CircularProgress from "@mui/material/CircularProgress";
|
import CircularProgress from "@mui/material/CircularProgress";
|
||||||
|
import { syncAll } from "../../libs/sync";
|
||||||
|
|
||||||
export default function Options() {
|
export default function Options() {
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
const [ready, setReady] = useState(false);
|
const [ready, setReady] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isGm) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
let i = 0;
|
if (isGm) {
|
||||||
for (;;) {
|
// 等待GM注入
|
||||||
if (window.APP_NAME === process.env.REACT_APP_NAME) {
|
let i = 0;
|
||||||
setReady(true);
|
for (;;) {
|
||||||
break;
|
if (window.APP_NAME === process.env.REACT_APP_NAME) {
|
||||||
}
|
setReady(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (++i > 8) {
|
if (++i > 8) {
|
||||||
setError(true);
|
setError(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 同步数据
|
||||||
|
syncAll();
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user