Feed updates: 1. Order by any bet instead of top 10 & comments 2. No resolved contracts 3. Show loading while fetching recent bets clientside so order preserved 4. Don't change order from new bets

This commit is contained in:
James Grugett 2022-02-25 01:59:53 -06:00
parent 8305ecd667
commit cd590031e7
5 changed files with 34 additions and 33 deletions

View File

@ -9,8 +9,6 @@ import { Comment, getRecentComments } from '../lib/firebase/comments'
import { Contract, listAllContracts } from '../lib/firebase/contracts' import { Contract, listAllContracts } from '../lib/firebase/contracts'
import { listAllFolds } from '../lib/firebase/folds' import { listAllFolds } from '../lib/firebase/folds'
import { findActiveContracts } from '../pages/activity' import { findActiveContracts } from '../pages/activity'
import { useRecentBets } from './use-bets'
import { useRecentComments } from './use-comments'
import { useContracts } from './use-contracts' import { useContracts } from './use-contracts'
import { useFollowedFolds } from './use-fold' import { useFollowedFolds } from './use-fold'
import { useUserBetContracts } from './use-user-bets' import { useUserBetContracts } from './use-user-bets'
@ -39,9 +37,8 @@ export const useActiveContracts = (
}, },
user: User | undefined | null user: User | undefined | null
) => { ) => {
const { recentBets, recentComments } = props
const contracts = useContracts() ?? props.contracts const contracts = useContracts() ?? props.contracts
const recentBets = useRecentBets() ?? props.recentBets
const recentComments = useRecentComments() ?? props.recentComments
const followedFoldIds = useFollowedFolds(user) const followedFoldIds = useFollowedFolds(user)
@ -82,8 +79,7 @@ export const useActiveContracts = (
const activeContracts = findActiveContracts( const activeContracts = findActiveContracts(
feedContracts, feedContracts,
recentComments, recentComments,
recentBets, recentBets
365
) )
const betsByContract = _.groupBy(recentBets, (bet) => bet.contractId) const betsByContract = _.groupBy(recentBets, (bet) => bet.contractId)

View File

@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'
import { Contract } from '../../common/contract' import { Contract } from '../../common/contract'
import { import {
Bet, Bet,
getRecentBets,
listenForBets, listenForBets,
listenForRecentBets, listenForRecentBets,
withoutAnteBets, withoutAnteBets,
@ -36,3 +37,11 @@ export const useRecentBets = () => {
useEffect(() => listenForRecentBets(setRecentBets), []) useEffect(() => listenForRecentBets(setRecentBets), [])
return recentBets return recentBets
} }
export const useGetRecentBets = () => {
const [recentBets, setRecentBets] = useState<Bet[] | undefined>()
useEffect(() => {
getRecentBets().then(setRecentBets)
}, [])
return recentBets
}

View File

@ -5,10 +5,8 @@ import { Contract } from '../lib/firebase/contracts'
import { Comment } from '../lib/firebase/comments' import { Comment } from '../lib/firebase/comments'
import { Col } from '../components/layout/col' import { Col } from '../components/layout/col'
import { Bet } from '../../common/bet' import { Bet } from '../../common/bet'
import { filterDefined } from '../../common/util/array'
const MAX_ACTIVE_CONTRACTS = 75 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. // 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? // TODO: Maybe store last activity time directly in the contract?
@ -29,8 +27,7 @@ function lastActivityTime(contract: Contract) {
export function findActiveContracts( export function findActiveContracts(
allContracts: Contract[], allContracts: Contract[],
recentComments: Comment[], recentComments: Comment[],
recentBets: Bet[], recentBets: Bet[]
daysAgo = 3
) { ) {
const idToActivityTime = new Map<string, number>() const idToActivityTime = new Map<string, number>()
function record(contractId: string, time: number) { function record(contractId: string, time: number) {
@ -44,11 +41,9 @@ export function findActiveContracts(
// Find contracts with activity in the last 3 days // Find contracts with activity in the last 3 days
const DAY_IN_MS = 24 * 60 * 60 * 1000 const DAY_IN_MS = 24 * 60 * 60 * 1000
for (const contract of allContracts || []) { for (const contract of allContracts || []) {
if (lastActivityTime(contract) > Date.now() - daysAgo * DAY_IN_MS) {
contracts.push(contract) contracts.push(contract)
record(contract.id, lastActivityTime(contract)) record(contract.id, lastActivityTime(contract))
} }
}
// Add every contract that had a recent comment, too // Add every contract that had a recent comment, too
const contractsById = new Map(allContracts.map((c) => [c.id, c])) const contractsById = new Map(allContracts.map((c) => [c.id, c]))
@ -60,29 +55,24 @@ export function findActiveContracts(
} }
} }
// Add recent top-trading contracts, ordered by last bet. // Add contracts by last bet time.
const contractBets = _.groupBy(recentBets, (bet) => bet.contractId) const contractBets = _.groupBy(recentBets, (bet) => bet.contractId)
const contractTotalBets = _.mapValues(contractBets, (bets) => const contractMostRecentBet = _.mapValues(
_.sumBy(bets, (bet) => bet.amount) contractBets,
(bets) => _.maxBy(bets, (bet) => bet.createdTime) as Bet
) )
const sortedPairs = _.sortBy( for (const bet of Object.values(contractMostRecentBet)) {
_.toPairs(contractTotalBets), const contract = contractsById.get(bet.id)
([_, total]) => -1 * total if (contract) {
)
const topTradedContracts = filterDefined(
sortedPairs.map(([id]) => contractsById.get(id))
).slice(0, MAX_HOT_MARKETS)
for (const contract of topTradedContracts) {
const bet = recentBets.find((bet) => bet.contractId === contract.id)
if (bet) {
contracts.push(contract) contracts.push(contract)
record(contract.id, bet.createdTime) record(contract.id, bet.createdTime)
} }
} }
contracts = _.uniqBy(contracts, (c) => c.id) contracts = _.uniqBy(contracts, (c) => c.id)
contracts = contracts.filter((contract) => contract.visibility === 'public') contracts = contracts.filter(
(contract) => contract.visibility === 'public' && !contract.isResolved
)
contracts = _.sortBy(contracts, (c) => -(idToActivityTime.get(c.id) ?? 0)) contracts = _.sortBy(contracts, (c) => -(idToActivityTime.get(c.id) ?? 0))
return contracts.slice(0, MAX_ACTIVE_CONTRACTS) return contracts.slice(0, MAX_ACTIVE_CONTRACTS)
} }

View File

@ -67,8 +67,7 @@ export async function getStaticProps(props: { params: { slugs: string[] } }) {
let activeContracts = findActiveContracts( let activeContracts = findActiveContracts(
contracts, contracts,
_.flatten(contractComments), _.flatten(contractComments),
_.flatten(contractRecentBets), _.flatten(contractRecentBets)
365
) )
const [resolved, unresolved] = _.partition( const [resolved, unresolved] = _.partition(
activeContracts, activeContracts,

View File

@ -19,6 +19,7 @@ import {
getAllContractInfo, getAllContractInfo,
useActiveContracts, useActiveContracts,
} from '../hooks/use-active-contracts' } from '../hooks/use-active-contracts'
import { useGetRecentBets } from '../hooks/use-bets'
export async function getStaticProps() { export async function getStaticProps() {
const contractInfo = await getAllContractInfo() const contractInfo = await getAllContractInfo()
@ -35,14 +36,20 @@ const Home = (props: {
recentBets: Bet[] recentBets: Bet[]
recentComments: Comment[] recentComments: Comment[]
}) => { }) => {
const { contracts, folds, recentComments } = props
const user = useUser() const user = useUser()
const recentBets = useGetRecentBets()
const { const {
activeContracts, activeContracts,
activeBets, activeBets,
activeComments, activeComments,
initialFollowedFoldSlugs, initialFollowedFoldSlugs,
} = useActiveContracts(props, user) } = useActiveContracts(
{ contracts, folds, recentBets: recentBets ?? [], recentComments },
user
)
if (user === null) { if (user === null) {
Router.replace('/') Router.replace('/')
@ -71,7 +78,7 @@ const Home = (props: {
</Row> </Row>
</Col> </Col>
{activeContracts ? ( {activeContracts && recentBets ? (
<ActivityFeed <ActivityFeed
contracts={activeContracts} contracts={activeContracts}
contractBets={activeBets} contractBets={activeBets}