Hook up client to use getFeed
This commit is contained in:
		
							parent
							
								
									db42761143
								
							
						
					
					
						commit
						50e77d5899
					
				| 
						 | 
					@ -8,31 +8,27 @@ import { useUser } from '../../hooks/use-user'
 | 
				
			||||||
import { ContractActivity } from './contract-activity'
 | 
					import { ContractActivity } from './contract-activity'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function ActivityFeed(props: {
 | 
					export function ActivityFeed(props: {
 | 
				
			||||||
  contracts: Contract[]
 | 
					  feed: {
 | 
				
			||||||
 | 
					    contract: Contract
 | 
				
			||||||
    recentBets: Bet[]
 | 
					    recentBets: Bet[]
 | 
				
			||||||
    recentComments: Comment[]
 | 
					    recentComments: Comment[]
 | 
				
			||||||
 | 
					  }[]
 | 
				
			||||||
  mode: 'only-recent' | 'abbreviated' | 'all'
 | 
					  mode: 'only-recent' | 'abbreviated' | 'all'
 | 
				
			||||||
  getContractPath?: (contract: Contract) => string
 | 
					  getContractPath?: (contract: Contract) => string
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  const { contracts, recentBets, recentComments, mode, getContractPath } = props
 | 
					  const { feed, mode, getContractPath } = props
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const user = useUser()
 | 
					  const user = useUser()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const groupedBets = _.groupBy(recentBets, (bet) => bet.contractId)
 | 
					 | 
				
			||||||
  const groupedComments = _.groupBy(
 | 
					 | 
				
			||||||
    recentComments,
 | 
					 | 
				
			||||||
    (comment) => comment.contractId
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <FeedContainer
 | 
					    <FeedContainer
 | 
				
			||||||
      contracts={contracts}
 | 
					      feed={feed}
 | 
				
			||||||
      renderContract={(contract) => (
 | 
					      renderItem={({ contract, recentBets, recentComments }) => (
 | 
				
			||||||
        <ContractActivity
 | 
					        <ContractActivity
 | 
				
			||||||
          user={user}
 | 
					          user={user}
 | 
				
			||||||
          contract={contract}
 | 
					          contract={contract}
 | 
				
			||||||
          bets={groupedBets[contract.id] ?? []}
 | 
					          bets={recentBets}
 | 
				
			||||||
          comments={groupedComments[contract.id] ?? []}
 | 
					          comments={recentComments}
 | 
				
			||||||
          mode={mode}
 | 
					          mode={mode}
 | 
				
			||||||
          contractPath={getContractPath ? getContractPath(contract) : undefined}
 | 
					          contractPath={getContractPath ? getContractPath(contract) : undefined}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
| 
						 | 
					@ -42,18 +38,26 @@ export function ActivityFeed(props: {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function FeedContainer(props: {
 | 
					function FeedContainer(props: {
 | 
				
			||||||
  contracts: Contract[]
 | 
					  feed: {
 | 
				
			||||||
  renderContract: (contract: Contract) => any
 | 
					    contract: Contract
 | 
				
			||||||
 | 
					    recentBets: Bet[]
 | 
				
			||||||
 | 
					    recentComments: Comment[]
 | 
				
			||||||
 | 
					  }[]
 | 
				
			||||||
 | 
					  renderItem: (item: {
 | 
				
			||||||
 | 
					    contract: Contract
 | 
				
			||||||
 | 
					    recentBets: Bet[]
 | 
				
			||||||
 | 
					    recentComments: Comment[]
 | 
				
			||||||
 | 
					  }) => any
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  const { contracts, renderContract } = props
 | 
					  const { feed, renderItem } = props
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Col className="items-center">
 | 
					    <Col className="items-center">
 | 
				
			||||||
      <Col className="w-full max-w-3xl">
 | 
					      <Col className="w-full max-w-3xl">
 | 
				
			||||||
        <Col className="w-full divide-y divide-gray-300 self-center bg-white">
 | 
					        <Col className="w-full divide-y divide-gray-300 self-center bg-white">
 | 
				
			||||||
          {contracts.map((contract) => (
 | 
					          {feed.map((item) => (
 | 
				
			||||||
            <div key={contract.id} className="py-6 px-2 sm:px-4">
 | 
					            <div key={item.contract.id} className="py-6 px-2 sm:px-4">
 | 
				
			||||||
              {renderContract(contract)}
 | 
					              {renderItem(item)}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          ))}
 | 
					          ))}
 | 
				
			||||||
        </Col>
 | 
					        </Col>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,205 +1,32 @@
 | 
				
			||||||
import _ from 'lodash'
 | 
					import _ from 'lodash'
 | 
				
			||||||
import { useState, useEffect, useMemo } from 'react'
 | 
					import { useState, useEffect } from 'react'
 | 
				
			||||||
import { Bet } from '../../common/bet'
 | 
					import { Bet } from '../../common/bet'
 | 
				
			||||||
import { Comment } from '../../common/comment'
 | 
					import { Comment } from '../../common/comment'
 | 
				
			||||||
import { Contract } from '../../common/contract'
 | 
					import { Contract } from '../../common/contract'
 | 
				
			||||||
import { User } from '../../common/user'
 | 
					 | 
				
			||||||
import { logInterpolation } from '../../common/util/math'
 | 
					 | 
				
			||||||
import { getRecommendedContracts } from '../../common/recommended-contracts'
 | 
					 | 
				
			||||||
import { useSeenContracts } from './use-seen-contracts'
 | 
					 | 
				
			||||||
import { useGetUserBetContractIds, useUserBetContracts } from './use-user-bets'
 | 
					 | 
				
			||||||
import { DAY_MS } from '../../common/util/time'
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  getProbability,
 | 
					 | 
				
			||||||
  getOutcomeProbability,
 | 
					 | 
				
			||||||
  getTopAnswer,
 | 
					 | 
				
			||||||
} from '../../common/calculate'
 | 
					 | 
				
			||||||
import { useTimeSinceFirstRender } from './use-time-since-first-render'
 | 
					import { useTimeSinceFirstRender } from './use-time-since-first-render'
 | 
				
			||||||
import { trackLatency } from '../lib/firebase/tracking'
 | 
					import { trackLatency } from '../lib/firebase/tracking'
 | 
				
			||||||
 | 
					import { getFeed } from '../lib/firebase/api-call'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MAX_FEED_CONTRACTS = 75
 | 
					export const useAlgoFeed = () => {
 | 
				
			||||||
 | 
					  const [feed, setFeed] = useState<
 | 
				
			||||||
export const useAlgoFeed = (
 | 
					    {
 | 
				
			||||||
  user: User | null | undefined,
 | 
					      contract: Contract
 | 
				
			||||||
  contracts: Contract[] | undefined,
 | 
					      recentBets: Bet[]
 | 
				
			||||||
  recentBets: Bet[] | undefined,
 | 
					      recentComments: Comment[]
 | 
				
			||||||
  recentComments: Comment[] | undefined
 | 
					    }[]
 | 
				
			||||||
) => {
 | 
					  >()
 | 
				
			||||||
  const initialContracts = useMemo(() => contracts, [!!contracts])
 | 
					 | 
				
			||||||
  const initialBets = useMemo(() => recentBets, [!!recentBets])
 | 
					 | 
				
			||||||
  const initialComments = useMemo(() => recentComments, [!!recentComments])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const yourBetContractIds = useGetUserBetContractIds(user?.id)
 | 
					 | 
				
			||||||
  // Update user bet contracts in local storage.
 | 
					 | 
				
			||||||
  useUserBetContracts(user?.id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const seenContracts = useSeenContracts()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const [algoFeed, setAlgoFeed] = useState<Contract[]>([])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const getTime = useTimeSinceFirstRender()
 | 
					  const getTime = useTimeSinceFirstRender()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    if (
 | 
					    getFeed().then(({ data }) => {
 | 
				
			||||||
      initialContracts &&
 | 
					      console.log('got data', data)
 | 
				
			||||||
      initialBets &&
 | 
					      setFeed(data.feed)
 | 
				
			||||||
      initialComments &&
 | 
					
 | 
				
			||||||
      yourBetContractIds
 | 
					 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
      const eligibleContracts = initialContracts.filter(
 | 
					 | 
				
			||||||
        (c) => !c.isResolved && (c.closeTime ?? Infinity) > Date.now()
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      const contracts = getAlgoFeed(
 | 
					 | 
				
			||||||
        eligibleContracts,
 | 
					 | 
				
			||||||
        initialBets,
 | 
					 | 
				
			||||||
        initialComments,
 | 
					 | 
				
			||||||
        yourBetContractIds,
 | 
					 | 
				
			||||||
        seenContracts
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      setAlgoFeed(contracts)
 | 
					 | 
				
			||||||
      trackLatency('feed', getTime())
 | 
					      trackLatency('feed', getTime())
 | 
				
			||||||
    }
 | 
					      console.log('feed load time', getTime())
 | 
				
			||||||
  }, [
 | 
					 | 
				
			||||||
    initialBets,
 | 
					 | 
				
			||||||
    initialComments,
 | 
					 | 
				
			||||||
    initialContracts,
 | 
					 | 
				
			||||||
    seenContracts,
 | 
					 | 
				
			||||||
    yourBetContractIds,
 | 
					 | 
				
			||||||
    getTime,
 | 
					 | 
				
			||||||
  ])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return algoFeed
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const getAlgoFeed = (
 | 
					 | 
				
			||||||
  contracts: Contract[],
 | 
					 | 
				
			||||||
  recentBets: Bet[],
 | 
					 | 
				
			||||||
  recentComments: Comment[],
 | 
					 | 
				
			||||||
  yourBetContractIds: string[],
 | 
					 | 
				
			||||||
  seenContracts: { [contractId: string]: number }
 | 
					 | 
				
			||||||
) => {
 | 
					 | 
				
			||||||
  const contractsById = _.keyBy(contracts, (c) => c.id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const recommended = getRecommendedContracts(contractsById, yourBetContractIds)
 | 
					 | 
				
			||||||
  const confidence = logInterpolation(0, 100, yourBetContractIds.length)
 | 
					 | 
				
			||||||
  const recommendedScores = _.fromPairs(
 | 
					 | 
				
			||||||
    recommended.map((c, index) => {
 | 
					 | 
				
			||||||
      const score = 1 - index / recommended.length
 | 
					 | 
				
			||||||
      const withConfidence = score * confidence + (1 - confidence)
 | 
					 | 
				
			||||||
      return [c.id, withConfidence] as [string, number]
 | 
					 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  )
 | 
					  }, [getTime])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const seenScores = _.fromPairs(
 | 
					  return feed
 | 
				
			||||||
    contracts.map(
 | 
					 | 
				
			||||||
      (c) => [c.id, getSeenContractsScore(c, seenContracts)] as [string, number]
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const activityScores = getContractsActivityScores(
 | 
					 | 
				
			||||||
    contracts,
 | 
					 | 
				
			||||||
    recentComments,
 | 
					 | 
				
			||||||
    recentBets,
 | 
					 | 
				
			||||||
    seenContracts
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const combinedScores = contracts.map((contract) => {
 | 
					 | 
				
			||||||
    const score =
 | 
					 | 
				
			||||||
      (recommendedScores[contract.id] ?? 0) *
 | 
					 | 
				
			||||||
      (seenScores[contract.id] ?? 0) *
 | 
					 | 
				
			||||||
      (activityScores[contract.id] ?? 0)
 | 
					 | 
				
			||||||
    return { contract, score }
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const sorted = _.sortBy(combinedScores, (c) => -c.score)
 | 
					 | 
				
			||||||
  return sorted.map((c) => c.contract).slice(0, MAX_FEED_CONTRACTS)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function getContractsActivityScores(
 | 
					 | 
				
			||||||
  contracts: Contract[],
 | 
					 | 
				
			||||||
  recentComments: Comment[],
 | 
					 | 
				
			||||||
  recentBets: Bet[],
 | 
					 | 
				
			||||||
  seenContracts: { [contractId: string]: number }
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  const contractBets = _.groupBy(recentBets, (bet) => bet.contractId)
 | 
					 | 
				
			||||||
  const contractMostRecentBet = _.mapValues(
 | 
					 | 
				
			||||||
    contractBets,
 | 
					 | 
				
			||||||
    (bets) => _.maxBy(bets, (bet) => bet.createdTime) as Bet
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const contractComments = _.groupBy(
 | 
					 | 
				
			||||||
    recentComments,
 | 
					 | 
				
			||||||
    (comment) => comment.contractId
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
  const contractMostRecentComment = _.mapValues(
 | 
					 | 
				
			||||||
    contractComments,
 | 
					 | 
				
			||||||
    (comments) => _.maxBy(comments, (c) => c.createdTime) as Comment
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const scoredContracts = contracts.map((contract) => {
 | 
					 | 
				
			||||||
    const { outcomeType } = contract
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const seenTime = seenContracts[contract.id]
 | 
					 | 
				
			||||||
    const lastCommentTime = contractMostRecentComment[contract.id]?.createdTime
 | 
					 | 
				
			||||||
    const hasNewComments =
 | 
					 | 
				
			||||||
      !seenTime || (lastCommentTime && lastCommentTime > seenTime)
 | 
					 | 
				
			||||||
    const newCommentScore = hasNewComments ? 1 : 0.5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const commentCount = contractComments[contract.id]?.length ?? 0
 | 
					 | 
				
			||||||
    const betCount = contractBets[contract.id]?.length ?? 0
 | 
					 | 
				
			||||||
    const activtyCount = betCount + commentCount * 5
 | 
					 | 
				
			||||||
    const activityCountScore =
 | 
					 | 
				
			||||||
      0.5 + 0.5 * logInterpolation(0, 200, activtyCount)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const lastBetTime =
 | 
					 | 
				
			||||||
      contractMostRecentBet[contract.id]?.createdTime ?? contract.createdTime
 | 
					 | 
				
			||||||
    const timeSinceLastBet = Date.now() - lastBetTime
 | 
					 | 
				
			||||||
    const daysAgo = timeSinceLastBet / DAY_MS
 | 
					 | 
				
			||||||
    const timeAgoScore = 1 - logInterpolation(0, 3, daysAgo)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let prob = 0.5
 | 
					 | 
				
			||||||
    if (outcomeType === 'BINARY') {
 | 
					 | 
				
			||||||
      prob = getProbability(contract)
 | 
					 | 
				
			||||||
    } else if (outcomeType === 'FREE_RESPONSE') {
 | 
					 | 
				
			||||||
      const topAnswer = getTopAnswer(contract)
 | 
					 | 
				
			||||||
      if (topAnswer)
 | 
					 | 
				
			||||||
        prob = Math.max(0.5, getOutcomeProbability(contract, topAnswer.id))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    const frac = 1 - Math.abs(prob - 0.5) ** 2 / 0.25
 | 
					 | 
				
			||||||
    const probScore = 0.5 + frac * 0.5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const score =
 | 
					 | 
				
			||||||
      newCommentScore * activityCountScore * timeAgoScore * probScore
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Map score to [0.5, 1] since no recent activty is not a deal breaker.
 | 
					 | 
				
			||||||
    const mappedScore = 0.5 + score / 2
 | 
					 | 
				
			||||||
    const newMappedScore = 0.75 + score / 4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const isNew = Date.now() < contract.createdTime + DAY_MS
 | 
					 | 
				
			||||||
    const activityScore = isNew ? newMappedScore : mappedScore
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return [contract.id, activityScore] as [string, number]
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return _.fromPairs(scoredContracts)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function getSeenContractsScore(
 | 
					 | 
				
			||||||
  contract: Contract,
 | 
					 | 
				
			||||||
  seenContracts: { [contractId: string]: number }
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  const lastSeen = seenContracts[contract.id]
 | 
					 | 
				
			||||||
  if (lastSeen === undefined) {
 | 
					 | 
				
			||||||
    return 1
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const daysAgo = (Date.now() - lastSeen) / DAY_MS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (daysAgo < 0.5) {
 | 
					 | 
				
			||||||
    const frac = logInterpolation(0, 0.5, daysAgo)
 | 
					 | 
				
			||||||
    return 0.5 * frac
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const frac = logInterpolation(0.5, 14, daysAgo)
 | 
					 | 
				
			||||||
  return 0.5 + 0.5 * frac
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,7 @@
 | 
				
			||||||
import { httpsCallable } from 'firebase/functions'
 | 
					import { httpsCallable } from 'firebase/functions'
 | 
				
			||||||
 | 
					import { Bet } from '../../../common/bet'
 | 
				
			||||||
 | 
					import { Comment } from '../../../common/comment'
 | 
				
			||||||
 | 
					import { Contract } from '../../../common/contract'
 | 
				
			||||||
import { Fold } from '../../../common/fold'
 | 
					import { Fold } from '../../../common/fold'
 | 
				
			||||||
import { User } from '../../../common/user'
 | 
					import { User } from '../../../common/user'
 | 
				
			||||||
import { randomString } from '../../../common/util/random'
 | 
					import { randomString } from '../../../common/util/random'
 | 
				
			||||||
| 
						 | 
					@ -71,3 +74,15 @@ export const addLiquidity = (data: { amount: number; contractId: string }) => {
 | 
				
			||||||
    .then((r) => r.data as { status: string })
 | 
					    .then((r) => r.data as { status: string })
 | 
				
			||||||
    .catch((e) => ({ status: 'error', message: e.message }))
 | 
					    .catch((e) => ({ status: 'error', message: e.message }))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getFeed = cloudFunction<
 | 
				
			||||||
 | 
					  undefined,
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    status: 'error' | 'success'
 | 
				
			||||||
 | 
					    feed: {
 | 
				
			||||||
 | 
					      contract: Contract
 | 
				
			||||||
 | 
					      recentBets: Bet[]
 | 
				
			||||||
 | 
					      recentComments: Comment[]
 | 
				
			||||||
 | 
					    }[]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					>('getFeed')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,30 +9,19 @@ import { Spacer } from '../components/layout/spacer'
 | 
				
			||||||
import { Col } from '../components/layout/col'
 | 
					import { Col } from '../components/layout/col'
 | 
				
			||||||
import { useUser } from '../hooks/use-user'
 | 
					import { useUser } from '../hooks/use-user'
 | 
				
			||||||
import { LoadingIndicator } from '../components/loading-indicator'
 | 
					import { LoadingIndicator } from '../components/loading-indicator'
 | 
				
			||||||
import { useRecentBets } from '../hooks/use-bets'
 | 
					 | 
				
			||||||
import { useActiveContracts } from '../hooks/use-contracts'
 | 
					 | 
				
			||||||
import { useRecentComments } from '../hooks/use-comments'
 | 
					 | 
				
			||||||
import { useAlgoFeed } from '../hooks/use-algo-feed'
 | 
					import { useAlgoFeed } from '../hooks/use-algo-feed'
 | 
				
			||||||
import { ContractPageContent } from './[username]/[contractSlug]'
 | 
					import { ContractPageContent } from './[username]/[contractSlug]'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Home = () => {
 | 
					const Home = () => {
 | 
				
			||||||
  const user = useUser()
 | 
					  const user = useUser()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const contracts = useActiveContracts()
 | 
					  const feed = useAlgoFeed()
 | 
				
			||||||
  const contractsDict = _.keyBy(contracts, 'id')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const recentBets = useRecentBets()
 | 
					 | 
				
			||||||
  const recentComments = useRecentComments()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const feedContracts = useAlgoFeed(user, contracts, recentBets, recentComments)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const updatedContracts = feedContracts.map(
 | 
					 | 
				
			||||||
    (contract) => contractsDict[contract.id] ?? contract
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const router = useRouter()
 | 
					  const router = useRouter()
 | 
				
			||||||
  const { u: username, s: slug } = router.query
 | 
					  const { u: username, s: slug } = router.query
 | 
				
			||||||
  const contract = feedContracts.find((c) => c.slug === slug)
 | 
					  const contract = feed?.find(
 | 
				
			||||||
 | 
					    ({ contract }) => contract.slug === slug
 | 
				
			||||||
 | 
					  )?.contract
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    // If the page initially loads with query params, redirect to the contract page.
 | 
					    // If the page initially loads with query params, redirect to the contract page.
 | 
				
			||||||
| 
						 | 
					@ -54,11 +43,9 @@ const Home = () => {
 | 
				
			||||||
          <Col className="w-full max-w-[700px]">
 | 
					          <Col className="w-full max-w-[700px]">
 | 
				
			||||||
            <FeedCreate user={user ?? undefined} />
 | 
					            <FeedCreate user={user ?? undefined} />
 | 
				
			||||||
            <Spacer h={10} />
 | 
					            <Spacer h={10} />
 | 
				
			||||||
            {contracts && recentBets && recentComments ? (
 | 
					            {feed ? (
 | 
				
			||||||
              <ActivityFeed
 | 
					              <ActivityFeed
 | 
				
			||||||
                contracts={updatedContracts}
 | 
					                feed={feed}
 | 
				
			||||||
                recentBets={recentBets}
 | 
					 | 
				
			||||||
                recentComments={recentComments}
 | 
					 | 
				
			||||||
                mode="only-recent"
 | 
					                mode="only-recent"
 | 
				
			||||||
                getContractPath={(c) =>
 | 
					                getContractPath={(c) =>
 | 
				
			||||||
                  `home?u=${c.creatorUsername}&s=${c.slug}`
 | 
					                  `home?u=${c.creatorUsername}&s=${c.slug}`
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user