refactor: adjust setting dialog component

This commit is contained in:
GyDi
2022-11-20 21:48:39 +08:00
parent 572d81ecef
commit 892b919cf3
23 changed files with 845 additions and 988 deletions

View File

@@ -1,36 +1,18 @@
import useSWR from "swr";
import { useEffect, useState } from "react";
import { forwardRef, useImperativeHandle, useState } from "react";
import { useTranslation } from "react-i18next";
import {
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Divider,
Stack,
Tooltip,
Typography,
} from "@mui/material";
import { Checkbox, Divider, Stack, Tooltip, Typography } from "@mui/material";
import { InfoRounded } from "@mui/icons-material";
import {
getProfiles,
getRuntimeExists,
patchProfilesConfig,
} from "@/services/cmds";
import { ModalHandler } from "@/hooks/use-modal-handler";
import { getRuntimeExists } from "@/services/cmds";
import {
HANDLE_FIELDS,
DEFAULT_FIELDS,
OTHERS_FIELDS,
} from "@/utils/clash-fields";
import { BaseDialog, DialogRef } from "@/components/base";
import { useProfiles } from "@/hooks/use-profiles";
import Notice from "@/components/base/base-notice";
interface Props {
handler: ModalHandler;
}
const fieldSorter = (a: string, b: string) => {
if (a.includes("-") === a.includes("-")) {
if (a.length === b.length) return a.localeCompare(b);
@@ -43,13 +25,10 @@ const fieldSorter = (a: string, b: string) => {
const otherFields = [...OTHERS_FIELDS].sort(fieldSorter);
const handleFields = [...HANDLE_FIELDS, ...DEFAULT_FIELDS].sort(fieldSorter);
const ClashFieldViewer = ({ handler }: Props) => {
export const ClashFieldViewer = forwardRef<DialogRef>((props, ref) => {
const { t } = useTranslation();
const { data: profiles = {}, mutate: mutateProfile } = useSWR(
"getProfiles",
getProfiles
);
const { profiles = {}, patchProfiles } = useProfiles();
const { data: existsKeys = [], mutate: mutateExists } = useSWR(
"getRuntimeExists",
getRuntimeExists
@@ -58,20 +37,14 @@ const ClashFieldViewer = ({ handler }: Props) => {
const [open, setOpen] = useState(false);
const [selected, setSelected] = useState<string[]>([]);
if (handler) {
handler.current = {
open: () => setOpen(true),
close: () => setOpen(false),
};
}
useEffect(() => {
if (open) {
mutateProfile();
useImperativeHandle(ref, () => ({
open: () => {
mutateExists();
setSelected(profiles.valid || []);
}
}, [open, profiles.valid]);
setOpen(true);
},
close: () => setOpen(false),
}));
const handleChange = (item: string) => {
if (!item) return;
@@ -91,8 +64,7 @@ const ClashFieldViewer = ({ handler }: Props) => {
if (curSet.size === oldSet.size && curSet.size === joinSet.size) return;
try {
await patchProfilesConfig({ valid: [...curSet] });
mutateProfile();
await patchProfiles({ valid: [...curSet] });
// Notice.success("Refresh clash config", 1000);
} catch (err: any) {
Notice.error(err?.message || err.toString());
@@ -100,62 +72,56 @@ const ClashFieldViewer = ({ handler }: Props) => {
};
return (
<Dialog open={open} onClose={() => setOpen(false)}>
<DialogTitle>{t("Clash Field")}</DialogTitle>
<BaseDialog
open={open}
title={t("Clash Field")}
contentSx={{
pb: 0,
width: 320,
height: 300,
overflowY: "auto",
userSelect: "text",
}}
okBtn={t("Save")}
cancelBtn={t("Back")}
onClose={() => setOpen(false)}
onCancel={() => setOpen(false)}
onOk={handleSave}
>
{otherFields.map((item) => {
const inSelect = selected.includes(item);
const inConfig = existsKeys.includes(item);
<DialogContent
sx={{
pb: 0,
width: 320,
height: 300,
overflowY: "auto",
userSelect: "text",
}}
>
{otherFields.map((item) => {
const inSelect = selected.includes(item);
const inConfig = existsKeys.includes(item);
return (
<Stack key={item} mb={0.5} direction="row" alignItems="center">
<Checkbox
checked={inSelect}
size="small"
sx={{ p: 0.5 }}
onChange={() => handleChange(item)}
/>
<Typography width="100%">{item}</Typography>
{!inSelect && inConfig && <WarnIcon />}
</Stack>
);
})}
<Divider sx={{ my: 1 }}>
<Typography color="text.secondary" fontSize={14}>
Clash Verge Control Fields
</Typography>
</Divider>
{handleFields.map((item) => (
return (
<Stack key={item} mb={0.5} direction="row" alignItems="center">
<Checkbox defaultChecked disabled size="small" sx={{ p: 0.5 }} />
<Typography>{item}</Typography>
</Stack>
))}
</DialogContent>
<Checkbox
checked={inSelect}
size="small"
sx={{ p: 0.5 }}
onChange={() => handleChange(item)}
/>
<Typography width="100%">{item}</Typography>
<DialogActions>
<Button variant="outlined" onClick={() => setOpen(false)}>
{t("Back")}
</Button>
<Button variant="contained" onClick={handleSave}>
{t("Save")}
</Button>
</DialogActions>
</Dialog>
{!inSelect && inConfig && <WarnIcon />}
</Stack>
);
})}
<Divider sx={{ my: 1 }}>
<Typography color="text.secondary" fontSize={14}>
Clash Verge Control Fields
</Typography>
</Divider>
{handleFields.map((item) => (
<Stack key={item} mb={0.5} direction="row" alignItems="center">
<Checkbox defaultChecked disabled size="small" sx={{ p: 0.5 }} />
<Typography>{item}</Typography>
</Stack>
))}
</BaseDialog>
);
};
});
function WarnIcon() {
return (
@@ -164,5 +130,3 @@ function WarnIcon() {
</Tooltip>
);
}
export default ClashFieldViewer;