diff --git a/web/components/answers/answer-item.tsx b/web/components/answers/answer-item.tsx index 7952a347..51ea9631 100644 --- a/web/components/answers/answer-item.tsx +++ b/web/components/answers/answer-item.tsx @@ -8,13 +8,12 @@ import { Col } from '../layout/col' import { Row } from '../layout/row' import { Avatar } from '../avatar' import { SiteLink } from '../site-link' -import { DateTimeTooltip } from '../datetime-tooltip' -import dayjs from 'dayjs' import { BuyButton } from '../yes-no-selector' import { formatPercent } from '../../../common/util/format' import { getOutcomeProbability } from '../../../common/calculate' import { tradingAllowed } from '../../lib/firebase/contracts' import { AnswerBetPanel } from './answer-bet-panel' +import { ContractFeed } from '../contract-feed' export function AnswerItem(props: { answer: Answer @@ -35,10 +34,9 @@ export function AnswerItem(props: { onDeselect, } = props const { resolution, resolutions, totalShares } = contract - const { username, avatarUrl, name, createdTime, number, text } = answer + const { username, avatarUrl, name, number, text } = answer const isChosen = chosenProb !== undefined - const createdDate = dayjs(createdTime).format('MMM D') const prob = getOutcomeProbability(totalShares, answer.id) const roundedProb = Math.round(prob * 100) const probPercent = formatPercent(prob) @@ -48,41 +46,44 @@ export function AnswerItem(props: { const [isBetting, setIsBetting] = useState(false) return ( - !isBetting && setIsBetting(true)} > - +
{text}
- +
{name}
- -
- -
- - {createdDate} - -
-
-
#{number}
+ {/* TODO: Show total pool? */}
+ + {isBetting && ( + + )} {isBetting ? ( @@ -92,11 +93,11 @@ export function AnswerItem(props: { closePanel={() => setIsBetting(false)} /> ) : ( - + {!wasResolvedTo && (showChoice === 'checkbox' ? ( - )} - + ) } diff --git a/web/components/contract-feed.tsx b/web/components/contract-feed.tsx index dc1d1bbd..1be52158 100644 --- a/web/components/contract-feed.tsx +++ b/web/components/contract-feed.tsx @@ -46,7 +46,7 @@ import { useAdmin } from '../hooks/use-admin' function FeedComment(props: { activityItem: any moreHref: string - feedType: 'activity' | 'market' + feedType: FeedType }) { const { activityItem, moreHref, feedType } = props const { person, text, amount, outcome, createdTime } = activityItem @@ -65,7 +65,8 @@ function FeedComment(props: { username={person.username} name={person.name} />{' '} - {bought} {money} of {' '} + {bought} {money} +

@@ -90,8 +91,8 @@ function Timestamp(props: { time: number }) { ) } -function FeedBet(props: { activityItem: any }) { - const { activityItem } = props +function FeedBet(props: { activityItem: any; feedType: FeedType }) { + const { activityItem, feedType } = props const { id, contractId, amount, outcome, createdTime } = activityItem const user = useUser() const isSelf = user?.id == activityItem.userId @@ -122,8 +123,9 @@ function FeedBet(props: { activityItem: any }) {
- {isSelf ? 'You' : 'A trader'} {bought} {money} of{' '} - + {isSelf ? 'You' : 'A trader'} {bought} {money} + + {canComment && ( // Allow user to comment in an textarea if they are the creator
@@ -382,6 +384,29 @@ function FeedDescription(props: { contract: Contract }) { ) } +function FeedAnswer(props: { contract: Contract; outcome: string }) { + const { contract, outcome } = props + const answer = contract?.answers?.[Number(outcome) - 1] + if (!answer) return null + + return ( + <> + +
+
+ {' '} + submitted answer {' '} + +
+
+ + ) +} + function OutcomeIcon(props: { outcome?: string }) { const { outcome } = props switch (outcome) { @@ -540,8 +565,12 @@ function groupBets( return items as ActivityItem[] } -function BetGroupSpan(props: { bets: Bet[]; outcome: string }) { - const { bets, outcome } = props +function BetGroupSpan(props: { + bets: Bet[] + outcome: string + feedType: FeedType +}) { + const { bets, outcome, feedType } = props const numberTraders = _.uniqBy(bets, (b) => b.userId).length @@ -556,14 +585,14 @@ function BetGroupSpan(props: { bets: Bet[]; outcome: string }) { {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 +function FeedBetGroup(props: { activityItem: any; feedType: FeedType }) { + const { activityItem, feedType } = props const bets: Bet[] = activityItem.bets const betGroups = _.groupBy(bets, (bet) => bet.outcome) @@ -585,7 +614,11 @@ function FeedBetGroup(props: { activityItem: any }) {
{outcomes.map((outcome, index) => ( - + {index !== outcomes.length - 1 &&
}
))} @@ -623,6 +656,18 @@ function FeedExpand(props: { setExpanded: (expanded: boolean) => void }) { ) } +// On 'multi' feeds, the outcome is redundant, so we hide it +function MaybeOutcomeLabel(props: { outcome: string; feedType: FeedType }) { + const { outcome, feedType } = props + return feedType === 'multi' ? null : ( + + {' '} + of + {/* TODO: Link to the correct e.g. #23 */} + + ) +} + // Missing feed items: // - Bet sold? type ActivityItem = { @@ -637,15 +682,23 @@ type ActivityItem = { | 'expand' } +type FeedType = + // Main homepage/fold feed, + | 'activity' + // Comments feed on a market + | 'market' + // Grouped for a multi-category outcome + | 'multi' + export function ContractFeed(props: { contract: Contract bets: Bet[] comments: Comment[] - // Feed types: 'activity' = Activity feed, 'market' = Comments feed on a market - feedType: 'activity' | 'market' + feedType: FeedType + outcome?: string // Which multi-category outcome to filter betRowClassName?: string }) { - const { contract, feedType, betRowClassName } = props + const { contract, feedType, outcome, betRowClassName } = props const { id, outcomeType } = contract const isBinary = outcomeType === 'BINARY' @@ -657,6 +710,10 @@ export function ContractFeed(props: { ? bets.filter((bet) => !bet.isAnte) : bets.filter((bet) => !(bet.isAnte && (bet.outcome as string) === '0')) + if (feedType === 'multi') { + bets = bets.filter((bet) => bet.outcome === outcome) + } + const comments = useComments(id) ?? props.comments const groupWindow = feedType == 'activity' ? 10 * DAY_IN_MS : DAY_IN_MS @@ -671,6 +728,10 @@ export function ContractFeed(props: { if (contract.resolution) { allItems.push({ type: 'resolve', id: `${contract.resolutionTime}` }) } + if (feedType === 'multi') { + // Hack to add some more padding above the 'multi' feedType, by adding a null item + allItems.unshift({ type: '', id: -1 }) + } // If there are more than 5 items, only show the first, an expand item, and last 3 let items = allItems @@ -684,45 +745,45 @@ export function ContractFeed(props: { return (
-
    +
    {items.map((activityItem, activityItemIdx) => ( -
  • -
    - {activityItemIdx !== items.length - 1 ? ( -
  • +
    ))} -
+
{isBinary && tradingAllowed(contract) && ( )}