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