diff --git a/package.json b/package.json index aa8b89da6fd3ede62065b1f7b9e13efa8a5fdc3c..0ed36e25487ae8ddedc53cdf70d96008f969982e 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "axios": "^1.1.3", "dayjs": "1.11.5", "i18next": "^22.0.4", + "lodash-es": "^4.17.21", "monaco-editor": "^0.34.1", "react": "^17.0.2", "react-dom": "^17.0.2", @@ -47,6 +48,7 @@ "@types/fs-extra": "^9.0.13", "@types/js-cookie": "^3.0.2", "@types/lodash": "^4.14.180", + "@types/lodash-es": "^4.17.7", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "@vitejs/plugin-react": "^2.0.1", diff --git a/src/locales/en.json b/src/locales/en.json index 93111e2fc1b3d359f66348b0f43e36297650b817..573e5f8ea231e863b1bbc72168ea6f6acd8fb409 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -15,6 +15,7 @@ "global": "global", "direct": "direct", "script": "script", + "Profiles": "Profiles", "Profile URL": "Profile URL", "Import": "Import", @@ -34,6 +35,9 @@ "Refresh": "Refresh", "To Top": "To Top", "To End": "To End", + "Update All Profiles": "Update All Profiles", + "View Runtime Config": "View Runtime Config", + "Reactivate Profiles": "Reactivate Profiles", "Location": "Location", "Delay check": "Delay check", diff --git a/src/locales/zh.json b/src/locales/zh.json index 25a621228027b683131538a5f2eeb88b83bb274b..b64ce7a36307241d2426066da96bc8aecd8e695b 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -15,6 +15,7 @@ "global": "全局", "direct": "ç›´è¿ž", "script": "脚本", + "Profiles": "é…ç½®", "Profile URL": "é…置文件链接", "Import": "导入", @@ -34,6 +35,9 @@ "Refresh": "刷新", "To Top": "移到最å‰", "To End": "移到末尾", + "Update All Profiles": "更新所有é…ç½®", + "View Runtime Config": "查看è¿è¡Œæ—¶é…ç½®", + "Reactivate Profiles": "é‡æ–°æ¿€æ´»é…ç½®", "Location": "当å‰èŠ‚点", "Delay check": "延迟测试", diff --git a/src/pages/profiles.tsx b/src/pages/profiles.tsx index ec423f1231bf69ce4b68c80bb5c8bcfb1a549893..1c10126b3d7fed3d83faae3277f445aed6406d7b 100644 --- a/src/pages/profiles.tsx +++ b/src/pages/profiles.tsx @@ -1,8 +1,13 @@ import useSWR, { mutate } from "swr"; -import { useLockFn } from "ahooks"; import { useMemo, useRef, useState } from "react"; +import { useLockFn } from "ahooks"; +import { useSetRecoilState } from "recoil"; import { Box, Button, Grid, IconButton, Stack, TextField } from "@mui/material"; -import { CachedRounded } from "@mui/icons-material"; +import { + LocalFireDepartmentRounded, + RefreshRounded, + TextSnippetOutlined, +} from "@mui/icons-material"; import { useTranslation } from "react-i18next"; import { getProfiles, @@ -10,9 +15,11 @@ import { enhanceProfiles, getRuntimeLogs, deleteProfile, + updateProfile, } from "@/services/cmds"; +import { atomLoadingCache } from "@/services/states"; import { closeAllConnections } from "@/services/api"; -import { BasePage, Notice } from "@/components/base"; +import { BasePage, DialogRef, Notice } from "@/components/base"; import { ProfileViewer, ProfileViewerRef, @@ -20,6 +27,8 @@ import { import { ProfileItem } from "@/components/profile/profile-item"; import { ProfileMore } from "@/components/profile/profile-more"; import { useProfiles } from "@/hooks/use-profiles"; +import { ConfigViewer } from "@/components/setting/mods/config-viewer"; +import { throttle } from "lodash-es"; const ProfilePage = () => { const { t } = useTranslation(); @@ -41,6 +50,7 @@ const ProfilePage = () => { const chain = profiles.chain || []; const viewerRef = useRef<ProfileViewerRef>(null); + const configRef = useRef<DialogRef>(null); // distinguish type const { regularItems, enhanceItems } = useMemo(() => { @@ -149,18 +159,65 @@ const ProfilePage = () => { mutateLogs(); }); + // 更新所有é…ç½® + const setLoadingCache = useSetRecoilState(atomLoadingCache); + const onUpdateAll = useLockFn(async () => { + const throttleMutate = throttle(mutateProfiles, 2000, { + trailing: true, + }); + const updateOne = async (uid: string) => { + try { + await updateProfile(uid); + throttleMutate(); + } finally { + setLoadingCache((cache) => ({ ...cache, [uid]: false })); + } + }; + + return new Promise((resolve) => { + setLoadingCache((cache) => { + // 获å–没有æ£åœ¨æ›´æ–°çš„é…ç½® + const items = regularItems.filter( + (e) => e.type === "remote" && !cache[e.uid] + ); + const change = Object.fromEntries(items.map((e) => [e.uid, true])); + + Promise.allSettled(items.map((e) => updateOne(e.uid))).then(resolve); + return { ...cache, ...change }; + }); + }); + }); + return ( <BasePage title={t("Profiles")} header={ - <Box sx={{ mt: 1, display: "flex", alignItems: "center" }}> + <Box sx={{ mt: 1, display: "flex", alignItems: "center", gap: 1 }}> + <IconButton + size="small" + color="inherit" + title={t("Update All Profiles")} + onClick={onUpdateAll} + > + <RefreshRounded /> + </IconButton> + <IconButton size="small" color="inherit" - title={t("Refresh profiles")} + title={t("View Runtime Config")} + onClick={() => configRef.current?.open()} + > + <TextSnippetOutlined /> + </IconButton> + + <IconButton + size="small" + color="primary" + title={t("Reactivate Profiles")} onClick={onEnhance} > - <CachedRounded /> + <LocalFireDepartmentRounded /> </IconButton> </Box> } @@ -232,6 +289,7 @@ const ProfilePage = () => { )} <ProfileViewer ref={viewerRef} onChange={() => mutateProfiles()} /> + <ConfigViewer ref={configRef} /> </BasePage> ); }; diff --git a/yarn.lock b/yarn.lock index 75dddd46aa72fcfbdf3493a933a608d4f802db83..ad799d4af567d1bbcde145978cfb56befc445031 100644 --- a/yarn.lock +++ b/yarn.lock @@ -869,6 +869,18 @@ resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-3.0.2.tgz#451eaeece64c6bdac8b2dde0caab23b085899e0d" integrity sha512-6+0ekgfusHftJNYpihfkMu8BWdeHs9EOJuGcSofErjstGPfPGEu9yTu4t460lTzzAMl2cM5zngQJqPMHbbnvYA== +"@types/lodash-es@^4.17.7": + version "4.17.7" + resolved "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.7.tgz#22edcae9f44aff08546e71db8925f05b33c7cc40" + integrity sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.191" + resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" + integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== + "@types/lodash@^4.14.180": version "4.14.180" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.180.tgz#4ab7c9ddfc92ec4a887886483bc14c79fb380670" @@ -1722,6 +1734,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"