From f80ef1cd34216a58406d0fed9a945ee286c0a8a6 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Wed, 2 Feb 2022 00:40:46 -0600 Subject: [PATCH] Add hot markets to home feed --- web/lib/firebase/bets.ts | 14 ++++++++++++++ web/pages/activity.tsx | 23 +++++++++++++++++++++++ web/pages/fold/[...slugs]/index.tsx | 1 + web/pages/home.tsx | 11 ++++++++--- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/web/lib/firebase/bets.ts b/web/lib/firebase/bets.ts index 982d4f89..717551b4 100644 --- a/web/lib/firebase/bets.ts +++ b/web/lib/firebase/bets.ts @@ -4,6 +4,7 @@ import { query, onSnapshot, where, + orderBy, } from 'firebase/firestore' import _ from 'lodash' @@ -23,6 +24,19 @@ export async function listAllBets(contractId: string) { return bets } +const DAY_IN_MS = 24 * 60 * 60 * 1000 + +// Define "recent" as "<24 hours ago" for now +const recentBetsQuery = query( + collectionGroup(db, 'bets'), + where('createdTime', '>', Date.now() - DAY_IN_MS), + orderBy('createdTime', 'desc') +) + +export async function getRecentBets() { + return getValues(recentBetsQuery) +} + export function listenForBets( contractId: string, setBets: (bets: Bet[]) => void diff --git a/web/pages/activity.tsx b/web/pages/activity.tsx index e59aae32..b740d580 100644 --- a/web/pages/activity.tsx +++ b/web/pages/activity.tsx @@ -7,6 +7,7 @@ import { Col } from '../components/layout/col' import { Bet } from '../../common/bet' const MAX_ACTIVE_CONTRACTS = 75 +const MAX_HOT_MARKETS = 10 // This does NOT include comment times, since those aren't part of the contract atm. // TODO: Maybe store last activity time directly in the contract? @@ -23,9 +24,11 @@ function lastActivityTime(contract: Contract) { // - Comment on a market // - New market created // - Market resolved +// - Markets with most betting in last 24 hours export function findActiveContracts( allContracts: Contract[], recentComments: Comment[], + recentBets: Bet[], daysAgo = 3 ) { const idToActivityTime = new Map() @@ -56,6 +59,26 @@ export function findActiveContracts( } } + // Add recent top-trading contracts, ordered by last bet. + const contractBets = _.groupBy(recentBets, (bet) => bet.contractId) + const contractTotalBets = _.mapValues(contractBets, (bets) => + _.sumBy(bets, (bet) => bet.amount) + ) + const topTradedContracts = _.sortBy( + _.toPairs(contractTotalBets), + ([_, total]) => -1 * total + ) + .map(([id]) => contractsById.get(id) as Contract) + .slice(0, MAX_HOT_MARKETS) + + for (const contract of topTradedContracts) { + const bet = recentBets.find((bet) => bet.contractId === contract.id) + if (bet) { + contracts.push(contract) + record(contract.id, bet.createdTime) + } + } + contracts = _.uniqBy(contracts, (c) => c.id) contracts = contracts.filter((contract) => contract.visibility === 'public') contracts = _.sortBy(contracts, (c) => -(idToActivityTime.get(c.id) ?? 0)) diff --git a/web/pages/fold/[...slugs]/index.tsx b/web/pages/fold/[...slugs]/index.tsx index 30a7edba..2776f6c8 100644 --- a/web/pages/fold/[...slugs]/index.tsx +++ b/web/pages/fold/[...slugs]/index.tsx @@ -50,6 +50,7 @@ export async function getStaticProps(props: { params: { slugs: string[] } }) { let activeContracts = findActiveContracts( contracts, _.flatten(contractComments), + [], 365 ) const [resolved, unresolved] = _.partition( diff --git a/web/pages/home.tsx b/web/pages/home.tsx index 54c2af24..840e1746 100644 --- a/web/pages/home.tsx +++ b/web/pages/home.tsx @@ -10,7 +10,7 @@ import { Comment, listAllComments, } from '../lib/firebase/comments' -import { Bet, listAllBets } from '../lib/firebase/bets' +import { Bet, getRecentBets, listAllBets } from '../lib/firebase/bets' import FeedCreate from '../components/feed-create' import { Spacer } from '../components/layout/spacer' import { Col } from '../components/layout/col' @@ -18,12 +18,17 @@ import { useUser } from '../hooks/use-user' import { useContracts } from '../hooks/use-contracts' export async function getStaticProps() { - const [contracts, recentComments] = await Promise.all([ + const [contracts, recentComments, recentBets] = await Promise.all([ listAllContracts().catch((_) => []), getRecentComments().catch(() => []), + getRecentBets().catch(() => []), ]) - const activeContracts = findActiveContracts(contracts, recentComments) + const activeContracts = findActiveContracts( + contracts, + recentComments, + recentBets + ) const activeContractBets = await Promise.all( activeContracts.map((contract) => listAllBets(contract.id).catch((_) => [])) )