mirror of
https://github.com/clash-verge-rev/clash-verge-rev
synced 2025-05-05 05:03:45 +08:00
feat(settings page): add loading state (#1157)
* feat(settings page): add loading state * fix: type
This commit is contained in:
parent
ca323371a7
commit
2913b911e3
@ -1,4 +1,4 @@
|
|||||||
import React, { ReactNode } from "react";
|
import React, { ReactNode, useState } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
List,
|
List,
|
||||||
@ -8,13 +8,15 @@ import {
|
|||||||
ListSubheader,
|
ListSubheader,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { ChevronRightRounded } from "@mui/icons-material";
|
import { ChevronRightRounded } from "@mui/icons-material";
|
||||||
|
import CircularProgress from "@mui/material/CircularProgress";
|
||||||
|
import isAsyncFunction from "@/utils/is-async-function";
|
||||||
|
|
||||||
interface ItemProps {
|
interface ItemProps {
|
||||||
label: ReactNode;
|
label: ReactNode;
|
||||||
extra?: ReactNode;
|
extra?: ReactNode;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
secondary?: ReactNode;
|
secondary?: ReactNode;
|
||||||
onClick?: () => void;
|
onClick?: () => void | Promise<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SettingItem: React.FC<ItemProps> = (props) => {
|
export const SettingItem: React.FC<ItemProps> = (props) => {
|
||||||
@ -28,11 +30,27 @@ export const SettingItem: React.FC<ItemProps> = (props) => {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const handleClick = () => {
|
||||||
|
if (onClick) {
|
||||||
|
if (isAsyncFunction(onClick)) {
|
||||||
|
setIsLoading(true);
|
||||||
|
onClick()!.finally(() => setIsLoading(false));
|
||||||
|
} else {
|
||||||
|
onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return clickable ? (
|
return clickable ? (
|
||||||
<ListItem disablePadding>
|
<ListItem disablePadding>
|
||||||
<ListItemButton onClick={onClick}>
|
<ListItemButton onClick={handleClick} disabled={isLoading}>
|
||||||
<ListItemText primary={primary} secondary={secondary} />
|
<ListItemText primary={primary} secondary={secondary} />
|
||||||
<ChevronRightRounded />
|
{isLoading ? (
|
||||||
|
<CircularProgress color="inherit" size={20} />
|
||||||
|
) : (
|
||||||
|
<ChevronRightRounded />
|
||||||
|
)}
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
) : (
|
) : (
|
||||||
|
@ -51,14 +51,14 @@ const SettingClash = ({ onError }: Props) => {
|
|||||||
const onChangeVerge = (patch: Partial<IVergeConfig>) => {
|
const onChangeVerge = (patch: Partial<IVergeConfig>) => {
|
||||||
mutateVerge({ ...verge, ...patch }, false);
|
mutateVerge({ ...verge, ...patch }, false);
|
||||||
};
|
};
|
||||||
const onUpdateGeo = useLockFn(async () => {
|
const onUpdateGeo = async () => {
|
||||||
try {
|
try {
|
||||||
await updateGeoData();
|
await updateGeoData();
|
||||||
Notice.success(t("GeoData Updated"));
|
Notice.success(t("GeoData Updated"));
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
Notice.error(err?.response.data.message || err.toString());
|
Notice.error(err?.response.data.message || err.toString());
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingList title={t("Clash Setting")}>
|
<SettingList title={t("Clash Setting")}>
|
||||||
|
@ -55,7 +55,7 @@ const SettingVerge = ({ onError }: Props) => {
|
|||||||
mutateVerge({ ...verge, ...patch }, false);
|
mutateVerge({ ...verge, ...patch }, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCheckUpdate = useLockFn(async () => {
|
const onCheckUpdate = async () => {
|
||||||
try {
|
try {
|
||||||
const info = await checkUpdate();
|
const info = await checkUpdate();
|
||||||
if (!info?.shouldUpdate) {
|
if (!info?.shouldUpdate) {
|
||||||
@ -66,7 +66,7 @@ const SettingVerge = ({ onError }: Props) => {
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
Notice.error(err.message || err.toString());
|
Notice.error(err.message || err.toString());
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingList title={t("Verge Setting")}>
|
<SettingList title={t("Verge Setting")}>
|
||||||
|
3
src/utils/is-async-function.ts
Normal file
3
src/utils/is-async-function.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function isAsyncFunction(fn: Function): boolean {
|
||||||
|
return fn.constructor.name === "AsyncFunction";
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user