webfix
This commit is contained in:
@@ -33,13 +33,12 @@ export const apiSyncData = async (url, key, data, isBg = false) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载订阅规则
|
* 下载数据
|
||||||
* @param {*} url
|
* @param {*} url
|
||||||
* @param {*} isBg
|
* @param {*} isBg
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const apiFetchRules = (url, isBg = false) =>
|
export const apiFetch = (url, isBg = false) => fetchPolyfill(url, { isBg });
|
||||||
fetchPolyfill(url, { isBg });
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 谷歌翻译
|
* 谷歌翻译
|
||||||
|
|||||||
@@ -441,9 +441,9 @@ export const I18N = {
|
|||||||
zh: `数据同步密钥`,
|
zh: `数据同步密钥`,
|
||||||
en: `Data Sync Key`,
|
en: `Data Sync Key`,
|
||||||
},
|
},
|
||||||
data_sync_test: {
|
sync_now: {
|
||||||
zh: `数据同步测试`,
|
zh: `立即同步`,
|
||||||
en: `Data Sync Test`,
|
en: `Sync Now`,
|
||||||
},
|
},
|
||||||
sync_success: {
|
sync_success: {
|
||||||
zh: `同步成功!`,
|
zh: `同步成功!`,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
STOKEY_SYNC,
|
STOKEY_SYNC,
|
||||||
STOKEY_MSAUTH,
|
STOKEY_MSAUTH,
|
||||||
STOKEY_RULESCACHE_PREFIX,
|
STOKEY_RULESCACHE_PREFIX,
|
||||||
|
STOKEY_WEBFIXCACHE_PREFIX,
|
||||||
DEFAULT_SETTING,
|
DEFAULT_SETTING,
|
||||||
DEFAULT_RULES,
|
DEFAULT_RULES,
|
||||||
DEFAULT_SYNC,
|
DEFAULT_SYNC,
|
||||||
@@ -104,6 +105,14 @@ export const delSubRules = (url) => del(STOKEY_RULESCACHE_PREFIX + url);
|
|||||||
export const setSubRules = (url, val) =>
|
export const setSubRules = (url, val) =>
|
||||||
setObj(STOKEY_RULESCACHE_PREFIX + url, val);
|
setObj(STOKEY_RULESCACHE_PREFIX + url, val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修复站点
|
||||||
|
*/
|
||||||
|
export const getWebfix = (url) => getObj(STOKEY_WEBFIXCACHE_PREFIX + url);
|
||||||
|
export const getWebfixWithDefault = async () => (await getWebfix()) || [];
|
||||||
|
export const setWebfix = (url, val) =>
|
||||||
|
setObj(STOKEY_WEBFIXCACHE_PREFIX + url, val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fab位置
|
* fab位置
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
getSubRules,
|
getSubRules,
|
||||||
updateSetting,
|
updateSetting,
|
||||||
} from "./storage";
|
} from "./storage";
|
||||||
import { apiFetchRules } from "../apis";
|
import { apiFetch } from "../apis";
|
||||||
import { checkRules } from "./rules";
|
import { checkRules } from "./rules";
|
||||||
import { isAllchar } from "./utils";
|
import { isAllchar } from "./utils";
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ import { isAllchar } from "./utils";
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const syncSubRules = async (url, isBg = false) => {
|
export const syncSubRules = async (url, isBg = false) => {
|
||||||
const res = await apiFetchRules(url, isBg);
|
const res = await apiFetch(url, isBg);
|
||||||
const rules = checkRules(res).filter(
|
const rules = checkRules(res).filter(
|
||||||
({ pattern }) => !isAllchar(pattern, GLOBAL_KEY)
|
({ pattern }) => !isAllchar(pattern, GLOBAL_KEY)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import { isMatch } from "./utils";
|
import { isMatch } from "./utils";
|
||||||
|
import { getWebfix, setWebfix } from "./storage";
|
||||||
|
import { apiFetch } from "../apis";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修复程序类型
|
||||||
|
*/
|
||||||
|
const WEBFIX_BR = "br";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要修复的站点列表
|
* 需要修复的站点列表
|
||||||
@@ -7,18 +14,18 @@ import { isMatch } from "./utils";
|
|||||||
* - rootSlector 需要监听的选择器,可留空
|
* - rootSlector 需要监听的选择器,可留空
|
||||||
* - fixer 修复函数,可针对不同网址,选用不同修复函数
|
* - fixer 修复函数,可针对不同网址,选用不同修复函数
|
||||||
*/
|
*/
|
||||||
export const sites = [
|
const DEFAULT_SITES = [
|
||||||
{
|
{
|
||||||
pattern: "www.phoronix.com",
|
pattern: "www.phoronix.com",
|
||||||
selector: ".content",
|
selector: ".content",
|
||||||
rootSlector: "",
|
rootSlector: "",
|
||||||
fixer: brFixer,
|
fixer: WEBFIX_BR,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: "t.me/s/*",
|
pattern: "t.me/s/*",
|
||||||
selector: ".tgme_widget_message_text",
|
selector: ".tgme_widget_message_text",
|
||||||
rootSlector: ".tgme_channel_history",
|
rootSlector: ".tgme_channel_history",
|
||||||
fixer: brFixer,
|
fixer: WEBFIX_BR,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -80,6 +87,13 @@ function brFixer(node) {
|
|||||||
node.innerHTML = html;
|
node.innerHTML = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修复程序映射
|
||||||
|
*/
|
||||||
|
const fixerMap = {
|
||||||
|
[WEBFIX_BR]: brFixer,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找、监听节点,并执行修复函数
|
* 查找、监听节点,并执行修复函数
|
||||||
* @param {*} selector
|
* @param {*} selector
|
||||||
@@ -108,19 +122,51 @@ function run(selector, fixer, rootSlector) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步远程数据
|
||||||
|
* @param {*} url
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const syncWebfix = async (url) => {
|
||||||
|
const sites = await apiFetch(url);
|
||||||
|
await setWebfix(url, sites);
|
||||||
|
return sites;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从缓存或远程加载修复站点
|
||||||
|
* @param {*} url
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const loadOrFetchWebfix = async (url) => {
|
||||||
|
try {
|
||||||
|
let sites = await getWebfix(url);
|
||||||
|
if (sites?.length) {
|
||||||
|
return sites;
|
||||||
|
}
|
||||||
|
return syncWebfix(url);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("[load webfix]", err.message);
|
||||||
|
return DEFAULT_SITES;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 匹配站点
|
* 匹配站点
|
||||||
*/
|
*/
|
||||||
export function webfix(href, { injectWebfix }) {
|
export async function webfix(href, { injectWebfix }) {
|
||||||
try {
|
try {
|
||||||
if (!injectWebfix) {
|
if (!injectWebfix) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sites = await loadOrFetchWebfix(process.env.REACT_APP_WEBFIXURL);
|
||||||
for (var i = 0; i < sites.length; i++) {
|
for (var i = 0; i < sites.length; i++) {
|
||||||
var site = sites[i];
|
var site = sites[i];
|
||||||
if (isMatch(href, site.pattern)) {
|
if (isMatch(href, site.pattern)) {
|
||||||
run(site.selector, site.fixer, site.rootSlector);
|
if (fixerMap[site.fixer]) {
|
||||||
|
run(site.selector, fixerMap[site.fixer], site.rootSlector);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default function SyncSetting() {
|
|||||||
onClick={handleSyncTest}
|
onClick={handleSyncTest}
|
||||||
startIcon={<SyncIcon />}
|
startIcon={<SyncIcon />}
|
||||||
>
|
>
|
||||||
{i18n("data_sync_test")}
|
{i18n("sync_now")}
|
||||||
</Button>
|
</Button>
|
||||||
{loading && <CircularProgress size={16} />}
|
{loading && <CircularProgress size={16} />}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Stack from "@mui/material/Stack";
|
import Stack from "@mui/material/Stack";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useI18n } from "../../hooks/I18n";
|
import { useI18n } from "../../hooks/I18n";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import Accordion from "@mui/material/Accordion";
|
import Accordion from "@mui/material/Accordion";
|
||||||
@@ -9,13 +9,17 @@ import AccordionDetails from "@mui/material/AccordionDetails";
|
|||||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||||
import Alert from "@mui/material/Alert";
|
import Alert from "@mui/material/Alert";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import { sites as webfixSites } from "../../libs/webfix";
|
|
||||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||||
import Switch from "@mui/material/Switch";
|
import Switch from "@mui/material/Switch";
|
||||||
import { useSetting } from "../../hooks/Setting";
|
import { useSetting } from "../../hooks/Setting";
|
||||||
|
import CircularProgress from "@mui/material/CircularProgress";
|
||||||
|
import { syncWebfix, loadOrFetchWebfix } from "../../libs/webfix";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import SyncIcon from "@mui/icons-material/Sync";
|
||||||
|
import { useAlert } from "../../hooks/Alert";
|
||||||
|
|
||||||
function ApiFields({ site }) {
|
function ApiFields({ site }) {
|
||||||
const { selector, rootSlector } = site;
|
const { selector, rootSlector, fixer } = site;
|
||||||
return (
|
return (
|
||||||
<Stack spacing={3}>
|
<Stack spacing={3}>
|
||||||
<TextField
|
<TextField
|
||||||
@@ -32,6 +36,13 @@ function ApiFields({ site }) {
|
|||||||
value={selector}
|
value={selector}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
|
<TextField
|
||||||
|
size="small"
|
||||||
|
label={"fixer"}
|
||||||
|
name="fixer"
|
||||||
|
value={fixer}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -56,33 +67,90 @@ function ApiAccordion({ site }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Webfix() {
|
export default function Webfix() {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [sites, setSites] = useState([]);
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
|
const alert = useAlert();
|
||||||
const { setting, updateSetting } = useSetting();
|
const { setting, updateSetting } = useSetting();
|
||||||
|
|
||||||
|
const handleSyncTest = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
await syncWebfix(process.env.REACT_APP_WEBFIXURL);
|
||||||
|
alert.success(i18n("sync_success"));
|
||||||
|
} catch (err) {
|
||||||
|
console.log("[sync webfix]", err);
|
||||||
|
alert.error(i18n("sync_failed"));
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const sites = await loadOrFetchWebfix(process.env.REACT_APP_WEBFIXURL);
|
||||||
|
setSites(sites);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("[load webfix]", err.message);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Stack spacing={3}>
|
<Stack spacing={3}>
|
||||||
<Alert severity="info">{i18n("patch_setting_help")}</Alert>
|
<Alert severity="info">{i18n("patch_setting_help")}</Alert>
|
||||||
|
|
||||||
<FormControlLabel
|
<Stack
|
||||||
control={
|
direction="row"
|
||||||
<Switch
|
alignItems="center"
|
||||||
size="small"
|
spacing={2}
|
||||||
checked={!!setting.injectWebfix}
|
useFlexGap
|
||||||
onChange={() => {
|
flexWrap="wrap"
|
||||||
updateSetting({
|
>
|
||||||
injectWebfix: !setting.injectWebfix,
|
<Button
|
||||||
});
|
size="small"
|
||||||
}}
|
variant="outlined"
|
||||||
/>
|
disabled={loading}
|
||||||
}
|
onClick={handleSyncTest}
|
||||||
label={i18n("inject_webfix")}
|
startIcon={<SyncIcon />}
|
||||||
/>
|
>
|
||||||
|
{i18n("sync_now")}
|
||||||
|
</Button>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
size="small"
|
||||||
|
checked={!!setting.injectWebfix}
|
||||||
|
onChange={() => {
|
||||||
|
updateSetting({
|
||||||
|
injectWebfix: !setting.injectWebfix,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={i18n("inject_webfix")}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
<Box>
|
{setting.injectWebfix && (
|
||||||
{webfixSites.map((site) => (
|
<Box>
|
||||||
<ApiAccordion key={site.pattern} site={site} />
|
{loading ? (
|
||||||
))}
|
<center>
|
||||||
</Box>
|
<CircularProgress size={16} />
|
||||||
|
</center>
|
||||||
|
) : (
|
||||||
|
sites.map((site) => (
|
||||||
|
<ApiAccordion key={site.pattern} site={site} />
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user