From 374f5e6b2fc039ea72e788689404abda01b0773f Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Fri, 12 Aug 2022 00:59:13 -0700 Subject: [PATCH] Load bets and comments tabs data on user page independently --- web/components/bets-list.tsx | 42 ++++++++--- web/components/comments-list.tsx | 47 +++++++++--- web/components/user-page.tsx | 126 ++++++------------------------- 3 files changed, 92 insertions(+), 123 deletions(-) diff --git a/web/components/bets-list.tsx b/web/components/bets-list.tsx index 18349597..073ba40f 100644 --- a/web/components/bets-list.tsx +++ b/web/components/bets-list.tsx @@ -1,5 +1,14 @@ import Link from 'next/link' -import { groupBy, mapValues, sortBy, partition, sumBy } from 'lodash' +import { + Dictionary, + keyBy, + groupBy, + mapValues, + sortBy, + partition, + sumBy, + uniq, +} from 'lodash' import dayjs from 'dayjs' import { useEffect, useMemo, useState } from 'react' import clsx from 'clsx' @@ -19,6 +28,7 @@ import { Contract, contractPath, getBinaryProbPercent, + getContractFromId, } from 'web/lib/firebase/contracts' import { Row } from './layout/row' import { UserLink } from './user-page' @@ -41,10 +51,12 @@ import { trackLatency } from 'web/lib/firebase/tracking' import { NumericContract } from 'common/contract' import { formatNumericProbability } from 'common/pseudo-numeric' import { useUser } from 'web/hooks/use-user' +import { useUserBets } from 'web/hooks/use-user-bets' import { SellSharesModal } from './sell-modal' import { useUnfilledBets } from 'web/hooks/use-bets' import { LimitBet } from 'common/bet' import { floatingEqual } from 'common/util/math' +import { filterDefined } from 'common/util/array' import { Pagination } from './pagination' import { LimitOrderTable } from './limit-bets' @@ -52,25 +64,35 @@ type BetSort = 'newest' | 'profit' | 'closeTime' | 'value' type BetFilter = 'open' | 'limit_bet' | 'sold' | 'closed' | 'resolved' | 'all' const CONTRACTS_PER_PAGE = 50 +const JUNE_1_2022 = new Date('2022-06-01T00:00:00.000Z').valueOf() -export function BetsList(props: { - user: User - bets: Bet[] | undefined - contractsById: { [id: string]: Contract } | undefined - hideBetsBefore?: number -}) { - const { user, bets: allBets, contractsById, hideBetsBefore } = props +export function BetsList(props: { user: User }) { + const { user } = props const signedInUser = useUser() const isYourBets = user.id === signedInUser?.id + const hideBetsBefore = isYourBets ? 0 : JUNE_1_2022 + const userBets = useUserBets(user.id, { includeRedemptions: true }) + const [contractsById, setContractsById] = useState< + Dictionary | undefined + >() // Hide bets before 06-01-2022 if this isn't your own profile // NOTE: This means public profits also begin on 06-01-2022 as well. const bets = useMemo( - () => allBets?.filter((bet) => bet.createdTime >= (hideBetsBefore ?? 0)), - [allBets, hideBetsBefore] + () => userBets?.filter((bet) => bet.createdTime >= (hideBetsBefore ?? 0)), + [userBets, hideBetsBefore] ) + useEffect(() => { + if (bets) { + const contractIds = uniq(bets.map((b) => getContractFromId(b.contractId))) + Promise.all(contractIds).then((contracts) => { + setContractsById(keyBy(filterDefined(contracts), 'id')) + }) + } + }, [bets]) + const [sort, setSort] = useState('newest') const [filter, setFilter] = useState('open') const [page, setPage] = useState(0) diff --git a/web/components/comments-list.tsx b/web/components/comments-list.tsx index 304a213f..f816ea6b 100644 --- a/web/components/comments-list.tsx +++ b/web/components/comments-list.tsx @@ -1,6 +1,12 @@ +import { useEffect, useState } from 'react' +import { Dictionary, groupBy, keyBy } from 'lodash' + import { Comment } from 'common/comment' import { Contract } from 'common/contract' +import { filterDefined } from 'common/util/array' import { contractPath } from 'web/lib/firebase/contracts' +import { getUsersComments } from 'web/lib/firebase/comments' +import { getContractFromId } from 'web/lib/firebase/contracts' import { SiteLink } from './site-link' import { Row } from './layout/row' import { Avatar } from './avatar' @@ -8,24 +14,41 @@ import { RelativeTimestamp } from './relative-timestamp' import { UserLink } from './user-page' import { User } from 'common/user' import { Col } from './layout/col' -import { groupBy } from 'lodash' import { Content } from './editor' +import { LoadingIndicator } from './loading-indicator' -export function UserCommentsList(props: { - user: User - comments: Comment[] - contractsById: { [id: string]: Contract } -}) { - const { comments, contractsById } = props +export function UserCommentsList(props: { user: User }) { + const { user } = props + const [comments, setComments] = useState | undefined>() + const [contracts, setContracts] = useState | undefined>() - // we don't show comments in groups here atm, just comments on contracts - const contractComments = comments.filter((c) => c.contractId) - const commentsByContract = groupBy(contractComments, 'contractId') + useEffect(() => { + getUsersComments(user.id).then((cs) => { + // we don't show comments in groups here atm, just comments on contracts + const contractComments = cs.filter((c) => c.contractId) + const commentsByContractId = groupBy(contractComments, 'contractId') + setComments(commentsByContractId) + }) + }, [user.id]) + + useEffect(() => { + if (comments) { + Promise.all(Object.keys(comments).map(getContractFromId)).then( + (contracts) => { + setContracts(keyBy(filterDefined(contracts), 'id')) + } + ) + } + }, [comments]) + + if (comments == null || contracts == null) { + return + } return ( - {Object.entries(commentsByContract).map(([contractId, comments]) => { - const contract = contractsById[contractId] + {Object.entries(comments).map(([contractId, comments]) => { + const contract = contracts[contractId] return (
() - const [usersContracts, setUsersContracts] = useState( - 'loading' - ) - const userBets = useUserBets(user.id, { includeRedemptions: true }) - const betCount = - userBets === undefined - ? 0 - : userBets.filter((bet) => !bet.isRedemption && bet.amount !== 0).length - - const [contractsById, setContractsById] = useState< - Dictionary | undefined - >() const [showConfetti, setShowConfetti] = useState(false) useEffect(() => { @@ -83,30 +62,6 @@ export function UserPage(props: { user: User; currentUser?: User }) { setShowConfetti(claimedMana) }, [router]) - useEffect(() => { - if (!user) return - getUsersComments(user.id).then(setUsersComments) - listContracts(user.id).then(setUsersContracts) - }, [user]) - - // TODO: display comments on groups - useEffect(() => { - 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) - }) - } - }, [userBets, usersComments]) - const profit = user.profitCached.allTime return ( @@ -163,9 +118,7 @@ export function UserPage(props: { user: User; currentUser?: User }) { {' '} profit - - {user.bio && ( <>
@@ -174,7 +127,6 @@ export function UserPage(props: { user: User; currentUser?: User }) { )} - @@ -236,7 +188,6 @@ export function UserPage(props: { user: User; currentUser?: User }) { )} - {currentUser?.id === user.id && ( )} - - {usersContracts !== 'loading' && contractsById && usersComments ? ( - - ), - tabIcon: ( - - {usersContracts.length} - - ), - }, - { - title: 'Comments', - content: ( - - ), - tabIcon: ( - - {usersComments.length} - - ), - }, - { - title: 'Bets', - content: ( -
- - -
- ), - tabIcon: {betCount}, - }, - ]} - /> - ) : ( - - )} + + ), + }, + { + title: 'Comments', + content: , + }, + { + title: 'Bets', + content: ( + <> + + + + ), + }, + ]} + /> )