diff --git a/web/components/bets-list.tsx b/web/components/bets-list.tsx index 8c90056b..3270408b 100644 --- a/web/components/bets-list.tsx +++ b/web/components/bets-list.tsx @@ -1,14 +1,5 @@ import Link from 'next/link' -import { - Dictionary, - keyBy, - groupBy, - mapValues, - sortBy, - partition, - sumBy, - uniq, -} from 'lodash' +import { keyBy, groupBy, mapValues, sortBy, partition, sumBy } from 'lodash' import dayjs from 'dayjs' import { useEffect, useMemo, useState } from 'react' import clsx from 'clsx' @@ -28,7 +19,6 @@ import { Contract, contractPath, getBinaryProbPercent, - getContractFromId, } from 'web/lib/firebase/contracts' import { Row } from './layout/row' import { UserLink } from './user-page' @@ -56,9 +46,9 @@ import { SellSharesModal } from './sell-modal' import { useUnfilledBets } from 'web/hooks/use-bets' import { LimitBet } from 'common/bet' import { floatingEqual } from 'common/util/math' -import { filterDefined } from 'common/util/array' import { Pagination } from './pagination' import { LimitOrderTable } from './limit-bets' +import { useUserBetContracts } from 'web/hooks/use-contracts' type BetSort = 'newest' | 'profit' | 'closeTime' | 'value' type BetFilter = 'open' | 'limit_bet' | 'sold' | 'closed' | 'resolved' | 'all' @@ -73,9 +63,6 @@ export function BetsList(props: { user: User }) { const isYourBets = user.id === signedInUser?.id const hideBetsBefore = isYourBets ? 0 : JUNE_1_2022 const userBets = useUserBets(user.id) - const [contractsById, setContractsById] = useState< - Dictionary | undefined - >() // Hide bets before 06-01-2022 if this isn't your own profile // NOTE: This means public profits also begin on 06-01-2022 as well. @@ -87,14 +74,10 @@ export function BetsList(props: { user: User }) { [userBets, hideBetsBefore] ) - useEffect(() => { - if (bets) { - const contractIds = uniq(bets.map((b) => b.contractId)) - Promise.all(contractIds.map(getContractFromId)).then((contracts) => { - setContractsById(keyBy(filterDefined(contracts), 'id')) - }) - } - }, [bets]) + const contractList = useUserBetContracts(user.id) + const contractsById = useMemo(() => { + return contractList ? keyBy(contractList, 'id') : undefined + }, [contractList]) const [sort, setSort] = useState('newest') const [filter, setFilter] = useState('open') diff --git a/web/hooks/use-contracts.ts b/web/hooks/use-contracts.ts index efe30d38..f277a209 100644 --- a/web/hooks/use-contracts.ts +++ b/web/hooks/use-contracts.ts @@ -1,3 +1,4 @@ +import { useFirestoreQueryData } from '@react-query-firebase/firestore' import { isEqual } from 'lodash' import { useEffect, useRef, useState } from 'react' import { @@ -8,6 +9,7 @@ import { listenForHotContracts, listenForInactiveContracts, listenForNewContracts, + getUserBetContractsQuery, } from 'web/lib/firebase/contracts' export const useContracts = () => { @@ -89,3 +91,15 @@ export const useUpdatedContracts = (contracts: Contract[] | undefined) => { ? contracts.map((c) => contractDict.current[c.id]) : undefined } + +export const useUserBetContracts = (userId: string) => { + const result = useFirestoreQueryData( + ['contracts', 'bets', userId], + getUserBetContractsQuery(userId), + { subscribe: true, includeMetadataChanges: true }, + // Temporary workaround for react-query bug: + // https://github.com/invertase/react-query-firebase/issues/25 + { refetchOnMount: 'always' } + ) + return result.data +} diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts index d3f18f54..2751e9bb 100644 --- a/web/lib/firebase/contracts.ts +++ b/web/lib/firebase/contracts.ts @@ -6,6 +6,7 @@ import { getDocs, limit, orderBy, + Query, query, setDoc, startAfter, @@ -156,6 +157,13 @@ export function listenForUserContracts( return listenForValues(q, setContracts) } +export function getUserBetContractsQuery(userId: string) { + return query( + contracts, + where('uniqueBettorIds', 'array-contains', userId) + ) as Query +} + const activeContractsQuery = query( contracts, where('isResolved', '==', false),