diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts index 6dc2ee3e..d3f18f54 100644 --- a/web/lib/firebase/contracts.ts +++ b/web/lib/firebase/contracts.ts @@ -12,7 +12,7 @@ import { updateDoc, where, } from 'firebase/firestore' -import { sortBy, sum } from 'lodash' +import { sortBy, sum, uniqBy } from 'lodash' import { coll, getValues, listenForValue, listenForValues } from './utils' import { BinaryContract, Contract } from 'common/contract' @@ -305,7 +305,7 @@ export const getRandTopCreatorContracts = async ( where('isResolved', '==', false), where('creatorId', '==', creatorId), orderBy('popularityScore', 'desc'), - limit(Math.max(count * 2, 15)) + limit(count * 2) ) const data = await getValues(creatorContractsQuery) const open = data @@ -315,6 +315,44 @@ export const getRandTopCreatorContracts = async ( return chooseRandomSubset(open, count) } +export const getRandTopGroupContracts = async ( + groupSlug: string, + count: number, + excluding: string[] = [] +) => { + const creatorContractsQuery = query( + contracts, + where('groupSlugs', 'array-contains', groupSlug), + where('isResolved', '==', false), + orderBy('popularityScore', 'desc'), + limit(count * 2) + ) + const data = await getValues(creatorContractsQuery) + const open = data + .filter((c) => c.closeTime && c.closeTime > Date.now()) + .filter((c) => !excluding.includes(c.id)) + + return chooseRandomSubset(open, count) +} + +export const getRecommendedContracts = async ( + contract: Contract, + count: number +) => { + const { creatorId, groupSlugs, id } = contract + + const [userContracts, groupContracts] = await Promise.all([ + getRandTopCreatorContracts(creatorId, count, [id]), + groupSlugs && groupSlugs[0] + ? getRandTopGroupContracts(groupSlugs[0], count, [id]) + : [], + ]) + + const combined = uniqBy([...userContracts, ...groupContracts], (c) => c.id) + + return chooseRandomSubset(combined, count) +} + export async function getRecentBetsAndComments(contract: Contract) { const contractDoc = doc(contracts, contract.id) diff --git a/web/pages/[username]/[contractSlug].tsx b/web/pages/[username]/[contractSlug].tsx index 026597e3..1561eb01 100644 --- a/web/pages/[username]/[contractSlug].tsx +++ b/web/pages/[username]/[contractSlug].tsx @@ -11,7 +11,7 @@ import { Spacer } from 'web/components/layout/spacer' import { Contract, getContractFromSlug, - getRandTopCreatorContracts, + getRecommendedContracts, tradingAllowed, } from 'web/lib/firebase/contracts' import { SEO } from 'web/components/SEO' @@ -40,8 +40,8 @@ import { ContractLeaderboard, ContractTopTrades, } from 'web/components/contract/contract-leaderboard' -import { Subtitle } from 'web/components/subtitle' import { ContractsGrid } from 'web/components/contract/contracts-grid' +import { Title } from 'web/components/title' export const getStaticProps = fromPropz(getStaticPropz) export async function getStaticPropz(props: { @@ -54,9 +54,7 @@ export async function getStaticPropz(props: { const [bets, comments, recommendedContracts] = await Promise.all([ contractId ? listAllBets(contractId) : [], contractId ? listAllComments(contractId) : [], - contract - ? getRandTopCreatorContracts(contract.creatorId, 4, [contract?.id]) - : [], + contract ? getRecommendedContracts(contract, 6) : [], ]) return { @@ -190,12 +188,11 @@ export function ContractPageContent( props.recommendedContracts ) useEffect(() => { - if (recommendedContracts.length === 0) { - getRandTopCreatorContracts(contract.creatorId, 4, [contract.id]).then( - setRecommendedMarkets - ) + if (contract && recommendedContracts.length === 0) { + getRecommendedContracts(contract, 6).then(setRecommendedMarkets) } - }, [contract.id, contract.creatorId, recommendedContracts]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [contract.id, recommendedContracts]) const { isResolved, question, outcomeType } = contract @@ -282,8 +279,8 @@ export function ContractPageContent( {recommendedContracts.length > 0 && ( - - + + <ContractsGrid contracts={recommendedContracts} /> </Col> )}