Skip to content

Commit

Permalink
converted more selectors to queries
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahSaso committed Jun 5, 2024
1 parent b555707 commit f75da18
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 101 deletions.
36 changes: 19 additions & 17 deletions packages/stateful/command/contexts/generic/dao.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ import {
HomeOutlined,
InboxOutlined,
} from '@mui/icons-material'
import { useQueryClient } from '@tanstack/react-query'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useRecoilState } from 'recoil'
import useDeepCompareEffect from 'use-deep-compare-effect'

import { navigatingToHrefAtom } from '@dao-dao/state'
import {
useCachedLoading,
useDaoInfoContext,
useDaoNavHelpers,
} from '@dao-dao/stateless'
import { useDaoInfoContext, useDaoNavHelpers } from '@dao-dao/stateless'
import { ContractVersion, Feature } from '@dao-dao/types'
import {
CommandModalContextMaker,
Expand All @@ -26,8 +23,13 @@ import {
import { getDisplayNameForChainId, getFallbackImage } from '@dao-dao/utils'

import { DaoProvidersWithoutInfo } from '../../../components'
import { useDaoTabs, useFollowingDaos, useGovDaoTabs } from '../../../hooks'
import { chainSubDaoInfosSelector, subDaoInfosSelector } from '../../../recoil'
import {
useCachedLoadingQuery,
useDaoTabs,
useFollowingDaos,
useGovDaoTabs,
} from '../../../hooks'
import { daoQueries } from '../../../queries'

export const makeGenericDaoContext: CommandModalContextMaker<{
dao: CommandModalDaoInfo
Expand Down Expand Up @@ -68,19 +70,19 @@ export const makeGenericDaoContext: CommandModalContextMaker<{
const daoPageHref = getDaoPath(coreAddress)
const createProposalHref = getDaoProposalPath(coreAddress, 'create')

const subDaosLoading = useCachedLoading(
const queryClient = useQueryClient()
const subDaosLoading = useCachedLoadingQuery(
coreVersion === ContractVersion.Gov
? chainSubDaoInfosSelector({
chainId,
})
: supportedFeatures[Feature.SubDaos]
? subDaoInfosSelector({
? daoQueries.chainSubDaoInfos(queryClient, {
chainId,
coreAddress,
})
: // Passing undefined here returns an infinite loading state, which is
// fine because it's never used.
undefined,
: {
...daoQueries.subDaoInfos(queryClient, {
chainId,
coreAddress,
}),
enabled: !!supportedFeatures[Feature.SubDaos],
},
[]
)

Expand Down
24 changes: 13 additions & 11 deletions packages/stateful/components/dao/tabs/SubDaosTab.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
import { useQueryClient } from '@tanstack/react-query'

import {
SubDaosTab as StatelessSubDaosTab,
useCachedLoading,
useChain,
useDaoInfoContext,
useDaoNavHelpers,
} from '@dao-dao/stateless'
import { ActionKey, Feature } from '@dao-dao/types'
import { getDaoProposalSinglePrefill } from '@dao-dao/utils'

import { useActionForKey } from '../../../actions'
import { useMembership } from '../../../hooks'
import { subDaoInfosSelector } from '../../../recoil'
import { useCachedLoadingQuery, useMembership } from '../../../hooks'
import { daoQueries } from '../../../queries'
import { ButtonLink } from '../../ButtonLink'
import { DaoCard } from '../DaoCard'

export const SubDaosTab = () => {
const { chain_id: chainId } = useChain()
const daoInfo = useDaoInfoContext()
const { getDaoPath, getDaoProposalPath } = useDaoNavHelpers()

const { isMember = false } = useMembership(daoInfo)

const subDaos = useCachedLoading(
daoInfo.supportedFeatures[Feature.SubDaos]
? subDaoInfosSelector({ chainId, coreAddress: daoInfo.coreAddress })
: // Passing undefined here returns an infinite loading state, which is
// fine because it's never used.
undefined,
const queryClient = useQueryClient()
const subDaos = useCachedLoadingQuery(
{
...daoQueries.subDaoInfos(queryClient, {
chainId: daoInfo.chainId,
coreAddress: daoInfo.coreAddress,
}),
enabled: !!daoInfo.supportedFeatures[Feature.SubDaos],
},
[]
)

Expand Down
20 changes: 6 additions & 14 deletions packages/stateful/hooks/useCachedLoadingQuery.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { QueryKey, useQuery } from '@tanstack/react-query'
import { useQuery } from '@tanstack/react-query'
import { useMemo } from 'react'
import { useDeepCompareMemoize } from 'use-deep-compare-effect'

Expand All @@ -9,25 +9,17 @@ import { LoadingData } from '@dao-dao/types'
* Transform react-query query results into a cached loading object that
* components expect.
*/
export const useCachedLoadingQuery = <
TQueryFnData extends unknown,
TQueryKey extends QueryKey = QueryKey
>(
options: Omit<
Parameters<
typeof useQuery<TQueryFnData, Error, TQueryFnData, TQueryKey>
>[0],
'select'
>,
export const useCachedLoadingQuery = <T extends unknown>(
options: Omit<Parameters<typeof useQuery<T, Error, T, any>>[0], 'select'>,
/**
* Default value in case of an error.
*/
defaultValue: TQueryFnData,
defaultValue: T,
/**
* Optionally call a function on error.
*/
onError?: (error: Error) => void
): LoadingData<TQueryFnData> => {
): LoadingData<T> => {
const { isPending, isError, isRefetching, data, error } = useQuery(options)

const onErrorRef = useUpdatingRef(onError)
Expand All @@ -36,7 +28,7 @@ export const useCachedLoadingQuery = <
// passed as the default value.
const memoizedDefaultValue = useDeepCompareMemoize(defaultValue)

return useMemo((): LoadingData<TQueryFnData> => {
return useMemo((): LoadingData<T> => {
if (isPending) {
return {
loading: true,
Expand Down
68 changes: 61 additions & 7 deletions packages/stateful/queries/dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,7 @@ import { fetchProposalModules } from '../utils'
*/
export const fetchDaoProposalModules = async (
queryClient: QueryClient,
{
chainId,
coreAddress,
}: {
chainId: string
coreAddress: string
}
{ chainId, coreAddress }: DaoSource
): Promise<ProposalModule[]> => {
const coreVersion = parseContractVersion(
(
Expand Down Expand Up @@ -336,6 +330,44 @@ export const fetchDaoParentInfo = async (
throw new Error('Parent is not a DAO nor the chain governance module')
}

/**
* Fetch DAO info for all of a DAO's SubDAOs.
*/
export const fetchSubDaoInfos = async (
queryClient: QueryClient,
{ chainId, coreAddress }: DaoSource
): Promise<DaoInfo[]> => {
const subDaos = await queryClient.fetchQuery(
daoDaoCoreQueries.listAllSubDaos(queryClient, {
chainId,
contractAddress: coreAddress,
})
)

return await Promise.all(
subDaos.map(({ addr }) =>
queryClient.fetchQuery(
daoQueries.info(queryClient, { chainId, coreAddress: addr })
)
)
)
}

/**
* Fetch DAO info for all of a chain's SubDAOs.
*/
export const fetchChainSubDaoInfos = (
queryClient: QueryClient,
{ chainId }: { chainId: string }
): Promise<DaoInfo[]> =>
Promise.all(
(getSupportedChainConfig(chainId)?.subDaos || []).map((coreAddress) =>
queryClient.fetchQuery(
daoQueries.info(queryClient, { chainId, coreAddress })
)
)
)

export const daoQueries = {
/**
* Fetch DAO proposal modules.
Expand Down Expand Up @@ -371,4 +403,26 @@ export const daoQueries = {
queryKey: ['dao', 'parentInfo', options],
queryFn: () => fetchDaoParentInfo(queryClient, options),
}),
/**
* Fetch DAO info for all of a DAO's SubDAOs.
*/
subDaoInfos: (
queryClient: QueryClient,
options: Parameters<typeof fetchSubDaoInfos>[1]
) =>
queryOptions({
queryKey: ['dao', 'subDaoInfos', options],
queryFn: () => fetchSubDaoInfos(queryClient, options),
}),
/**
* Fetch DAO info for all of a chain's SubDAOs.
*/
chainSubDaoInfos: (
queryClient: QueryClient,
options: Parameters<typeof fetchChainSubDaoInfos>[1]
) =>
queryOptions({
queryKey: ['dao', 'chainSubDaoInfos', options],
queryFn: () => fetchChainSubDaoInfos(queryClient, options),
}),
}
52 changes: 0 additions & 52 deletions packages/stateful/recoil/selectors/dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,58 +156,6 @@ export const daoCardLazyDataSelector = selectorFamily<
},
})

export const subDaoInfosSelector = selectorFamily<
DaoInfo[],
WithChainId<{ coreAddress: string }>
>({
key: 'subDaoInfos',
get:
({ coreAddress: contractAddress, chainId }) =>
({ get }) => {
const subDaos = get(
DaoCoreV2Selectors.listAllSubDaosSelector({
contractAddress,
chainId,
})
)

return get(
waitForAll(
subDaos.map(({ chainId, addr }) =>
daoInfoSelector({
chainId,
coreAddress: addr,
})
)
)
)
},
})

export const chainSubDaoInfosSelector = selectorFamily<
DaoInfo[],
{ chainId: string }
>({
key: 'chainSubDaoInfos',
get:
({ chainId }) =>
({ get }) => {
const subDaos = getSupportedChainConfig(chainId)?.subDaos || []
return subDaos.length
? get(
waitForAll(
subDaos.map((coreAddress) =>
daoInfoSelector({
chainId,
coreAddress,
})
)
)
)
: []
},
})

export const followingDaosWithProposalModulesSelector = selectorFamily<
(DaoSource & {
proposalModules: ProposalModule[]
Expand Down

0 comments on commit f75da18

Please sign in to comment.