sync subscribe rules when browser start or userscript run
This commit is contained in:
1
.env
1
.env
@@ -8,5 +8,6 @@ REACT_APP_OPTIONSPAGE=https://kiss-translator.rayjar.com/options
|
|||||||
REACT_APP_OPTIONSPAGE2=https://fishjar.github.io/kiss-translator/options.html
|
REACT_APP_OPTIONSPAGE2=https://fishjar.github.io/kiss-translator/options.html
|
||||||
REACT_APP_OPTIONSPAGE_DEV=http://localhost:3000/options.html
|
REACT_APP_OPTIONSPAGE_DEV=http://localhost:3000/options.html
|
||||||
REACT_APP_LOGOURL=https://kiss-translator.rayjar.com/images/logo192.png
|
REACT_APP_LOGOURL=https://kiss-translator.rayjar.com/images/logo192.png
|
||||||
|
REACT_APP_RULESURL=https://kiss-translator.rayjar.com/kiss-translator-rules.json
|
||||||
REACT_APP_USERSCRIPT_DOWNLOADURL=https://kiss-translator.rayjar.com/kiss-translator.user.js
|
REACT_APP_USERSCRIPT_DOWNLOADURL=https://kiss-translator.rayjar.com/kiss-translator.user.js
|
||||||
REACT_APP_USERSCRIPT_DOWNLOADURL2=https://fishjar.github.io/kiss-translator/kiss-translator.user.js
|
REACT_APP_USERSCRIPT_DOWNLOADURL2=https://fishjar.github.io/kiss-translator/kiss-translator.user.js
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { sha256 } from "../libs/utils";
|
|||||||
* @param {*} data
|
* @param {*} data
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const apiSyncData = async (url, key, data) =>
|
export const apiSyncData = async (url, key, data, isBg = false) =>
|
||||||
fetchPolyfill(url, {
|
fetchPolyfill(url, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
@@ -28,6 +28,7 @@ export const apiSyncData = async (url, key, data) =>
|
|||||||
},
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
isBg,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,15 +50,14 @@ const apiGoogleTranslate = async (translator, text, to, from) => {
|
|||||||
};
|
};
|
||||||
const { googleUrl } = await getSetting();
|
const { googleUrl } = await getSetting();
|
||||||
const input = `${googleUrl}?${queryString.stringify(params)}`;
|
const input = `${googleUrl}?${queryString.stringify(params)}`;
|
||||||
return fetchPolyfill(
|
return fetchPolyfill(input, {
|
||||||
input,
|
headers: {
|
||||||
{
|
"Content-type": "application/json",
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{ useCache: true, usePool: true, translator }
|
useCache: true,
|
||||||
);
|
usePool: true,
|
||||||
|
translator,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,17 +74,16 @@ const apiMicrosoftTranslate = (translator, text, to, from) => {
|
|||||||
"api-version": "3.0",
|
"api-version": "3.0",
|
||||||
};
|
};
|
||||||
const input = `${URL_MICROSOFT_TRANS}?${queryString.stringify(params)}`;
|
const input = `${URL_MICROSOFT_TRANS}?${queryString.stringify(params)}`;
|
||||||
return fetchPolyfill(
|
return fetchPolyfill(input, {
|
||||||
input,
|
headers: {
|
||||||
{
|
"Content-type": "application/json",
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json",
|
|
||||||
},
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify([{ Text: text }]),
|
|
||||||
},
|
},
|
||||||
{ useCache: true, usePool: true, translator }
|
method: "POST",
|
||||||
);
|
body: JSON.stringify([{ Text: text }]),
|
||||||
|
useCache: true,
|
||||||
|
usePool: true,
|
||||||
|
translator,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,31 +99,31 @@ const apiOpenaiTranslate = async (translator, text, to, from) => {
|
|||||||
let prompt = openaiPrompt
|
let prompt = openaiPrompt
|
||||||
.replaceAll(PROMPT_PLACE_FROM, from)
|
.replaceAll(PROMPT_PLACE_FROM, from)
|
||||||
.replaceAll(PROMPT_PLACE_TO, to);
|
.replaceAll(PROMPT_PLACE_TO, to);
|
||||||
return fetchPolyfill(
|
return fetchPolyfill(openaiUrl, {
|
||||||
openaiUrl,
|
headers: {
|
||||||
{
|
"Content-type": "application/json",
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json",
|
|
||||||
},
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
model: openaiModel,
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
role: "system",
|
|
||||||
content: prompt,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "user",
|
|
||||||
content: text,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
temperature: 0,
|
|
||||||
max_tokens: 256,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{ useCache: true, usePool: true, translator, token: openaiKey }
|
method: "POST",
|
||||||
);
|
body: JSON.stringify({
|
||||||
|
model: openaiModel,
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: "system",
|
||||||
|
content: prompt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: text,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
temperature: 0,
|
||||||
|
max_tokens: 256,
|
||||||
|
}),
|
||||||
|
useCache: true,
|
||||||
|
usePool: true,
|
||||||
|
translator,
|
||||||
|
token: openaiKey,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,12 +14,15 @@ import {
|
|||||||
STOKEY_RULES,
|
STOKEY_RULES,
|
||||||
STOKEY_SYNC,
|
STOKEY_SYNC,
|
||||||
CACHE_NAME,
|
CACHE_NAME,
|
||||||
|
STOKEY_RULESCACHE_PREFIX,
|
||||||
|
BUILTIN_RULES,
|
||||||
} from "./config";
|
} from "./config";
|
||||||
import storage from "./libs/storage";
|
import storage from "./libs/storage";
|
||||||
import { getSetting } from "./libs";
|
import { getSetting } from "./libs";
|
||||||
import { syncAll } from "./libs/sync";
|
import { syncAll } from "./libs/sync";
|
||||||
import { fetchData, fetchPool } from "./libs/fetch";
|
import { fetchData, fetchPool } from "./libs/fetch";
|
||||||
import { sendTabMsg } from "./libs/msg";
|
import { sendTabMsg } from "./libs/msg";
|
||||||
|
import { trySyncAllSubRules } from "./libs/rules";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件安装
|
* 插件安装
|
||||||
@@ -29,7 +32,10 @@ browser.runtime.onInstalled.addListener(() => {
|
|||||||
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);
|
||||||
// todo:缓存内置rules
|
storage.trySetObj(
|
||||||
|
`${STOKEY_RULESCACHE_PREFIX}${process.env.REACT_APP_RULESURL}`,
|
||||||
|
BUILTIN_RULES
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,13 +45,16 @@ browser.runtime.onStartup.addListener(async () => {
|
|||||||
console.log("browser onStartup");
|
console.log("browser onStartup");
|
||||||
|
|
||||||
// 同步数据
|
// 同步数据
|
||||||
await syncAll();
|
await syncAll(true);
|
||||||
|
|
||||||
// 清除缓存
|
// 清除缓存
|
||||||
const { clearCache } = await getSetting();
|
const setting = await getSetting();
|
||||||
if (clearCache) {
|
if (setting.clearCache) {
|
||||||
caches.delete(CACHE_NAME);
|
caches.delete(CACHE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 同步订阅规则
|
||||||
|
trySyncAllSubRules(setting, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,8 +64,8 @@ browser.runtime.onMessage.addListener(
|
|||||||
({ action, args }, sender, sendResponse) => {
|
({ action, args }, sender, sendResponse) => {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case MSG_FETCH:
|
case MSG_FETCH:
|
||||||
const { input, init, opts } = args;
|
const { input, opts } = args;
|
||||||
fetchData(input, init, opts)
|
fetchData(input, opts)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
sendResponse({ data });
|
sendResponse({ data });
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export const GLOBLA_RULE = {
|
|||||||
// 订阅列表
|
// 订阅列表
|
||||||
export const DEFAULT_SUBRULES_LIST = [
|
export const DEFAULT_SUBRULES_LIST = [
|
||||||
{
|
{
|
||||||
url: "https://kiss-translator.rayjar.com/kiss-translator-rules.json",
|
url: process.env.REACT_APP_RULESURL,
|
||||||
selected: true,
|
selected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -192,4 +192,5 @@ export const DEFAULT_SYNC = {
|
|||||||
settingSyncAt: 0,
|
settingSyncAt: 0,
|
||||||
rulesUpdateAt: 0,
|
rulesUpdateAt: 0,
|
||||||
rulesSyncAt: 0,
|
rulesSyncAt: 0,
|
||||||
|
subRulesSyncAt: 0, // 订阅规则同步时间
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const newCacheReq = async (request) => {
|
|||||||
* @param {*} param0
|
* @param {*} param0
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const fetchApi = async ({ input, init, translator, token }) => {
|
const fetchApi = async ({ input, init = {}, translator, token }) => {
|
||||||
if (translator === OPT_TRANS_MICROSOFT) {
|
if (translator === OPT_TRANS_MICROSOFT) {
|
||||||
init.headers["Authorization"] = `Bearer ${token}`;
|
init.headers["Authorization"] = `Bearer ${token}`;
|
||||||
} else if (translator === OPT_TRANS_OPENAI) {
|
} else if (translator === OPT_TRANS_OPENAI) {
|
||||||
@@ -103,14 +103,12 @@ export const fetchPool = taskPool(
|
|||||||
/**
|
/**
|
||||||
* 请求数据统一接口
|
* 请求数据统一接口
|
||||||
* @param {*} input
|
* @param {*} input
|
||||||
* @param {*} init
|
|
||||||
* @param {*} opts
|
* @param {*} opts
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const fetchData = async (
|
export const fetchData = async (
|
||||||
input,
|
input,
|
||||||
init,
|
{ useCache, usePool, translator, token, ...init } = {}
|
||||||
{ useCache, usePool, translator, token } = {}
|
|
||||||
) => {
|
) => {
|
||||||
const cacheReq = await newCacheReq(new Request(input, init));
|
const cacheReq = await newCacheReq(new Request(input, init));
|
||||||
const cache = await caches.open(CACHE_NAME);
|
const cache = await caches.open(CACHE_NAME);
|
||||||
@@ -157,22 +155,21 @@ export const fetchData = async (
|
|||||||
/**
|
/**
|
||||||
* fetch 兼容性封装
|
* fetch 兼容性封装
|
||||||
* @param {*} input
|
* @param {*} input
|
||||||
* @param {*} init
|
|
||||||
* @param {*} opts
|
* @param {*} opts
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const fetchPolyfill = async (input, init, opts) => {
|
export const fetchPolyfill = async (input, { isBg = false, ...opts } = {}) => {
|
||||||
// 插件
|
// 插件
|
||||||
if (isExt) {
|
if (isExt && !isBg) {
|
||||||
const res = await sendMsg(MSG_FETCH, { input, init, opts });
|
const res = await sendMsg(MSG_FETCH, { input, opts });
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
throw new Error(res.error);
|
throw new Error(res.error);
|
||||||
}
|
}
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 油猴/网页
|
// 油猴/网页/BackgroundPage
|
||||||
return await fetchData(input, init, opts);
|
return await fetchData(input, opts);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
} from "../config";
|
} from "../config";
|
||||||
import { browser } from "./browser";
|
import { browser } from "./browser";
|
||||||
import { isMatch } from "./utils";
|
import { isMatch } from "./utils";
|
||||||
import { tryLoadRules } from "./rules";
|
import { loadSubRules } from "./rules";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取节点列表并转为数组
|
* 获取节点列表并转为数组
|
||||||
@@ -63,7 +63,7 @@ export const matchRule = async (
|
|||||||
try {
|
try {
|
||||||
const selectedSub = subrulesList.find((item) => item.selected);
|
const selectedSub = subrulesList.find((item) => item.selected);
|
||||||
if (selectedSub?.url) {
|
if (selectedSub?.url) {
|
||||||
const subRules = await tryLoadRules(selectedSub.url);
|
const subRules = await loadSubRules(selectedSub.url);
|
||||||
rules.splice(-1, 0, ...subRules);
|
rules.splice(-1, 0, ...subRules);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
OPT_LANGS_FROM,
|
OPT_LANGS_FROM,
|
||||||
OPT_LANGS_TO,
|
OPT_LANGS_TO,
|
||||||
} from "../config";
|
} from "../config";
|
||||||
|
import { syncOpt } from "./sync";
|
||||||
|
|
||||||
const fromLangs = OPT_LANGS_FROM.map((item) => item[0]);
|
const fromLangs = OPT_LANGS_FROM.map((item) => item[0]);
|
||||||
const toLangs = OPT_LANGS_TO.map((item) => item[0]);
|
const toLangs = OPT_LANGS_TO.map((item) => item[0]);
|
||||||
@@ -62,11 +63,11 @@ export const checkRules = (rules) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 本地rules缓存
|
* 订阅规则的本地缓存
|
||||||
*/
|
*/
|
||||||
export const rulesCache = {
|
export const rulesCache = {
|
||||||
fetch: async (url) => {
|
fetch: async (url, isBg = false) => {
|
||||||
const res = await fetchPolyfill(url);
|
const res = await fetchPolyfill(url, { isBg });
|
||||||
const rules = checkRules(res).filter(
|
const rules = checkRules(res).filter(
|
||||||
(rule) => rule.pattern.replaceAll(GLOBAL_KEY, "") !== ""
|
(rule) => rule.pattern.replaceAll(GLOBAL_KEY, "") !== ""
|
||||||
);
|
);
|
||||||
@@ -84,16 +85,61 @@ export const rulesCache = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从缓存或远程加载订阅的rules
|
* 同步订阅规则
|
||||||
* @param {*} url
|
* @param {*} url
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const tryLoadRules = async (url) => {
|
export const syncSubRules = async (url, isBg = false) => {
|
||||||
let rules = await rulesCache.get(url);
|
const rules = await rulesCache.fetch(url, isBg);
|
||||||
|
if (rules.length > 0) {
|
||||||
|
await rulesCache.set(url, rules);
|
||||||
|
}
|
||||||
|
return rules;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步所有订阅规则
|
||||||
|
* @param {*} url
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const syncAllSubRules = async (subrulesList, isBg = false) => {
|
||||||
|
for (let subrules of subrulesList) {
|
||||||
|
try {
|
||||||
|
await syncSubRules(subrules.url, isBg);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`[sync subrule error]: ${subrules.url}`, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据时间同步所有订阅规则
|
||||||
|
* @param {*} url
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const trySyncAllSubRules = async ({ subrulesList }, isBg = false) => {
|
||||||
|
try {
|
||||||
|
const { subRulesSyncAt } = await syncOpt.load();
|
||||||
|
const now = Date.now();
|
||||||
|
const interval = 24 * 60 * 60 * 1000; // 间隔一天
|
||||||
|
if (now - subRulesSyncAt > interval) {
|
||||||
|
await syncAllSubRules(subrulesList, isBg);
|
||||||
|
await syncOpt.update({ subRulesSyncAt: now });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("[try sync all subrules]", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从缓存或远程加载订阅规则
|
||||||
|
* @param {*} url
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const loadSubRules = async (url) => {
|
||||||
|
const rules = await rulesCache.get(url);
|
||||||
if (rules?.length) {
|
if (rules?.length) {
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
rules = await rulesCache.fetch(url);
|
return await syncSubRules(url);
|
||||||
await rulesCache.set(url, rules);
|
|
||||||
return rules;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,69 +13,95 @@ import { getSetting, getRules } from ".";
|
|||||||
import { apiSyncData } from "../apis";
|
import { apiSyncData } from "../apis";
|
||||||
import { sha256 } from "./utils";
|
import { sha256 } from "./utils";
|
||||||
|
|
||||||
export const loadSyncOpt = async () =>
|
/**
|
||||||
(await storage.getObj(STOKEY_SYNC)) || DEFAULT_SYNC;
|
* 同步相关数据
|
||||||
|
*/
|
||||||
|
export const syncOpt = {
|
||||||
|
load: async () => (await storage.getObj(STOKEY_SYNC)) || DEFAULT_SYNC,
|
||||||
|
update: async (obj) => {
|
||||||
|
await storage.putObj(STOKEY_SYNC, obj);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const syncSetting = async () => {
|
/**
|
||||||
|
* 同步设置
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const syncSetting = async (isBg = false) => {
|
||||||
try {
|
try {
|
||||||
const { syncUrl, syncKey, settingUpdateAt } = await loadSyncOpt();
|
const { syncUrl, syncKey, settingUpdateAt } = await syncOpt.load();
|
||||||
if (!syncUrl || !syncKey) {
|
if (!syncUrl || !syncKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const setting = await getSetting();
|
const setting = await getSetting();
|
||||||
const res = await apiSyncData(syncUrl, syncKey, {
|
const res = await apiSyncData(
|
||||||
key: KV_SETTING_KEY,
|
syncUrl,
|
||||||
value: setting,
|
syncKey,
|
||||||
updateAt: settingUpdateAt,
|
{
|
||||||
});
|
key: KV_SETTING_KEY,
|
||||||
|
value: setting,
|
||||||
|
updateAt: settingUpdateAt,
|
||||||
|
},
|
||||||
|
isBg
|
||||||
|
);
|
||||||
|
|
||||||
if (res && res.updateAt > settingUpdateAt) {
|
if (res && res.updateAt > settingUpdateAt) {
|
||||||
await storage.putObj(STOKEY_SYNC, {
|
await syncOpt.update({
|
||||||
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 syncOpt.update({ settingSyncAt: res.updateAt });
|
||||||
settingSyncAt: res.updateAt,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("[sync setting]", err);
|
console.log("[sync setting]", err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const syncRules = async () => {
|
/**
|
||||||
|
* 同步规则
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const syncRules = async (isBg = false) => {
|
||||||
try {
|
try {
|
||||||
const { syncUrl, syncKey, rulesUpdateAt } = await loadSyncOpt();
|
const { syncUrl, syncKey, rulesUpdateAt } = await syncOpt.load();
|
||||||
if (!syncUrl || !syncKey) {
|
if (!syncUrl || !syncKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rules = await getRules();
|
const rules = await getRules();
|
||||||
const res = await apiSyncData(syncUrl, syncKey, {
|
const res = await apiSyncData(
|
||||||
key: KV_RULES_KEY,
|
syncUrl,
|
||||||
value: rules,
|
syncKey,
|
||||||
updateAt: rulesUpdateAt,
|
{
|
||||||
});
|
key: KV_RULES_KEY,
|
||||||
|
value: rules,
|
||||||
|
updateAt: rulesUpdateAt,
|
||||||
|
},
|
||||||
|
isBg
|
||||||
|
);
|
||||||
|
|
||||||
if (res && res.updateAt > rulesUpdateAt) {
|
if (res && res.updateAt > rulesUpdateAt) {
|
||||||
await storage.putObj(STOKEY_SYNC, {
|
await syncOpt.update({
|
||||||
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 syncOpt.update({ rulesSyncAt: res.updateAt });
|
||||||
rulesSyncAt: res.updateAt,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("[sync user rules]", err);
|
console.log("[sync user rules]", err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步分享规则
|
||||||
|
* @param {*} param0
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const syncShareRules = async ({ rules, syncUrl, syncKey }) => {
|
export const syncShareRules = async ({ rules, syncUrl, syncKey }) => {
|
||||||
await apiSyncData(syncUrl, syncKey, {
|
await apiSyncData(syncUrl, syncKey, {
|
||||||
key: KV_RULES_SHARE_KEY,
|
key: KV_RULES_SHARE_KEY,
|
||||||
@@ -87,7 +113,11 @@ export const syncShareRules = async ({ rules, syncUrl, syncKey }) => {
|
|||||||
return shareUrl;
|
return shareUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const syncAll = async () => {
|
/**
|
||||||
await syncSetting();
|
* 同步个人设置和规则
|
||||||
await syncRules();
|
* @returns
|
||||||
|
*/
|
||||||
|
export const syncAll = async (isBg = false) => {
|
||||||
|
await syncSetting(isBg);
|
||||||
|
await syncRules(isBg);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import createCache from "@emotion/cache";
|
|||||||
import { CacheProvider } from "@emotion/react";
|
import { CacheProvider } from "@emotion/react";
|
||||||
import { getSetting, getRules, matchRule, getFab } from "./libs";
|
import { getSetting, getRules, matchRule, getFab } from "./libs";
|
||||||
import { Translator } from "./libs/translator";
|
import { Translator } from "./libs/translator";
|
||||||
|
import { trySyncAllSubRules } from "./libs/rules";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 入口函数
|
* 入口函数
|
||||||
@@ -70,4 +71,7 @@ import { Translator } from "./libs/translator";
|
|||||||
},
|
},
|
||||||
"C"
|
"C"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 同步订阅规则
|
||||||
|
trySyncAllSubRules(setting);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ import IconButton from "@mui/material/IconButton";
|
|||||||
import ShareIcon from "@mui/icons-material/Share";
|
import ShareIcon from "@mui/icons-material/Share";
|
||||||
import SyncIcon from "@mui/icons-material/Sync";
|
import SyncIcon from "@mui/icons-material/Sync";
|
||||||
import { useSubrules } from "../../hooks/Rules";
|
import { useSubrules } from "../../hooks/Rules";
|
||||||
import { rulesCache, tryLoadRules } from "../../libs/rules";
|
import { rulesCache, loadSubRules, syncSubRules } from "../../libs/rules";
|
||||||
import { useAlert } from "../../hooks/Alert";
|
import { useAlert } from "../../hooks/Alert";
|
||||||
import { loadSyncOpt, syncShareRules } from "../../libs/sync";
|
import { syncOpt, syncShareRules } from "../../libs/sync";
|
||||||
|
|
||||||
function RuleFields({ rule, rules, setShow }) {
|
function RuleFields({ rule, rules, setShow }) {
|
||||||
const initFormValues = rule || { ...DEFAULT_RULE, transOpen: "true" };
|
const initFormValues = rule || { ...DEFAULT_RULE, transOpen: "true" };
|
||||||
@@ -402,7 +402,7 @@ function ShareButton({ rules, injectRules, selectedSub }) {
|
|||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const handleClick = async () => {
|
const handleClick = async () => {
|
||||||
try {
|
try {
|
||||||
const { syncUrl, syncKey } = await loadSyncOpt();
|
const { syncUrl, syncKey } = await syncOpt.load();
|
||||||
if (!syncUrl || !syncKey) {
|
if (!syncUrl || !syncKey) {
|
||||||
alert.warning(i18n("error_sync_setting"));
|
alert.warning(i18n("error_sync_setting"));
|
||||||
return;
|
return;
|
||||||
@@ -410,7 +410,7 @@ function ShareButton({ rules, injectRules, selectedSub }) {
|
|||||||
|
|
||||||
const shareRules = [...rules.list];
|
const shareRules = [...rules.list];
|
||||||
if (injectRules) {
|
if (injectRules) {
|
||||||
const subRules = await tryLoadRules(selectedSub?.url);
|
const subRules = await loadSubRules(selectedSub?.url);
|
||||||
shareRules.splice(-1, 0, ...subRules);
|
shareRules.splice(-1, 0, ...subRules);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,9 +543,8 @@ function SubRulesItem({ index, url, selectedUrl, subrules, setRules }) {
|
|||||||
const handleSync = async () => {
|
const handleSync = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const rules = await rulesCache.fetch(url);
|
const rules = await syncSubRules(url);
|
||||||
await rulesCache.set(url, rules);
|
if (rules.length > 0 && url === selectedUrl) {
|
||||||
if (url === selectedUrl) {
|
|
||||||
setRules(rules);
|
setRules(rules);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -604,11 +603,10 @@ function SubRulesEdit({ subrules }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rules = await rulesCache.fetch(url);
|
const rules = await syncSubRules(url);
|
||||||
if (rules.length === 0) {
|
if (rules.length === 0) {
|
||||||
throw new Error("empty rules");
|
throw new Error("empty rules");
|
||||||
}
|
}
|
||||||
await rulesCache.set(url, rules);
|
|
||||||
await subrules.add(url);
|
await subrules.add(url);
|
||||||
setShowInput(false);
|
setShowInput(false);
|
||||||
setInputText("");
|
setInputText("");
|
||||||
@@ -687,7 +685,7 @@ function SubRules() {
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
const rules = await tryLoadRules(selectedSub?.url);
|
const rules = await loadSubRules(selectedSub?.url);
|
||||||
setRules(rules);
|
setRules(rules);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("[load rules]", err);
|
console.log("[load rules]", err);
|
||||||
|
|||||||
Reference in New Issue
Block a user