From 0e1724b96f706ae11a46f5a662bcee6b2c7cf952 Mon Sep 17 00:00:00 2001 From: Wukong Sun Date: Tue, 8 Oct 2024 19:12:16 +0800 Subject: [PATCH] fix: mf-6371 infinite loading in DAO tab (#11828) --- .../src/SiteAdaptor/ProfileSpaceHeader.tsx | 15 ++++---- .../Snapshot/src/SiteAdaptor/ProfileView.tsx | 20 +++++----- .../Snapshot/src/SiteAdaptor/SpaceMenu.tsx | 37 +++++-------------- .../hooks/useCurrentAccountFollowSpaceList.ts | 14 ++++--- .../src/SiteAdaptor/hooks/useProposalList.ts | 14 ++++--- .../src/SiteAdaptor/hooks/useSpace.ts | 14 ++++--- 6 files changed, 51 insertions(+), 63 deletions(-) diff --git a/packages/plugins/Snapshot/src/SiteAdaptor/ProfileSpaceHeader.tsx b/packages/plugins/Snapshot/src/SiteAdaptor/ProfileSpaceHeader.tsx index 33ccf7dcafeb..c0a0e1771438 100644 --- a/packages/plugins/Snapshot/src/SiteAdaptor/ProfileSpaceHeader.tsx +++ b/packages/plugins/Snapshot/src/SiteAdaptor/ProfileSpaceHeader.tsx @@ -13,7 +13,7 @@ import { useSnapshotTrans } from '../locales/index.js' interface ProfileSpaceHeaderProps { spaceList: Array> currentSpace: DAOResult - setSpaceIndex: (x: number) => void + setSpaceId(id: string): void theme: Theme } @@ -63,14 +63,13 @@ const useStyles = makeStyles()((theme) => ({ }, })) -export function ProfileSpaceHeader(props: ProfileSpaceHeaderProps) { - const { spaceList, currentSpace, setSpaceIndex, theme } = props +export function ProfileSpaceHeader({ spaceList, currentSpace, setSpaceId, theme }: ProfileSpaceHeaderProps) { const t = useSnapshotTrans() const { classes } = useStyles() const [spaceMenuOpen, setSpaceMenuOpen] = useState(false) const spaceRef = useRef(null) const { account } = useChainContext() - const { value: followedSpaceList } = useCurrentAccountFollowSpaceList() + const { data: followedSpaceList } = useCurrentAccountFollowSpaceList() return ( @@ -96,13 +95,13 @@ export function ProfileSpaceHeader(props: ProfileSpaceHeaderProps) { { - setSpaceIndex(i) + onSelect={(option) => { + setSpaceId(option.spaceId) setSpaceMenuOpen(false) }} containerRef={spaceRef} - spaceMenuOpen={spaceMenuOpen} - setSpaceMenuOpen={setSpaceMenuOpen} + open={spaceMenuOpen} + onClose={() => setSpaceMenuOpen(false)} /> diff --git a/packages/plugins/Snapshot/src/SiteAdaptor/ProfileView.tsx b/packages/plugins/Snapshot/src/SiteAdaptor/ProfileView.tsx index 191ae76faf46..110a5149b520 100644 --- a/packages/plugins/Snapshot/src/SiteAdaptor/ProfileView.tsx +++ b/packages/plugins/Snapshot/src/SiteAdaptor/ProfileView.tsx @@ -6,7 +6,7 @@ import type { DAOResult } from '@masknet/web3-shared-base' import type { ChainId } from '@masknet/web3-shared-evm' import { TabContext } from '@mui/lab' import { Icons } from '@masknet/icons' -import { PluginID } from '@masknet/shared-base' +import { EMPTY_LIST, PluginID } from '@masknet/shared-base' import { useIsMinimalMode } from '@masknet/plugin-infra/content-script' import { PluginDescriptor } from './PluginDescriptor.js' import { ProfileSpaceHeader } from './ProfileSpaceHeader.js' @@ -47,7 +47,7 @@ interface ProfileViewProps extends withClasses<'content' | 'footer'> { export function ProfileView(props: ProfileViewProps) { const { ProfileCardProps, spaceList } = props - const { classes } = useStyles(undefined, { props }) + const { classes } = useStyles() const t = useSnapshotTrans() const theme = useTheme() const [currentTab, , , setTab] = useTabs( @@ -57,26 +57,26 @@ export function ProfileView(props: ProfileViewProps) { ContentTabs.Pending, ContentTabs.Closed, ) - const [spaceIndex, setSpaceIndex] = useState(0) const isMinimalMode = useIsMinimalMode(PluginID.Snapshot) - const currentSpace = spaceList[spaceIndex] + const [spaceId = spaceList[0]?.spaceId, setSpaceId] = useState() + const currentSpace = spaceList.find((x) => x.spaceId === spaceId) || spaceList[0] - const { value: space, loading: loadingSpaceMemberList } = useSpace(currentSpace.spaceId) + const { data: space, isPending: loadingSpaceMemberList } = useSpace(spaceId) - const { value: proposalList, loading: loadingProposalList } = useProposalList( + const { data: proposalList, isPending: loadingProposalList } = useProposalList( currentSpace.spaceId, currentSpace.strategyName ?? space?.symbol, ) const [isPending, startTransition] = useTransition() const filteredProposalList = useMemo(() => { - if (!proposalList?.length || !space?.members) return + if (!proposalList?.length || !space?.members) return EMPTY_LIST if (currentTab === ContentTabs.All) return proposalList if (currentTab === ContentTabs.Core) return proposalList.filter((x) => space.members.includes(x.author)) return proposalList.filter((x) => x.state.toLowerCase() === currentTab.toLowerCase()) - }, [currentTab, JSON.stringify(proposalList), JSON.stringify(space?.members)]) + }, [currentTab, proposalList, space?.members]) if (isMinimalMode) { return ( @@ -104,7 +104,7 @@ export function ProfileView(props: ProfileViewProps) { ...currentSpace, followersCount: space?.followersCount ?? currentSpace.followersCount, }} - setSpaceIndex={setSpaceIndex} + setSpaceId={setSpaceId} /> @@ -121,7 +121,7 @@ export function ProfileView(props: ProfileViewProps) { - {loadingProposalList || loadingSpaceMemberList || !filteredProposalList || isPending ? + {loadingProposalList || loadingSpaceMemberList || isPending ? diff --git a/packages/plugins/Snapshot/src/SiteAdaptor/SpaceMenu.tsx b/packages/plugins/Snapshot/src/SiteAdaptor/SpaceMenu.tsx index 3d6e203802ac..22149e8fcd1a 100644 --- a/packages/plugins/Snapshot/src/SiteAdaptor/SpaceMenu.tsx +++ b/packages/plugins/Snapshot/src/SiteAdaptor/SpaceMenu.tsx @@ -1,8 +1,7 @@ import type { RefObject } from 'react' -import { isEqual } from 'lodash-es' import { Icons } from '@masknet/icons' import { makeStyles, ShadowRootMenu } from '@masknet/theme' -import { Avatar, MenuItem, Stack, Typography, Divider } from '@mui/material' +import { Avatar, MenuItem, Stack, Typography, Divider, type MenuProps } from '@mui/material' import type { DAOResult } from '@masknet/web3-shared-base' import type { ChainId } from '@masknet/web3-shared-evm' import { useSnapshotTrans } from '../locales/index.js' @@ -71,47 +70,31 @@ const useStyles = makeStyles()((theme) => ({ }, })) -interface SpaceMenuProps { +interface SpaceMenuProps extends Omit { options: Array> currentOption?: DAOResult - onSelect(index: number): void + onSelect(space: DAOResult): void containerRef: RefObject - spaceMenuOpen: boolean - setSpaceMenuOpen: (a: boolean) => void - disablePortal?: boolean - disableScrollLock?: boolean } -export function SpaceMenu({ - options, - currentOption, - onSelect, - containerRef, - spaceMenuOpen, - setSpaceMenuOpen, - disablePortal, - disableScrollLock, -}: SpaceMenuProps) { +export function SpaceMenu({ options, currentOption, onSelect, containerRef, ...rest }: SpaceMenuProps) { const { classes } = useStyles() const t = useSnapshotTrans() return ( setSpaceMenuOpen(false)}> + {...rest}>
{t.plugin_snapshot_space()} - {options.map((x, i) => { - const selected = isEqual(x, currentOption) + {options.map((option) => { + const selected = option.spaceId === currentOption?.spaceId return ( - onSelect(i)}> - + onSelect(option)}> + - {x.spaceName} + {option.spaceName}
{selected ? diff --git a/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useCurrentAccountFollowSpaceList.ts b/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useCurrentAccountFollowSpaceList.ts index d818f873f802..f3d29893e499 100644 --- a/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useCurrentAccountFollowSpaceList.ts +++ b/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useCurrentAccountFollowSpaceList.ts @@ -1,13 +1,15 @@ import { useChainContext } from '@masknet/web3-hooks-base' import { Snapshot } from '@masknet/web3-providers' -import { useAsyncRetry } from 'react-use' +import { useQuery } from '@tanstack/react-query' export function useCurrentAccountFollowSpaceList() { const { account } = useChainContext() + return useQuery({ + queryKey: ['following-space-list', account], + async queryFn() { + if (!account) return [] - return useAsyncRetry(async () => { - if (!account) return - - return Snapshot.getFollowingSpaceIdList(account) - }, [account]) + return Snapshot.getFollowingSpaceIdList(account) + }, + }) } diff --git a/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useProposalList.ts b/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useProposalList.ts index 0fe8ad51476f..41d013237b9d 100644 --- a/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useProposalList.ts +++ b/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useProposalList.ts @@ -1,11 +1,13 @@ -import { useAsyncRetry } from 'react-use' import { EMPTY_LIST } from '@masknet/shared-base' import { Snapshot } from '@masknet/web3-providers' -import type { SnapshotBaseAPI } from '@masknet/web3-providers/types' +import { useQuery } from '@tanstack/react-query' export function useProposalList(spaceId: string, strategyName?: string) { - return useAsyncRetry(async () => { - if (!spaceId) return EMPTY_LIST - return Snapshot.getProposalListBySpace(spaceId, strategyName) - }, [spaceId, strategyName]) + return useQuery({ + queryKey: ['proposal-list', spaceId, strategyName], + queryFn: async () => { + if (!spaceId) return EMPTY_LIST + return Snapshot.getProposalListBySpace(spaceId, strategyName) + }, + }) } diff --git a/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useSpace.ts b/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useSpace.ts index 602eed3e14e8..39590f3cdb9d 100644 --- a/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useSpace.ts +++ b/packages/plugins/Snapshot/src/SiteAdaptor/hooks/useSpace.ts @@ -1,10 +1,12 @@ -import { useAsyncRetry } from 'react-use' import { Snapshot } from '@masknet/web3-providers' -import type { SnapshotBaseAPI } from '@masknet/web3-providers/types' +import { useQuery } from '@tanstack/react-query' export function useSpace(spaceId: string) { - return useAsyncRetry(async () => { - if (!spaceId) return - return Snapshot.getSpace(spaceId) - }, [spaceId]) + return useQuery({ + queryKey: ['space', spaceId], + async queryFn() { + if (!spaceId) return null + return Snapshot.getSpace(spaceId) + }, + }) }