فهرست منبع

feat(settings page): add loading state (#1157)

* feat(settings page): add loading state

* fix: type
Eric Huang 1 سال پیش
والد
کامیت
ad35ed96c8

+ 22 - 4
src/components/setting/mods/setting-comp.tsx

@@ -1,4 +1,4 @@
-import React, { ReactNode } from "react";
+import React, { ReactNode, useState } from "react";
 import {
   Box,
   List,
@@ -8,13 +8,15 @@ import {
   ListSubheader,
 } from "@mui/material";
 import { ChevronRightRounded } from "@mui/icons-material";
+import CircularProgress from "@mui/material/CircularProgress";
+import isAsyncFunction from "@/utils/is-async-function";
 
 interface ItemProps {
   label: ReactNode;
   extra?: ReactNode;
   children?: ReactNode;
   secondary?: ReactNode;
-  onClick?: () => void;
+  onClick?: () => void | Promise<any>;
 }
 
 export const SettingItem: React.FC<ItemProps> = (props) => {
@@ -28,11 +30,27 @@ export const SettingItem: React.FC<ItemProps> = (props) => {
     </Box>
   );
 
+  const [isLoading, setIsLoading] = useState(false);
+  const handleClick = () => {
+    if (onClick) {
+      if (isAsyncFunction(onClick)) {
+        setIsLoading(true);
+        onClick()!.finally(() => setIsLoading(false));
+      } else {
+        onClick();
+      }
+    }
+  };
+
   return clickable ? (
     <ListItem disablePadding>
-      <ListItemButton onClick={onClick}>
+      <ListItemButton onClick={handleClick} disabled={isLoading}>
         <ListItemText primary={primary} secondary={secondary} />
-        <ChevronRightRounded />
+        {isLoading ? (
+          <CircularProgress color="inherit" size={20} />
+        ) : (
+          <ChevronRightRounded />
+        )}
       </ListItemButton>
     </ListItem>
   ) : (

+ 2 - 2
src/components/setting/setting-clash.tsx

@@ -51,14 +51,14 @@ const SettingClash = ({ onError }: Props) => {
   const onChangeVerge = (patch: Partial<IVergeConfig>) => {
     mutateVerge({ ...verge, ...patch }, false);
   };
-  const onUpdateGeo = useLockFn(async () => {
+  const onUpdateGeo = async () => {
     try {
       await updateGeoData();
       Notice.success(t("GeoData Updated"));
     } catch (err: any) {
       Notice.error(err?.response.data.message || err.toString());
     }
-  });
+  };
 
   return (
     <SettingList title={t("Clash Setting")}>

+ 2 - 2
src/components/setting/setting-verge.tsx

@@ -55,7 +55,7 @@ const SettingVerge = ({ onError }: Props) => {
     mutateVerge({ ...verge, ...patch }, false);
   };
 
-  const onCheckUpdate = useLockFn(async () => {
+  const onCheckUpdate = async () => {
     try {
       const info = await checkUpdate();
       if (!info?.shouldUpdate) {
@@ -66,7 +66,7 @@ const SettingVerge = ({ onError }: Props) => {
     } catch (err: any) {
       Notice.error(err.message || err.toString());
     }
-  });
+  };
 
   return (
     <SettingList title={t("Verge Setting")}>

+ 3 - 0
src/utils/is-async-function.ts

@@ -0,0 +1,3 @@
+export default function isAsyncFunction(fn: Function): boolean {
+  return fn.constructor.name === "AsyncFunction";
+}