From 3b6ba76db65f15cf8a5d3b794c116f4f18cbe73e Mon Sep 17 00:00:00 2001 From: Ben Congdon Date: Sun, 26 Jun 2022 17:00:02 -0700 Subject: [PATCH] Add market liquidity addition events to bets feed (#578) * Add liquidity events to bets feed * Use larger avatar for liquidity feed items --- web/components/contract/contract-tabs.tsx | 7 +- web/components/feed/activity-items.ts | 30 +++++++- web/components/feed/contract-activity.tsx | 6 +- web/components/feed/feed-items.tsx | 3 + web/components/feed/feed-liquidity.tsx | 85 +++++++++++++++++++++++ web/pages/[username]/[contractSlug].tsx | 4 ++ 6 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 web/components/feed/feed-liquidity.tsx diff --git a/web/components/contract/contract-tabs.tsx b/web/components/contract/contract-tabs.tsx index cb4a3537..e68e59b9 100644 --- a/web/components/contract/contract-tabs.tsx +++ b/web/components/contract/contract-tabs.tsx @@ -8,15 +8,17 @@ import { Spacer } from '../layout/spacer' import { Tabs } from '../layout/tabs' import { Col } from '../layout/col' import { CommentTipMap } from 'web/hooks/use-tip-txns' +import { LiquidityProvision } from 'common/liquidity-provision' export function ContractTabs(props: { contract: Contract user: User | null | undefined bets: Bet[] + liquidityProvisions: LiquidityProvision[] comments: Comment[] tips: CommentTipMap }) { - const { contract, user, bets, comments, tips } = props + const { contract, user, bets, comments, tips, liquidityProvisions } = props const { outcomeType } = contract const userBets = user && bets.filter((bet) => bet.userId === user.id) @@ -25,6 +27,7 @@ export function ContractTabs(props: { ({ + type: 'liquidity' as const, + id: liquidity.id, + contract, + liquidity, + hideOutcome: false, + smallAvatar: false, + })) + ) + items = sortBy(items, (item) => + item.type === 'bet' + ? item.bet.createdTime + : item.type === 'liquidity' + ? item.liquidity.createdTime + : undefined + ) break case 'comments': { diff --git a/web/components/feed/contract-activity.tsx b/web/components/feed/contract-activity.tsx index 9ffc8717..8f728d39 100644 --- a/web/components/feed/contract-activity.tsx +++ b/web/components/feed/contract-activity.tsx @@ -8,11 +8,13 @@ import { FeedItems } from './feed-items' import { User } from 'common/user' import { useContractWithPreload } from 'web/hooks/use-contract' import { CommentTipMap } from 'web/hooks/use-tip-txns' +import { LiquidityProvision } from 'common/liquidity-provision' export function ContractActivity(props: { contract: Contract bets: Bet[] comments: Comment[] + liquidityProvisions: LiquidityProvision[] tips: CommentTipMap user: User | null | undefined mode: 'comments' | 'bets' | 'free-response-comment-answer-groups' @@ -20,7 +22,8 @@ export function ContractActivity(props: { className?: string betRowClassName?: string }) { - const { user, mode, tips, className, betRowClassName } = props + const { user, mode, tips, className, betRowClassName, liquidityProvisions } = + props const contract = useContractWithPreload(props.contract) ?? props.contract @@ -33,6 +36,7 @@ export function ContractActivity(props: { contract, bets, comments, + liquidityProvisions, tips, user, { mode } diff --git a/web/components/feed/feed-items.tsx b/web/components/feed/feed-items.tsx index ef0d133b..312190e4 100644 --- a/web/components/feed/feed-items.tsx +++ b/web/components/feed/feed-items.tsx @@ -35,6 +35,7 @@ import { } from 'web/components/feed/feed-comments' import { FeedBet } from 'web/components/feed/feed-bets' import { NumericContract } from 'common/contract' +import { FeedLiquidity } from './feed-liquidity' export function FeedItems(props: { contract: Contract @@ -83,6 +84,8 @@ export function FeedItem(props: { item: ActivityItem }) { return case 'bet': return + case 'liquidity': + return case 'answergroup': return case 'close': diff --git a/web/components/feed/feed-liquidity.tsx b/web/components/feed/feed-liquidity.tsx new file mode 100644 index 00000000..cfce3861 --- /dev/null +++ b/web/components/feed/feed-liquidity.tsx @@ -0,0 +1,85 @@ +import dayjs from 'dayjs' +import { User } from 'common/user' +import { useUser, useUserById } from 'web/hooks/use-user' +import { Row } from 'web/components/layout/row' +import { Avatar, EmptyAvatar } from 'web/components/avatar' +import clsx from 'clsx' +import { formatMoney } from 'common/util/format' +import { RelativeTimestamp } from 'web/components/relative-timestamp' +import React from 'react' +import { UserLink } from '../user-page' +import { LiquidityProvision } from 'common/liquidity-provision' + +export function FeedLiquidity(props: { + liquidity: LiquidityProvision + smallAvatar: boolean +}) { + const { liquidity, smallAvatar } = props + const { userId, createdTime } = liquidity + + const isBeforeJune2022 = dayjs(createdTime).isBefore('2022-06-01') + // eslint-disable-next-line react-hooks/rules-of-hooks + const bettor = isBeforeJune2022 ? undefined : useUserById(userId) + + const user = useUser() + const isSelf = user?.id === userId + + return ( + <> + + {isSelf ? ( + + ) : bettor ? ( + + ) : ( +
+ +
+ )} +
+ +
+
+ + ) +} + +export function LiquidityStatusText(props: { + liquidity: LiquidityProvision + isSelf: boolean + bettor?: User +}) { + const { liquidity, bettor, isSelf } = props + const { amount, createdTime } = liquidity + + // TODO: Withdrawn liquidity will never be shown, since liquidity amounts currently are zeroed out upon withdrawal. + const bought = amount >= 0 ? 'added' : 'withdrew' + const money = formatMoney(Math.abs(amount)) + + return ( +
+ {bettor ? ( + + ) : ( + {isSelf ? 'You' : 'A trader'} + )}{' '} + {bought} {money} + {' of liquidity'} + +
+ ) +} diff --git a/web/pages/[username]/[contractSlug].tsx b/web/pages/[username]/[contractSlug].tsx index 099ba57e..24982b4f 100644 --- a/web/pages/[username]/[contractSlug].tsx +++ b/web/pages/[username]/[contractSlug].tsx @@ -42,6 +42,7 @@ import { useBets } from 'web/hooks/use-bets' import { AlertBox } from 'web/components/alert-box' import { useTracking } from 'web/hooks/use-tracking' import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns' +import { useLiquidity } from 'web/hooks/use-liquidity' export const getStaticProps = fromPropz(getStaticPropz) export async function getStaticPropz(props: { @@ -117,6 +118,8 @@ export function ContractPageContent( }) const bets = useBets(contract.id) ?? props.bets + const liquidityProvisions = + useLiquidity(contract.id)?.filter((l) => !l.isAnte && l.amount > 0) ?? [] // Sort for now to see if bug is fixed. comments.sort((c1, c2) => c1.createdTime - c2.createdTime) @@ -233,6 +236,7 @@ export function ContractPageContent(