diff --git a/web/components/contract-feed.tsx b/web/components/contract-feed.tsx index 4a25e4c6..dbeecfb9 100644 --- a/web/components/contract-feed.tsx +++ b/web/components/contract-feed.tsx @@ -1,5 +1,6 @@ // From https://tailwindui.com/components/application-ui/lists/feeds import { useState } from 'react' +import _ from 'lodash' import { BanIcon, ChatAltIcon, @@ -10,11 +11,11 @@ import { UsersIcon, XIcon, } from '@heroicons/react/solid' -import { useBets } from '../hooks/use-bets' -import { Bet, withoutAnteBets } from '../lib/firebase/bets' -import { Comment, mapCommentsByBetId } from '../lib/firebase/comments' + import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' +dayjs.extend(relativeTime) + import { OutcomeLabel } from './outcome-label' import { contractMetrics, @@ -33,11 +34,18 @@ import { SiteLink } from './site-link' import { Col } from './layout/col' import { UserLink } from './user-page' import { DateTimeTooltip } from './datetime-tooltip' -dayjs.extend(relativeTime) +import { useBets } from '../hooks/use-bets' +import { Bet, withoutAnteBets } from '../lib/firebase/bets' +import { Comment, mapCommentsByBetId } from '../lib/firebase/comments' +import { JoinSpans } from './join-spans' function FeedComment(props: { activityItem: any }) { const { activityItem } = props const { person, text, amount, outcome, createdTime } = activityItem + + const bought = amount >= 0 ? 'bought' : 'sold' + const money = formatMoney(Math.abs(amount)) + return ( <> @@ -59,7 +67,7 @@ function FeedComment(props: { activityItem: any }) { username={person.username} name={person.name} />{' '} - placed {formatMoney(amount)} on {' '} + {bought} {money} of {' '}

@@ -97,6 +105,10 @@ function FeedBet(props: { activityItem: any }) { if (!user || !comment) return await createComment(contractId, id, comment, user) } + + const bought = amount >= 0 ? 'bought' : 'sold' + const money = formatMoney(Math.abs(amount)) + return ( <>
@@ -108,9 +120,8 @@ function FeedBet(props: { activityItem: any }) {
- {isCreator ? 'You' : 'A trader'} placed{' '} - {formatMoney(amount)} on {' '} - + {isCreator ? 'You' : 'A trader'} {bought} {money} of{' '} + {canComment && ( // Allow user to comment in an textarea if they are the creator
@@ -452,44 +463,51 @@ function groupBets( return items as ActivityItem[] } +function BetGroupSpan(props: { bets: Bet[]; outcome: 'YES' | 'NO' }) { + const { bets, outcome } = props + + const numberTraders = _.uniqBy(bets, (b) => b.userId).length + + const [buys, sells] = _.partition(bets, (bet) => bet.amount >= 0) + const buyTotal = _.sumBy(buys, (b) => b.amount) + const sellTotal = _.sumBy(sells, (b) => -b.amount) + + return ( + + {numberTraders} {numberTraders > 1 ? 'traders' : 'trader'}{' '} + + {buyTotal > 0 && <>bought {formatMoney(buyTotal)} } + {sellTotal > 0 && <>sold {formatMoney(sellTotal)} } + + of + + ) +} + // TODO: Make this expandable to show all grouped bets? function FeedBetGroup(props: { activityItem: any }) { const { activityItem } = props const bets: Bet[] = activityItem.bets - const yesAmount = bets - .filter((b) => b.outcome == 'YES') - .reduce((acc, bet) => acc + bet.amount, 0) - const yesSpan = yesAmount ? ( - - {formatMoney(yesAmount)} on - - ) : null - const noAmount = bets - .filter((b) => b.outcome == 'NO') - .reduce((acc, bet) => acc + bet.amount, 0) - const noSpan = noAmount ? ( - - {formatMoney(noAmount)} on - - ) : null - const traderCount = bets.length + const [yesBets, noBets] = _.partition(bets, (bet) => bet.outcome === 'YES') + const createdTime = bets[0].createdTime return ( <>
-
-
- {traderCount} traders placed {yesSpan} - {yesAmount && noAmount ? ' and ' : ''} - {noSpan} + {yesBets.length > 0 && } + {yesBets.length > 0 && noBets.length > 0 &&
} + {noBets.length > 0 && } +
diff --git a/web/components/join-spans.tsx b/web/components/join-spans.tsx new file mode 100644 index 00000000..e6947ee8 --- /dev/null +++ b/web/components/join-spans.tsx @@ -0,0 +1,31 @@ +export const JoinSpans = (props: { + children: any[] + separator?: JSX.Element | string +}) => { + const { separator } = props + const children = props.children.filter((x) => !!x) + + if (children.length === 0) return <> + if (children.length === 1) return children[0] + if (children.length === 2) + return ( + <> + {children[0]} and {children[1]} + + ) + + const head = children.slice(0, -1).map((child) => ( + <> + {child} + {separator || ','}{' '} + + )) + + const tail = children[children.length - 1] + + return ( + <> + {head}and {tail} + + ) +}