De-feedify contract bets list
This commit is contained in:
parent
1e3a0ca3d9
commit
4cde587ae6
|
@ -123,12 +123,7 @@ export function ContractTopTrades(props: {
|
|||
<>
|
||||
<Title text="💸 Smartest money" className="!mt-0" />
|
||||
<div className="relative flex items-start space-x-3 rounded-md bg-gray-50 px-2 py-4">
|
||||
<FeedBet
|
||||
contract={contract}
|
||||
bet={betsById[topBetId]}
|
||||
hideOutcome={false}
|
||||
smallAvatar={false}
|
||||
/>
|
||||
<FeedBet contract={contract} bet={betsById[topBetId]} />
|
||||
</div>
|
||||
<div className="mt-2 text-sm text-gray-500">
|
||||
{topBettor?.name} made {formatMoney(profitById[topBetId] || 0)}!
|
||||
|
|
|
@ -2,7 +2,10 @@ import { Bet } from 'common/bet'
|
|||
import { Contract } from 'common/contract'
|
||||
import { ContractComment } from 'common/comment'
|
||||
import { User } from 'common/user'
|
||||
import { ContractActivity } from '../feed/contract-activity'
|
||||
import {
|
||||
ContractActivity,
|
||||
ContractBetsActivity,
|
||||
} from '../feed/contract-activity'
|
||||
import { ContractBetsTable, BetsSummary } from '../bets-list'
|
||||
import { Spacer } from '../layout/spacer'
|
||||
import { Tabs } from '../layout/tabs'
|
||||
|
@ -34,15 +37,10 @@ export function ContractTabs(props: {
|
|||
const comments = updatedComments ?? props.comments
|
||||
|
||||
const betActivity = (
|
||||
<ContractActivity
|
||||
<ContractBetsActivity
|
||||
contract={contract}
|
||||
bets={bets}
|
||||
liquidityProvisions={liquidityProvisions}
|
||||
comments={comments}
|
||||
tips={tips}
|
||||
user={user}
|
||||
mode="bets"
|
||||
betRowClassName="!mt-0 xl:hidden"
|
||||
/>
|
||||
)
|
||||
|
||||
|
@ -51,7 +49,6 @@ export function ContractTabs(props: {
|
|||
<ContractActivity
|
||||
contract={contract}
|
||||
bets={bets}
|
||||
liquidityProvisions={liquidityProvisions}
|
||||
comments={comments}
|
||||
tips={tips}
|
||||
user={user}
|
||||
|
@ -69,7 +66,6 @@ export function ContractTabs(props: {
|
|||
<ContractActivity
|
||||
contract={contract}
|
||||
bets={bets}
|
||||
liquidityProvisions={liquidityProvisions}
|
||||
comments={comments}
|
||||
tips={tips}
|
||||
user={user}
|
||||
|
|
|
@ -7,18 +7,15 @@ import { ContractComment } from 'common/comment'
|
|||
import { Contract, FreeResponseContract } from 'common/contract'
|
||||
import { User } from 'common/user'
|
||||
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
||||
import { LiquidityProvision } from 'common/liquidity-provision'
|
||||
|
||||
export type ActivityItem =
|
||||
| DescriptionItem
|
||||
| QuestionItem
|
||||
| BetItem
|
||||
| AnswerGroupItem
|
||||
| CloseItem
|
||||
| ResolveItem
|
||||
| CommentInputItem
|
||||
| CommentThreadItem
|
||||
| LiquidityItem
|
||||
|
||||
type BaseActivityItem = {
|
||||
id: string
|
||||
|
@ -40,14 +37,6 @@ export type QuestionItem = BaseActivityItem & {
|
|||
contractPath?: string
|
||||
}
|
||||
|
||||
export type BetItem = BaseActivityItem & {
|
||||
type: 'bet'
|
||||
bet: Bet
|
||||
hideOutcome: boolean
|
||||
smallAvatar: boolean
|
||||
hideComment?: boolean
|
||||
}
|
||||
|
||||
export type CommentThreadItem = BaseActivityItem & {
|
||||
type: 'commentThread'
|
||||
parentComment: ContractComment
|
||||
|
@ -73,14 +62,6 @@ export type ResolveItem = BaseActivityItem & {
|
|||
type: 'resolve'
|
||||
}
|
||||
|
||||
export type LiquidityItem = BaseActivityItem & {
|
||||
type: 'liquidity'
|
||||
liquidity: LiquidityProvision
|
||||
hideOutcome: boolean
|
||||
smallAvatar: boolean
|
||||
hideComment?: boolean
|
||||
}
|
||||
|
||||
function getAnswerAndCommentInputGroups(
|
||||
contract: FreeResponseContract,
|
||||
bets: Bet[],
|
||||
|
@ -148,50 +129,16 @@ export function getSpecificContractActivityItems(
|
|||
contract: Contract,
|
||||
bets: Bet[],
|
||||
comments: ContractComment[],
|
||||
liquidityProvisions: LiquidityProvision[],
|
||||
tips: CommentTipMap,
|
||||
user: User | null | undefined,
|
||||
options: {
|
||||
mode: 'comments' | 'bets' | 'free-response-comment-answer-groups'
|
||||
mode: 'comments' | 'free-response-comment-answer-groups'
|
||||
}
|
||||
) {
|
||||
const { mode } = options
|
||||
let items = [] as ActivityItem[]
|
||||
|
||||
switch (mode) {
|
||||
case 'bets':
|
||||
// Remove first bet (which is the ante):
|
||||
if (contract.outcomeType === 'FREE_RESPONSE') bets = bets.slice(1)
|
||||
items.push(
|
||||
...bets.map((bet) => ({
|
||||
type: 'bet' as const,
|
||||
id: bet.id + '-' + bet.isSold,
|
||||
bet,
|
||||
contract,
|
||||
hideOutcome: false,
|
||||
smallAvatar: false,
|
||||
hideComment: true,
|
||||
}))
|
||||
)
|
||||
items.push(
|
||||
...liquidityProvisions.map((liquidity) => ({
|
||||
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': {
|
||||
const nonFreeResponseComments = comments.filter((comment) =>
|
||||
commentIsGeneralComment(comment, contract)
|
||||
|
|
|
@ -4,25 +4,72 @@ import { Bet } from 'common/bet'
|
|||
import { useBets } from 'web/hooks/use-bets'
|
||||
import { getSpecificContractActivityItems } from './activity-items'
|
||||
import { FeedItems } from './feed-items'
|
||||
import { FeedBet } from './feed-bets'
|
||||
import { FeedLiquidity } from './feed-liquidity'
|
||||
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'
|
||||
import { sortBy } from 'lodash'
|
||||
import { Col } from 'web/components/layout/col'
|
||||
|
||||
export function ContractBetsActivity(props: {
|
||||
contract: Contract
|
||||
bets: Bet[]
|
||||
liquidityProvisions: LiquidityProvision[]
|
||||
}) {
|
||||
const { contract, bets, liquidityProvisions } = props
|
||||
|
||||
// Remove first bet (which is the ante):
|
||||
const displayedBets =
|
||||
contract.outcomeType === 'FREE_RESPONSE' ? bets.slice(1) : bets
|
||||
|
||||
const items = [
|
||||
...displayedBets.map((bet) => ({
|
||||
type: 'bet' as const,
|
||||
id: bet.id + '-' + bet.isSold,
|
||||
bet,
|
||||
})),
|
||||
...liquidityProvisions.map((liquidity) => ({
|
||||
type: 'liquidity' as const,
|
||||
id: liquidity.id,
|
||||
liquidity,
|
||||
})),
|
||||
]
|
||||
|
||||
const sortedItems = sortBy(items, (item) =>
|
||||
item.type === 'bet'
|
||||
? -item.bet.createdTime
|
||||
: item.type === 'liquidity'
|
||||
? -item.liquidity.createdTime
|
||||
: undefined
|
||||
)
|
||||
|
||||
return (
|
||||
<Col className="gap-4">
|
||||
{sortedItems.map((item) =>
|
||||
item.type === 'bet' ? (
|
||||
<FeedBet key={item.id} contract={contract} bet={item.bet} />
|
||||
) : (
|
||||
<FeedLiquidity key={item.id} liquidity={item.liquidity} />
|
||||
)
|
||||
)}
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
||||
export function ContractActivity(props: {
|
||||
contract: Contract
|
||||
bets: Bet[]
|
||||
comments: ContractComment[]
|
||||
liquidityProvisions: LiquidityProvision[]
|
||||
tips: CommentTipMap
|
||||
user: User | null | undefined
|
||||
mode: 'comments' | 'bets' | 'free-response-comment-answer-groups'
|
||||
mode: 'comments' | 'free-response-comment-answer-groups'
|
||||
contractPath?: string
|
||||
className?: string
|
||||
betRowClassName?: string
|
||||
}) {
|
||||
const { user, mode, tips, className, betRowClassName, liquidityProvisions } =
|
||||
props
|
||||
const { user, mode, tips, className, betRowClassName } = props
|
||||
|
||||
const contract = useContractWithPreload(props.contract) ?? props.contract
|
||||
const comments = props.comments
|
||||
|
@ -37,7 +84,6 @@ export function ContractActivity(props: {
|
|||
contract,
|
||||
bets,
|
||||
comments,
|
||||
liquidityProvisions,
|
||||
tips,
|
||||
user,
|
||||
{ mode }
|
||||
|
|
|
@ -16,13 +16,8 @@ import { SiteLink } from 'web/components/site-link'
|
|||
import { getChallenge, getChallengeUrl } from 'web/lib/firebase/challenges'
|
||||
import { Challenge } from 'common/challenge'
|
||||
|
||||
export function FeedBet(props: {
|
||||
contract: Contract
|
||||
bet: Bet
|
||||
hideOutcome: boolean
|
||||
smallAvatar: boolean
|
||||
}) {
|
||||
const { contract, bet, hideOutcome, smallAvatar } = props
|
||||
export function FeedBet(props: { contract: Contract; bet: Bet }) {
|
||||
const { contract, bet } = props
|
||||
const { userId, createdTime } = bet
|
||||
|
||||
const isBeforeJune2022 = dayjs(createdTime).isBefore('2022-06-01')
|
||||
|
@ -33,21 +28,11 @@ export function FeedBet(props: {
|
|||
const isSelf = user?.id === userId
|
||||
|
||||
return (
|
||||
<Row className={'flex w-full items-center gap-2 pt-3'}>
|
||||
<Row className="flex w-full items-center gap-2 pt-3">
|
||||
{isSelf ? (
|
||||
<Avatar
|
||||
className={clsx(smallAvatar && 'ml-1')}
|
||||
size={smallAvatar ? 'sm' : undefined}
|
||||
avatarUrl={user.avatarUrl}
|
||||
username={user.username}
|
||||
/>
|
||||
<Avatar avatarUrl={user.avatarUrl} username={user.username} />
|
||||
) : bettor ? (
|
||||
<Avatar
|
||||
className={clsx(smallAvatar && 'ml-1')}
|
||||
size={smallAvatar ? 'sm' : undefined}
|
||||
avatarUrl={bettor.avatarUrl}
|
||||
username={bettor.username}
|
||||
/>
|
||||
<Avatar avatarUrl={bettor.avatarUrl} username={bettor.username} />
|
||||
) : (
|
||||
<EmptyAvatar className="mx-1" />
|
||||
)}
|
||||
|
@ -56,7 +41,6 @@ export function FeedBet(props: {
|
|||
contract={contract}
|
||||
isSelf={isSelf}
|
||||
bettor={bettor}
|
||||
hideOutcome={hideOutcome}
|
||||
className="flex-1"
|
||||
/>
|
||||
</Row>
|
||||
|
|
|
@ -3,7 +3,6 @@ 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'
|
||||
|
@ -11,10 +10,10 @@ import { UserLink } from '../user-page'
|
|||
import { LiquidityProvision } from 'common/liquidity-provision'
|
||||
|
||||
export function FeedLiquidity(props: {
|
||||
className?: string
|
||||
liquidity: LiquidityProvision
|
||||
smallAvatar: boolean
|
||||
}) {
|
||||
const { liquidity, smallAvatar } = props
|
||||
const { liquidity } = props
|
||||
const { userId, createdTime } = liquidity
|
||||
|
||||
const isBeforeJune2022 = dayjs(createdTime).isBefore('2022-06-01')
|
||||
|
@ -26,21 +25,11 @@ export function FeedLiquidity(props: {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Row className={'flex w-full gap-2 pt-3'}>
|
||||
<Row className="flex w-full gap-2 pt-3">
|
||||
{isSelf ? (
|
||||
<Avatar
|
||||
className={clsx(smallAvatar && 'ml-1')}
|
||||
size={smallAvatar ? 'sm' : undefined}
|
||||
avatarUrl={user.avatarUrl}
|
||||
username={user.username}
|
||||
/>
|
||||
<Avatar avatarUrl={user.avatarUrl} username={user.username} />
|
||||
) : bettor ? (
|
||||
<Avatar
|
||||
className={clsx(smallAvatar && 'ml-1')}
|
||||
size={smallAvatar ? 'sm' : undefined}
|
||||
avatarUrl={bettor.avatarUrl}
|
||||
username={bettor.username}
|
||||
/>
|
||||
<Avatar avatarUrl={bettor.avatarUrl} username={bettor.username} />
|
||||
) : (
|
||||
<div className="relative px-1">
|
||||
<EmptyAvatar />
|
||||
|
|
Loading…
Reference in New Issue
Block a user