diff --git a/web/hooks/use-contracts.ts b/web/hooks/use-contracts.ts index 88fc8f80..ed25783d 100644 --- a/web/hooks/use-contracts.ts +++ b/web/hooks/use-contracts.ts @@ -5,6 +5,7 @@ import { listenForContracts, listenForHotContracts, } from '../lib/firebase/contracts' +import { listenForTaggedContracts } from '../lib/firebase/folds' export const useContracts = () => { const [contracts, setContracts] = useState() @@ -16,6 +17,21 @@ export const useContracts = () => { return contracts } +export const useTaggedContracts = (tags: string[] | undefined) => { + const [contracts, setContracts] = useState( + tags && tags.length === 0 ? [] : undefined + ) + const tagsKey = tags?.map((tag) => tag.toLowerCase()).join(',') ?? '' + + useEffect(() => { + if (!tags || tags.length === 0) return + return listenForTaggedContracts(tags, setContracts) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [tagsKey]) + + return contracts +} + export const useHotContracts = () => { const [hotContracts, setHotContracts] = useState() diff --git a/web/lib/firebase/folds.ts b/web/lib/firebase/folds.ts index d760fc16..c5c172f1 100644 --- a/web/lib/firebase/folds.ts +++ b/web/lib/firebase/folds.ts @@ -45,6 +45,17 @@ export async function getFoldBySlug(slug: string) { return folds.length === 0 ? null : folds[0] } +function contractsByTagsQuery(tags: string[]) { + return query( + contractCollection, + where( + 'lowercaseTags', + 'array-contains-any', + tags.map((tag) => tag.toLowerCase()) + ) + ) +} + export async function getFoldContracts(fold: Fold) { const { tags, @@ -56,18 +67,7 @@ export async function getFoldContracts(fold: Fold) { const [tagsContracts, includedContracts] = await Promise.all([ // TODO: if tags.length > 10, execute multiple parallel queries - tags.length > 0 - ? getValues( - query( - contractCollection, - where( - 'lowercaseTags', - 'array-contains-any', - tags.map((tag) => tag.toLowerCase()) - ) - ) - ) - : [], + tags.length > 0 ? getValues(contractsByTagsQuery(tags)) : [], // TODO: if contractIds.length > 10, execute multiple parallel queries contractIds.length > 0 @@ -97,6 +97,13 @@ export async function getFoldContracts(fold: Fold) { return [...approvedContracts, ...includedContracts] } +export function listenForTaggedContracts( + tags: string[], + setContracts: (contracts: Contract[]) => void +) { + return listenForValues(contractsByTagsQuery(tags), setContracts) +} + export function listenForFold( foldId: string, setFold: (fold: Fold | null) => void diff --git a/web/lib/firebase/init.ts b/web/lib/firebase/init.ts index 86c0648a..c44f72ea 100644 --- a/web/lib/firebase/init.ts +++ b/web/lib/firebase/init.ts @@ -2,8 +2,8 @@ import { getFirestore } from '@firebase/firestore' import { initializeApp, getApps, getApp } from 'firebase/app' // TODO: Reenable this when we have a way to set the Firebase db in dev -// export const isProd = process.env.NODE_ENV === 'production' -export const isProd = true +export const isProd = process.env.NODE_ENV === 'production' +// export const isProd = true const firebaseConfig = isProd ? { diff --git a/web/pages/fold/[...slugs]/index.tsx b/web/pages/fold/[...slugs]/index.tsx index d5f905a4..eba41837 100644 --- a/web/pages/fold/[...slugs]/index.tsx +++ b/web/pages/fold/[...slugs]/index.tsx @@ -34,6 +34,7 @@ import Custom404 from '../../404' import { FollowFoldButton } from '../../../components/follow-fold-button' import FeedCreate from '../../../components/feed-create' import { SEO } from '../../../components/SEO' +import { useTaggedContracts } from '../../../hooks/use-contracts' export async function getStaticProps(props: { params: { slugs: string[] } }) { const { slugs } = props.params @@ -133,8 +134,6 @@ export default function FoldPage(props: { }) { const { curator, - contracts, - activeContracts, activeContractBets, activeContractComments, topTraders, @@ -157,6 +156,16 @@ export default function FoldPage(props: { const user = useUser() const isCurator = user && fold && user.id === fold.curatorId + const taggedContracts = useTaggedContracts(fold?.tags) ?? props.contracts + const contractsMap = _.fromPairs( + taggedContracts.map((contract) => [contract.id, contract]) + ) + + const contracts = props.contracts.map((contract) => contractsMap[contract.id]) + const activeContracts = props.activeContracts.map( + (contract) => contractsMap[contract.id] + ) + if (fold === null || !foldSubpages.includes(page) || slugs[2]) { return }