From d0700c1221f59f33808967136ac80e40d61d4c9f Mon Sep 17 00:00:00 2001
From: Ian Philips
Date: Fri, 29 Apr 2022 10:39:59 -0600
Subject: [PATCH] Show users position or recent bet with comments
---
web/components/feed/activity-items.ts | 66 +++--
web/components/feed/feed-items.tsx | 342 +++++++++++++++---------
web/pages/[username]/[contractSlug].tsx | 2 +-
3 files changed, 261 insertions(+), 149 deletions(-)
diff --git a/web/components/feed/activity-items.ts b/web/components/feed/activity-items.ts
index 2dc8c564..fa8b15b9 100644
--- a/web/components/feed/activity-items.ts
+++ b/web/components/feed/activity-items.ts
@@ -31,6 +31,8 @@ type BaseActivityItem = {
export type CommentInputItem = BaseActivityItem & {
type: 'commentInput'
+ bets: Bet[]
+ comments: Comment[]
}
export type DescriptionItem = BaseActivityItem & {
@@ -48,12 +50,13 @@ export type BetItem = BaseActivityItem & {
bet: Bet
hideOutcome: boolean
smallAvatar: boolean
+ hideComment?: boolean
}
export type CommentItem = BaseActivityItem & {
type: 'comment'
comment: Comment
- bet: Bet | undefined
+ betsBySameUser: Bet[]
hideOutcome: boolean
truncate: boolean
smallAvatar: boolean
@@ -129,7 +132,7 @@ function groupBets(
type: 'comment' as const,
id: bet.id,
comment,
- bet,
+ betsBySameUser: [bet],
contract,
hideOutcome,
truncate: abbreviated,
@@ -280,7 +283,7 @@ function groupBetsAndComments(
id: comment.id,
contract: contract,
comment,
- bet: undefined,
+ betsBySameUser: [],
truncate: abbreviated,
hideOutcome: true,
smallAvatar,
@@ -308,6 +311,37 @@ function groupBetsAndComments(
return abbrItems
}
+function getCommentsWithPositions(
+ bets: Bet[],
+ comments: Comment[],
+ contract: Contract
+) {
+ function mapBetsByUserId(bets: Bet[]) {
+ return bets.reduce((acc, bet) => {
+ const userId = bet.userId
+ if (!acc[userId]) {
+ acc[userId] = []
+ }
+ acc[userId].push(bet)
+ return acc
+ }, {} as { [userId: string]: Bet[] })
+ }
+ const betsByUserId = mapBetsByUserId(bets)
+
+ const items = comments.map((comment) => ({
+ type: 'comment' as const,
+ id: comment.id,
+ contract: contract,
+ comment,
+ betsBySameUser: bets.length === 0 ? [] : betsByUserId[comment.userId],
+ truncate: true,
+ hideOutcome: false,
+ smallAvatar: false,
+ }))
+
+ return items
+}
+
export function getAllContractActivityItems(
contract: Contract,
bets: Bet[],
@@ -361,6 +395,8 @@ export function getAllContractActivityItems(
type: 'commentInput',
id: 'commentInput',
contract,
+ bets: [],
+ comments: [],
})
} else {
items.push(
@@ -385,6 +421,8 @@ export function getAllContractActivityItems(
type: 'commentInput',
id: 'commentInput',
contract,
+ bets: [],
+ comments: [],
})
}
@@ -467,32 +505,20 @@ export function getSpecificContractActivityItems(
contract,
hideOutcome: false,
smallAvatar: false,
+ hideComment: true,
}))
)
break
case 'comments':
- const onlyBetsWithComments = bets.filter((bet) =>
- comments.some((comment) => comment.betId === bet.id)
- )
- items.push(
- ...groupBetsAndComments(
- onlyBetsWithComments,
- comments,
- contract,
- user?.id,
- {
- hideOutcome: false,
- abbreviated: false,
- smallAvatar: false,
- reversed: false,
- }
- )
- )
+ items.push(...getCommentsWithPositions(bets, comments, contract))
+
items.push({
type: 'commentInput',
id: 'commentInput',
contract,
+ bets: bets,
+ comments: comments,
})
break
}
diff --git a/web/components/feed/feed-items.tsx b/web/components/feed/feed-items.tsx
index eb2cd174..5b224d9d 100644
--- a/web/components/feed/feed-items.tsx
+++ b/web/components/feed/feed-items.tsx
@@ -56,8 +56,7 @@ import { trackClick } from '../../lib/firebase/tracking'
import { firebaseLogin } from '../../lib/firebase/users'
import { DAY_MS } from '../../../common/util/time'
import NewContractBadge from '../new-contract-badge'
-import { useUserContractBets } from '../../hooks/use-user-bets'
-import { useSaveShares } from '../use-save-shares'
+import { calculateCpmmSale } from '../../../common/calculate-cpmm'
export function FeedItems(props: {
contract: Contract
@@ -131,29 +130,38 @@ function FeedItem(props: { item: ActivityItem }) {
export function FeedComment(props: {
contract: Contract
comment: Comment
- bet: Bet | undefined
+ betsBySameUser: Bet[]
hideOutcome: boolean
truncate: boolean
smallAvatar: boolean
}) {
- const { contract, comment, bet, hideOutcome, truncate, smallAvatar } = props
- let money: string | undefined
- let outcome: string | undefined
- let bought: string | undefined
- if (bet) {
- outcome = bet.outcome
- bought = bet.amount >= 0 ? 'bought' : 'sold'
- money = formatMoney(Math.abs(bet.amount))
- }
- const { text, userUsername, userName, userAvatarUrl, createdTime, userId } =
- comment
+ const {
+ contract,
+ comment,
+ betsBySameUser,
+ hideOutcome,
+ truncate,
+ smallAvatar,
+ } = props
+ const { text, userUsername, userName, userAvatarUrl, createdTime } = comment
+ let outcome: string | undefined,
+ bought: string | undefined,
+ money: string | undefined
- const userBets = useUserContractBets(userId, contract.id)
- const { yesFloorShares, noFloorShares } = useSaveShares(
- contract as FullContract,
- userBets
- )
- const userPosition = yesFloorShares || noFloorShares
+ const matchedBet = betsBySameUser.find((bet) => bet.id === comment.betId)
+ if (matchedBet) {
+ outcome = matchedBet.outcome
+ bought = matchedBet.amount >= 0 ? 'bought' : 'sold'
+ money = formatMoney(Math.abs(matchedBet.amount))
+ }
+
+ // Only calculated if they don't have a matching bet
+ const [userPosition, userPositionMoney, yesFloorShares, noFloorShares] =
+ getBettorsPosition(
+ contract,
+ comment.createdTime,
+ matchedBet ? [] : betsBySameUser
+ )
return (
<>
@@ -171,36 +179,33 @@ export function FeedComment(props: {
username={userUsername}
name={userName}
/>{' '}
- {contract.outcomeType === 'BINARY' ? (
- userPosition > 0 && (
- <>
- {'owns ' + userPosition + ' shares '}
- <>
- {' of '}
- noFloorShares ? 'YES' : 'NO'}
- contract={contract}
- truncate="short"
- />
- >
- >
- )
- ) : (
+ {!matchedBet && userPosition > 0 && (
<>
- {bought} {money}
- {!hideOutcome && (
- <>
- {' '}
- of{' '}
-
- >
- )}
+ {'with ' + userPositionMoney + ' '}
+ <>
+ {' of '}
+ noFloorShares ? 'YES' : 'NO'}
+ contract={contract}
+ truncate="short"
+ />
+ >
>
)}
+ <>
+ {bought} {money}
+ {outcome && !hideOutcome && (
+ <>
+ {' '}
+ of{' '}
+
+ >
+ )}
+ >
@@ -214,20 +219,12 @@ export function FeedComment(props: {
)
}
-function RelativeTimestamp(props: { time: number }) {
- const { time } = props
- return (
-
-
- {fromNow(time)}
-
-
- )
-}
-
-export function CommentInput(props: { contract: Contract }) {
- // see if we can comment input on any bet:
- const { contract } = props
+export function CommentInput(props: {
+ contract: Contract
+ bets: Bet[]
+ comments: Comment[]
+}) {
+ const { contract, bets, comments } = props
const user = useUser()
const [comment, setComment] = useState('')
@@ -240,14 +237,50 @@ export function CommentInput(props: { contract: Contract }) {
setComment('')
}
+ // Should this be oldest bet or most recent bet?
+ const mostRecentCommentableBet = bets
+ .filter(
+ (bet) =>
+ canCommentOnBet(bet.userId, bet.createdTime, user) &&
+ !comments.some((comment) => comment.betId == bet.id)
+ )
+ .sort((b1, b2) => b1.createdTime - b2.createdTime)
+ .pop()
+
+ if (mostRecentCommentableBet) {
+ return (
+
+ )
+ }
+ const [userPosition, userPositionMoney, yesFloorShares, noFloorShares] =
+ getBettorsPosition(contract, Date.now(), bets)
+
return (
<>
-
+
+ {user && userPosition > 0 && (
+ <>
+ {'You with ' + userPositionMoney + ' '}
+ <>
+ {' of '}
+
noFloorShares ? 'YES' : 'NO'}
+ contract={contract}
+ truncate="short"
+ />
+ >
+ >
+ )}