Load contracts at UserPage top level instead of in BetsList
This commit is contained in:
parent
f294189e20
commit
5e1ed17cdf
|
@ -1,5 +1,5 @@
|
|||
import Link from 'next/link'
|
||||
import { uniq, groupBy, mapValues, sortBy, partition, sumBy } from 'lodash'
|
||||
import { groupBy, mapValues, sortBy, partition, sumBy } from 'lodash'
|
||||
import dayjs from 'dayjs'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import clsx from 'clsx'
|
||||
|
@ -16,7 +16,6 @@ import { Col } from './layout/col'
|
|||
import { Spacer } from './layout/spacer'
|
||||
import {
|
||||
Contract,
|
||||
getContractFromId,
|
||||
contractPath,
|
||||
getBinaryProbPercent,
|
||||
} from 'web/lib/firebase/contracts'
|
||||
|
@ -25,7 +24,6 @@ import { UserLink } from './user-page'
|
|||
import { sellBet } from 'web/lib/firebase/api'
|
||||
import { ConfirmationButton } from './confirmation-button'
|
||||
import { OutcomeLabel, YesLabel, NoLabel } from './outcome-label'
|
||||
import { filterDefined } from 'common/util/array'
|
||||
import { LoadingIndicator } from './loading-indicator'
|
||||
import { SiteLink } from './site-link'
|
||||
import {
|
||||
|
@ -56,9 +54,10 @@ const CONTRACTS_PER_PAGE = 20
|
|||
export function BetsList(props: {
|
||||
user: User
|
||||
bets: Bet[] | undefined
|
||||
contractsById: { [id: string]: Contract } | undefined
|
||||
hideBetsBefore?: number
|
||||
}) {
|
||||
const { user, bets: allBets, hideBetsBefore } = props
|
||||
const { user, bets: allBets, contractsById, hideBetsBefore } = props
|
||||
|
||||
const signedInUser = useUser()
|
||||
const isYourBets = user.id === signedInUser?.id
|
||||
|
@ -69,7 +68,6 @@ export function BetsList(props: {
|
|||
() => allBets?.filter((bet) => bet.createdTime >= (hideBetsBefore ?? 0)),
|
||||
[allBets, hideBetsBefore]
|
||||
)
|
||||
const [contracts, setContracts] = useState<Contract[] | undefined>()
|
||||
|
||||
const [sort, setSort] = useState<BetSort>('newest')
|
||||
const [filter, setFilter] = useState<BetFilter>('open')
|
||||
|
@ -77,39 +75,26 @@ export function BetsList(props: {
|
|||
const start = page * CONTRACTS_PER_PAGE
|
||||
const end = start + CONTRACTS_PER_PAGE
|
||||
|
||||
useEffect(() => {
|
||||
if (bets) {
|
||||
const contractIds = uniq(bets.map((bet) => bet.contractId))
|
||||
|
||||
let disposed = false
|
||||
Promise.all(contractIds.map((id) => getContractFromId(id))).then(
|
||||
(contracts) => {
|
||||
if (!disposed) setContracts(filterDefined(contracts))
|
||||
}
|
||||
)
|
||||
|
||||
return () => {
|
||||
disposed = true
|
||||
}
|
||||
}
|
||||
}, [bets])
|
||||
|
||||
const getTime = useTimeSinceFirstRender()
|
||||
useEffect(() => {
|
||||
if (bets && contracts) {
|
||||
if (bets && contractsById) {
|
||||
trackLatency('portfolio', getTime())
|
||||
}
|
||||
}, [bets, contracts, getTime])
|
||||
}, [bets, contractsById, getTime])
|
||||
|
||||
if (!bets || !contracts) {
|
||||
if (!bets || !contractsById) {
|
||||
return <LoadingIndicator />
|
||||
}
|
||||
|
||||
if (bets.length === 0) return <NoBets user={user} />
|
||||
|
||||
// Decending creation time.
|
||||
bets.sort((bet1, bet2) => bet2.createdTime - bet1.createdTime)
|
||||
const contractBets = groupBy(bets, 'contractId')
|
||||
const contractsById = Object.fromEntries(contracts.map((c) => [c.id, c]))
|
||||
|
||||
// Keep only contracts that have bets.
|
||||
const contracts = Object.values(contractsById).filter(
|
||||
(c) => contractBets[c.id]
|
||||
)
|
||||
|
||||
const contractsMetrics = mapValues(contractBets, (bets, contractId) => {
|
||||
const contract = contractsById[contractId]
|
||||
|
|
|
@ -9,16 +9,25 @@ import { UserLink } from './user-page'
|
|||
import { User } from 'common/user'
|
||||
import { Col } from './layout/col'
|
||||
import { Linkify } from './linkify'
|
||||
import { groupBy } from 'lodash'
|
||||
|
||||
export function UserCommentsList(props: {
|
||||
user: User
|
||||
commentsByUniqueContracts: Map<Contract, Comment[]>
|
||||
comments: Comment[]
|
||||
contractsById: { [id: string]: Contract }
|
||||
}) {
|
||||
const { commentsByUniqueContracts } = props
|
||||
const { comments, contractsById } = props
|
||||
const commentsByContract = groupBy(comments, 'contractId')
|
||||
|
||||
const contractCommentPairs = Object.entries(commentsByContract)
|
||||
.map(
|
||||
([contractId, comments]) => [contractsById[contractId], comments] as const
|
||||
)
|
||||
.filter(([contract]) => contract)
|
||||
|
||||
return (
|
||||
<Col className={'bg-white'}>
|
||||
{Array.from(commentsByUniqueContracts).map(([contract, comments]) => (
|
||||
{contractCommentPairs.map(([contract, comments]) => (
|
||||
<div key={contract.id} className={'border-width-1 border-b p-5'}>
|
||||
<div className={'mb-2 text-sm text-indigo-700'}>
|
||||
<SiteLink href={contractPath(contract)}>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import clsx from 'clsx'
|
||||
import { uniq } from 'lodash'
|
||||
import { Dictionary, keyBy, uniq } from 'lodash'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { LinkIcon } from '@heroicons/react/solid'
|
||||
|
@ -39,6 +39,7 @@ import { PortfolioMetrics } from 'common/user'
|
|||
import { ReferralsButton } from 'web/components/referrals-button'
|
||||
import { GroupsButton } from 'web/components/groups/groups-button'
|
||||
import { PortfolioValueSection } from './portfolio/portfolio-value-section'
|
||||
import { filterDefined } from 'common/util/array'
|
||||
|
||||
export function UserLink(props: {
|
||||
name: string
|
||||
|
@ -72,7 +73,7 @@ export function UserPage(props: {
|
|||
const router = useRouter()
|
||||
const isCurrentUser = user.id === currentUser?.id
|
||||
const bannerUrl = user.bannerUrl ?? defaultBannerUrl(user.id)
|
||||
const [usersComments, setUsersComments] = useState<Comment[]>([] as Comment[])
|
||||
const [usersComments, setUsersComments] = useState<Comment[] | undefined>()
|
||||
const [usersContracts, setUsersContracts] = useState<Contract[] | 'loading'>(
|
||||
'loading'
|
||||
)
|
||||
|
@ -85,9 +86,9 @@ export function UserPage(props: {
|
|||
const [portfolioHistory, setUsersPortfolioHistory] = useState<
|
||||
PortfolioMetrics[]
|
||||
>([])
|
||||
const [commentsByContract, setCommentsByContract] = useState<
|
||||
Map<Contract, Comment[]> | 'loading'
|
||||
>('loading')
|
||||
const [contractsById, setContractsById] = useState<
|
||||
Dictionary<Contract> | undefined
|
||||
>()
|
||||
const [showConfetti, setShowConfetti] = useState(false)
|
||||
const { width, height } = useWindowSize()
|
||||
|
||||
|
@ -106,25 +107,21 @@ export function UserPage(props: {
|
|||
|
||||
// TODO: display comments on groups
|
||||
useEffect(() => {
|
||||
const uniqueContractIds = uniq(
|
||||
usersComments.map((comment) => comment.contractId)
|
||||
)
|
||||
Promise.all(
|
||||
uniqueContractIds.map(
|
||||
(contractId) => contractId && getContractFromId(contractId)
|
||||
)
|
||||
).then((contracts) => {
|
||||
const commentsByContract = new Map<Contract, Comment[]>()
|
||||
contracts.forEach((contract) => {
|
||||
if (!contract) return
|
||||
commentsByContract.set(
|
||||
contract,
|
||||
usersComments.filter((comment) => comment.contractId === contract.id)
|
||||
if (usersComments && userBets) {
|
||||
const uniqueContractIds = uniq([
|
||||
...usersComments.map((comment) => comment.contractId),
|
||||
...(userBets?.map((bet) => bet.contractId) ?? []),
|
||||
])
|
||||
Promise.all(
|
||||
uniqueContractIds.map((contractId) =>
|
||||
contractId ? getContractFromId(contractId) : undefined
|
||||
)
|
||||
).then((contracts) => {
|
||||
const contractsById = keyBy(filterDefined(contracts), 'id')
|
||||
setContractsById(contractsById)
|
||||
})
|
||||
setCommentsByContract(commentsByContract)
|
||||
})
|
||||
}, [usersComments])
|
||||
}
|
||||
}, [userBets, usersComments])
|
||||
|
||||
const yourFollows = useFollows(currentUser?.id)
|
||||
const isFollowing = yourFollows?.includes(user.id)
|
||||
|
@ -265,7 +262,7 @@ export function UserPage(props: {
|
|||
|
||||
<Spacer h={10} />
|
||||
|
||||
{usersContracts !== 'loading' && commentsByContract != 'loading' ? (
|
||||
{usersContracts !== 'loading' && contractsById && usersComments ? (
|
||||
<Tabs
|
||||
currentPageForAnalytics={'profile'}
|
||||
labelClassName={'pb-2 pt-1 '}
|
||||
|
@ -296,7 +293,8 @@ export function UserPage(props: {
|
|||
content: (
|
||||
<UserCommentsList
|
||||
user={user}
|
||||
commentsByUniqueContracts={commentsByContract}
|
||||
contractsById={contractsById}
|
||||
comments={usersComments}
|
||||
/>
|
||||
),
|
||||
tabIcon: (
|
||||
|
@ -314,6 +312,7 @@ export function UserPage(props: {
|
|||
user={user}
|
||||
bets={userBets}
|
||||
hideBetsBefore={isCurrentUser ? 0 : JUNE_1_2022}
|
||||
contractsById={contractsById}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue
Block a user