diff --git a/common/recommended-contracts.ts b/common/recommended-contracts.ts index eb5cf4a7..be50c5cd 100644 --- a/common/recommended-contracts.ts +++ b/common/recommended-contracts.ts @@ -5,6 +5,8 @@ import { ClickEvent } from './tracking' import { filterDefined } from './util/array' import { addObjects } from './util/object' +export const MAX_FEED_CONTRACTS = 75 + export const getRecommendedContracts = ( contractsById: { [contractId: string]: Contract }, yourBetOnContractIds: string[] @@ -146,6 +148,8 @@ export function getContractScore( contract: Contract, wordScores: { [word: string]: number } ) { + if (Object.keys(wordScores).length === 0) return 1 + const wordFrequency = contractToWordFrequency(contract) const score = _.sumBy(Object.keys(wordFrequency), (word) => { const wordFreq = wordFrequency[word] ?? 0 diff --git a/functions/src/update-user-feed.ts b/functions/src/update-user-feed.ts index 80dc292d..57a15bb6 100644 --- a/functions/src/update-user-feed.ts +++ b/functions/src/update-user-feed.ts @@ -14,13 +14,14 @@ import { import { Bet } from '../../common/bet' import { Comment } from '../../common/comment' import { User } from '../../common/user' -import { getContractScore } from '../../common/recommended-contracts' +import { + getContractScore, + MAX_FEED_CONTRACTS, +} from '../../common/recommended-contracts' import { callCloudFunction } from './call-cloud-function' const firestore = admin.firestore() -const MAX_FEED_CONTRACTS = 75 - export const updateFeed = functions.pubsub .schedule('every 60 minutes') .onRun(async () => { diff --git a/web/hooks/use-algo-feed.ts b/web/hooks/use-algo-feed.ts index f424d40f..b8cfb7a2 100644 --- a/web/hooks/use-algo-feed.ts +++ b/web/hooks/use-algo-feed.ts @@ -8,6 +8,10 @@ import { trackLatency } from '../lib/firebase/tracking' import { User } from '../../common/user' import { getUserFeed } from '../lib/firebase/users' import { useUpdatedContracts } from './use-contracts' +import { + getRecentBetsAndComments, + getTopWeeklyContracts, +} from '../lib/firebase/contracts' type feed = { contract: Contract @@ -23,7 +27,9 @@ export const useAlgoFeed = (user: User | null | undefined) => { useEffect(() => { if (user) { getUserFeed(user.id).then((feed) => { - setFeed(feed) + if (feed.length === 0) { + getDefaultFeed().then((feed) => setFeed(feed)) + } else setFeed(feed) trackLatency('feed', getTime()) console.log('feed load time', getTime()) @@ -44,3 +50,11 @@ const useUpdateFeed = (feed: feed | undefined) => { })) : undefined } + +const getDefaultFeed = async () => { + const contracts = await getTopWeeklyContracts() + const feed = await Promise.all( + contracts.map((c) => getRecentBetsAndComments(c)) + ) + return feed +} diff --git a/web/hooks/use-contracts.ts b/web/hooks/use-contracts.ts index 3135d522..0402613f 100644 --- a/web/hooks/use-contracts.ts +++ b/web/hooks/use-contracts.ts @@ -94,6 +94,8 @@ export const useUpdatedContracts = (contracts: Contract[] | undefined) => { }) }) + triggerUpdate((n) => n + 1) + return () => { disposes.forEach((dispose) => dispose()) } diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts index f41d6902..f1ab7bba 100644 --- a/web/lib/firebase/contracts.ts +++ b/web/lib/firebase/contracts.ts @@ -23,6 +23,9 @@ import { createRNG, shuffle } from '../../../common/util/random' import { getCpmmProbability } from '../../../common/calculate-cpmm' import { formatMoney, formatPercent } from '../../../common/util/format' import { DAY_MS } from '../../../common/util/time' +import { MAX_FEED_CONTRACTS } from '../../../common/recommended-contracts' +import { Bet } from '../../../common/bet' +import { Comment } from '../../../common/comment' export type { Contract } export function contractPath(contract: Contract) { @@ -231,6 +234,16 @@ export async function getHotContracts() { ) } +const topWeeklyQuery = query( + contractCollection, + where('isResolved', '==', false), + orderBy('volume7Days', 'desc'), + limit(MAX_FEED_CONTRACTS) +) +export async function getTopWeeklyContracts() { + return await getValues(topWeeklyQuery) +} + const closingSoonQuery = query( contractCollection, where('isResolved', '==', false), @@ -276,3 +289,33 @@ export async function getDailyContracts( return contractsByDay } + +export async function getRecentBetsAndComments(contract: Contract) { + const contractDoc = doc(db, 'contracts', contract.id) + + const [recentBets, recentComments] = await Promise.all([ + getValues( + query( + collection(contractDoc, 'bets'), + where('createdTime', '>', Date.now() - DAY_MS), + orderBy('createdTime', 'desc'), + limit(1) + ) + ), + + getValues( + query( + collection(contractDoc, 'comments'), + where('createdTime', '>', Date.now() - 3 * DAY_MS), + orderBy('createdTime', 'desc'), + limit(3) + ) + ), + ]) + + return { + contract, + recentBets, + recentComments, + } +}