From 8673b618fdc0b53d1f2c79bc992eefcc45229ecc Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Wed, 21 Sep 2022 15:11:29 -0700 Subject: [PATCH] No need to look up users on contract leaderboard --- .../contract/contract-leaderboard.tsx | 53 ++++++++----------- web/components/leaderboard.tsx | 3 +- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/web/components/contract/contract-leaderboard.tsx b/web/components/contract/contract-leaderboard.tsx index 25c4323a..f984e3b6 100644 --- a/web/components/contract/contract-leaderboard.tsx +++ b/web/components/contract/contract-leaderboard.tsx @@ -3,9 +3,8 @@ import { resolvedPayout } from 'common/calculate' import { Contract } from 'common/contract' import { formatMoney } from 'common/util/format' import { groupBy, mapValues, sumBy, sortBy, keyBy } from 'lodash' -import { useState, useMemo, useEffect } from 'react' +import { memo } from 'react' import { useComments } from 'web/hooks/use-comments' -import { listUsers, User } from 'web/lib/firebase/users' import { FeedBet } from '../feed/feed-bets' import { FeedComment } from '../feed/feed-comments' import { Spacer } from '../layout/spacer' @@ -13,53 +12,43 @@ import { Leaderboard } from '../leaderboard' import { Title } from '../title' import { BETTORS } from 'common/user' -export function ContractLeaderboard(props: { +export const ContractLeaderboard = memo(function ContractLeaderboard(props: { contract: Contract bets: Bet[] }) { const { contract, bets } = props - const [users, setUsers] = useState() - const { userProfits, top5Ids } = useMemo(() => { - // Create a map of userIds to total profits (including sales) - const openBets = bets.filter((bet) => !bet.isSold && !bet.sale) - const betsByUser = groupBy(openBets, 'userId') - - const userProfits = mapValues(betsByUser, (bets) => - sumBy(bets, (bet) => resolvedPayout(contract, bet) - bet.amount) - ) - // Find the 5 users with the most profits - const top5Ids = Object.entries(userProfits) - .sort(([_i1, p1], [_i2, p2]) => p2 - p1) - .filter(([, p]) => p > 0) - .slice(0, 5) - .map(([id]) => id) - return { userProfits, top5Ids } - }, [contract, bets]) - - useEffect(() => { - if (top5Ids.length > 0) { - listUsers(top5Ids).then((users) => { - const sortedUsers = sortBy(users, (user) => -userProfits[user.id]) - setUsers(sortedUsers) - }) + // Create a map of userIds to total profits (including sales) + const openBets = bets.filter((bet) => !bet.isSold && !bet.sale) + const betsByUser = groupBy(openBets, 'userId') + const userProfits = mapValues(betsByUser, (bets) => { + return { + name: bets[0].userName, + username: bets[0].userUsername, + avatarUrl: bets[0].userAvatarUrl, + total: sumBy(bets, (bet) => resolvedPayout(contract, bet) - bet.amount), } - }, [userProfits, top5Ids]) + }) + // Find the 5 users with the most profits + const top5 = Object.values(userProfits) + .sort((p1, p2) => p2.total - p1.total) + .filter((p) => p.total > 0) + .slice(0, 5) - return users && users.length > 0 ? ( + return top5 && top5.length > 0 ? ( formatMoney(userProfits[user.id] || 0), + renderCell: (entry) => formatMoney(entry.total), }, ]} className="mt-12 max-w-sm" /> ) : null -} +}) export function ContractTopTrades(props: { contract: Contract; bets: Bet[] }) { const { contract, bets } = props diff --git a/web/components/leaderboard.tsx b/web/components/leaderboard.tsx index 237dd002..1035e9d1 100644 --- a/web/components/leaderboard.tsx +++ b/web/components/leaderboard.tsx @@ -5,7 +5,6 @@ import { SiteLink } from './site-link' import { Title } from './title' interface LeaderboardEntry { - id: string username: string name: string avatarUrl?: string @@ -44,7 +43,7 @@ export function Leaderboard(props: { {entries.map((entry, index) => ( - + {index + 1}