getting comments pretty much looking how I want, now need help on group organizing
This commit is contained in:
parent
4ed1ca7e76
commit
d685f0288b
|
@ -149,62 +149,58 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
|
||||||
</Row>
|
</Row>
|
||||||
)
|
)
|
||||||
|
|
||||||
if (contract.outcomeType === 'FREE_RESPONSE') {
|
// if (contract.outcomeType === 'FREE_RESPONSE') {
|
||||||
const sortedAnswers = sortBy(
|
// const sortedAnswers = sortBy(
|
||||||
contract.answers,
|
// contract.answers,
|
||||||
(a) => -getOutcomeProbability(contract, a.id)
|
// (a) => -getOutcomeProbability(contract, a.id)
|
||||||
)
|
// )
|
||||||
const commentsByOutcome = groupBy(
|
// const commentsByOutcome = groupBy(
|
||||||
sortedComments,
|
// sortedComments,
|
||||||
(c) => c.answerOutcome ?? c.betOutcome ?? '_'
|
// (c) => c.answerOutcome ?? c.betOutcome ?? '_'
|
||||||
)
|
// )
|
||||||
const generalTopLevelComments = topLevelComments.filter(
|
// const generalTopLevelComments = topLevelComments.filter(
|
||||||
(c) => c.answerOutcome === undefined && c.betId === undefined
|
// (c) => c.answerOutcome === undefined && c.betId === undefined
|
||||||
)
|
// )
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<>
|
// <>
|
||||||
<Col className="flex w-full">
|
// <Col className="flex w-full">
|
||||||
<div className="mb-4 w-full border-gray-200" />
|
// <div className="mb-4 w-full border-gray-200" />
|
||||||
{sortedAnswers.map((answer) => {
|
// {sortedAnswers.map((answer) => {
|
||||||
const answerComments =
|
// const answerComments =
|
||||||
commentsByOutcome[answer.number.toString()] ?? []
|
// commentsByOutcome[answer.number.toString()] ?? []
|
||||||
if (answerComments.length > 0) {
|
// if (answerComments.length > 0) {
|
||||||
return (
|
// return (
|
||||||
<div key={answer.id} className="relative pb-4">
|
// <div key={answer.id} className="relative pb-4">
|
||||||
{/* <span
|
// <FeedAnswerCommentGroup
|
||||||
className="absolute top-5 left-5 -ml-px h-[calc(100%-2rem)] w-0.5 bg-gray-200"
|
// contract={contract}
|
||||||
aria-hidden="true"
|
// answer={answer}
|
||||||
/> */}
|
// answerComments={
|
||||||
<FeedAnswerCommentGroup
|
// commentsByOutcome[answer.number.toString()] ?? []
|
||||||
contract={contract}
|
// }
|
||||||
answer={answer}
|
// tips={tips}
|
||||||
answerComments={
|
// />
|
||||||
commentsByOutcome[answer.number.toString()] ?? []
|
// </div>
|
||||||
}
|
// )
|
||||||
tips={tips}
|
// } else {
|
||||||
/>
|
// return <></>
|
||||||
</div>
|
// }
|
||||||
)
|
// })}
|
||||||
} else {
|
// <ContractCommentInput className="mb-5" contract={contract} />
|
||||||
return <></>
|
// {sortRow}
|
||||||
}
|
// {generalTopLevelComments.map((comment) => (
|
||||||
})}
|
// <FeedCommentThread
|
||||||
{sortRow}
|
// key={comment.id}
|
||||||
<ContractCommentInput className="mb-5" contract={contract} />
|
// contract={contract}
|
||||||
{generalTopLevelComments.map((comment) => (
|
// parentComment={comment}
|
||||||
<FeedCommentThread
|
// threadComments={commentsByParent[comment.id] ?? []}
|
||||||
key={comment.id}
|
// tips={tips}
|
||||||
contract={contract}
|
// />
|
||||||
parentComment={comment}
|
// ))}
|
||||||
threadComments={commentsByParent[comment.id] ?? []}
|
// </Col>
|
||||||
tips={tips}
|
// </>
|
||||||
/>
|
// )
|
||||||
))}
|
// } else {
|
||||||
</Col>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{sortRow}
|
{sortRow}
|
||||||
|
@ -223,7 +219,7 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
// }
|
||||||
})
|
})
|
||||||
|
|
||||||
const BetsTabContent = memo(function BetsTabContent(props: {
|
const BetsTabContent = memo(function BetsTabContent(props: {
|
||||||
|
|
|
@ -37,7 +37,7 @@ export function TipButton(props: {
|
||||||
<Col className={'relative items-center sm:flex-row'}>
|
<Col className={'relative items-center sm:flex-row'}>
|
||||||
<HeartIcon
|
<HeartIcon
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'h-5 w-5 sm:h-6 sm:w-6',
|
'h-5 w-5',
|
||||||
totalTipped > 0 ? 'mr-2' : '',
|
totalTipped > 0 ? 'mr-2' : '',
|
||||||
userTipped ? 'fill-green-700 text-green-700' : ''
|
userTipped ? 'fill-green-700 text-green-700' : ''
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -51,15 +51,7 @@ export function FeedAnswerCommentGroup(props: {
|
||||||
ref={answerRef}
|
ref={answerRef}
|
||||||
id={answerElementId}
|
id={answerElementId}
|
||||||
>
|
>
|
||||||
<Col>
|
<Avatar username={username} avatarUrl={avatarUrl} size="sm" />
|
||||||
<Avatar username={username} avatarUrl={avatarUrl} size="xs" />
|
|
||||||
{seeReplies && (
|
|
||||||
<span
|
|
||||||
className="mx-auto h-full w-0.5 bg-gray-200"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
<Col className="min-w-0 flex-1">
|
<Col className="min-w-0 flex-1">
|
||||||
<div className="text-greyscale-6 text-xs">
|
<div className="text-greyscale-6 text-xs">
|
||||||
<UserLink username={username} name={name} /> answered
|
<UserLink username={username} name={name} /> answered
|
||||||
|
@ -93,7 +85,7 @@ export function FeedAnswerCommentGroup(props: {
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{seeReplies && (
|
{seeReplies && (
|
||||||
<Col className="gap-3 pl-1">
|
<Col className="w-full gap-3 pl-1">
|
||||||
{answerComments.map((comment) => (
|
{answerComments.map((comment) => (
|
||||||
<FeedComment
|
<FeedComment
|
||||||
key={comment.id}
|
key={comment.id}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import { Editor } from '@tiptap/react'
|
||||||
import { UserLink } from 'web/components/user-link'
|
import { UserLink } from 'web/components/user-link'
|
||||||
import { CommentInput } from '../comment-input'
|
import { CommentInput } from '../comment-input'
|
||||||
import { AwardBountyButton } from 'web/components/award-bounty-button'
|
import { AwardBountyButton } from 'web/components/award-bounty-button'
|
||||||
|
import { ReplyIcon } from '@heroicons/react/solid'
|
||||||
|
import { Button } from '../button'
|
||||||
|
|
||||||
export type ReplyTo = { id: string; username: string }
|
export type ReplyTo = { id: string; username: string }
|
||||||
|
|
||||||
|
@ -34,10 +36,6 @@ export function FeedCommentThread(props: {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Col className="relative w-full items-stretch gap-3 pb-4">
|
<Col className="relative w-full items-stretch gap-3 pb-4">
|
||||||
<span
|
|
||||||
className="absolute top-5 left-4 -ml-px h-[calc(100%-2rem)] w-0.5 bg-gray-200"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
{[parentComment].concat(threadComments).map((comment, commentIdx) => (
|
{[parentComment].concat(threadComments).map((comment, commentIdx) => (
|
||||||
<FeedComment
|
<FeedComment
|
||||||
key={comment.id}
|
key={comment.id}
|
||||||
|
@ -76,26 +74,7 @@ export function FeedComment(props: {
|
||||||
onReplyClick?: () => void
|
onReplyClick?: () => void
|
||||||
}) {
|
}) {
|
||||||
const { contract, comment, tips, indent, onReplyClick } = props
|
const { contract, comment, tips, indent, onReplyClick } = props
|
||||||
const {
|
const { text, content, userUsername, userAvatarUrl } = comment
|
||||||
text,
|
|
||||||
content,
|
|
||||||
userUsername,
|
|
||||||
userName,
|
|
||||||
userAvatarUrl,
|
|
||||||
commenterPositionProb,
|
|
||||||
commenterPositionShares,
|
|
||||||
commenterPositionOutcome,
|
|
||||||
createdTime,
|
|
||||||
bountiesAwarded,
|
|
||||||
} = comment
|
|
||||||
const betOutcome = comment.betOutcome
|
|
||||||
let bought: string | undefined
|
|
||||||
let money: string | undefined
|
|
||||||
if (comment.betAmount != null) {
|
|
||||||
bought = comment.betAmount >= 0 ? 'bought' : 'sold'
|
|
||||||
money = formatMoney(Math.abs(comment.betAmount))
|
|
||||||
}
|
|
||||||
const totalAwarded = bountiesAwarded ?? 0
|
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const highlighted = router.asPath.endsWith(`#${comment.id}`)
|
const highlighted = router.asPath.endsWith(`#${comment.id}`)
|
||||||
|
@ -107,88 +86,64 @@ export function FeedComment(props: {
|
||||||
}
|
}
|
||||||
}, [highlighted])
|
}, [highlighted])
|
||||||
|
|
||||||
|
const [showActions, setShowActions] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row
|
<Row
|
||||||
ref={commentRef}
|
ref={commentRef}
|
||||||
id={comment.id}
|
id={comment.id}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'relative',
|
'hover:bg-greyscale-1 gap-2 transition-colors',
|
||||||
indent ? 'ml-6' : '',
|
indent ? 'ml-8' : '',
|
||||||
highlighted ? `-m-1.5 rounded bg-indigo-500/[0.2] p-1.5` : ''
|
highlighted ? `-m-1.5 rounded bg-indigo-500/[0.2] p-1.5` : ''
|
||||||
)}
|
)}
|
||||||
|
onMouseOver={() => setShowActions(true)}
|
||||||
|
onMouseLeave={() => setShowActions(false)}
|
||||||
>
|
>
|
||||||
{/*draw a gray line from the comment to the left:*/}
|
<Col className={clsx(indent ? '-ml-3' : '')}>
|
||||||
{indent ? (
|
<Avatar
|
||||||
|
size={indent ? 'xs' : 'sm'}
|
||||||
|
username={userUsername}
|
||||||
|
avatarUrl={userAvatarUrl}
|
||||||
|
/>
|
||||||
|
{indent && (
|
||||||
<span
|
<span
|
||||||
className="bg-greyscale-2 absolute -left-1 -ml-[1px] mt-[0.8rem] h-2 w-0.5 rotate-90"
|
className="bg-greyscale-2 mx-auto h-full w-0.5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
) : null}
|
|
||||||
<Avatar size="xs" username={userUsername} avatarUrl={userAvatarUrl} />
|
|
||||||
<div>
|
|
||||||
<div className="text-greyscale-6 mt-0.5 text-xs">
|
|
||||||
<UserLink username={userUsername} name={userName} />{' '}
|
|
||||||
<span className="text-greyscale-4">
|
|
||||||
{comment.betId == null &&
|
|
||||||
commenterPositionProb != null &&
|
|
||||||
commenterPositionOutcome != null &&
|
|
||||||
commenterPositionShares != null &&
|
|
||||||
commenterPositionShares > 0 &&
|
|
||||||
contract.outcomeType !== 'NUMERIC' && (
|
|
||||||
<>
|
|
||||||
{'is '}
|
|
||||||
<CommentStatus
|
|
||||||
prob={commenterPositionProb}
|
|
||||||
outcome={commenterPositionOutcome}
|
|
||||||
contract={contract}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
{bought} {money}
|
</Col>
|
||||||
{contract.outcomeType !== 'FREE_RESPONSE' && betOutcome && (
|
<Col className="w-full">
|
||||||
<>
|
<FeedCommentHeader comment={comment} contract={contract} />
|
||||||
{' '}
|
<Row>
|
||||||
of{' '}
|
|
||||||
<OutcomeLabel
|
|
||||||
outcome={betOutcome ? betOutcome : ''}
|
|
||||||
contract={contract}
|
|
||||||
truncate="short"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
<CopyLinkDateTimeComponent
|
|
||||||
prefix={contract.creatorUsername}
|
|
||||||
slug={contract.slug}
|
|
||||||
createdTime={createdTime}
|
|
||||||
elementId={comment.id}
|
|
||||||
/>
|
|
||||||
{totalAwarded > 0 && (
|
|
||||||
<span className=" text-primary ml-2 text-sm">
|
|
||||||
+{formatMoney(totalAwarded)}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<Content
|
<Content
|
||||||
className="mt-2 text-[12px] text-gray-700"
|
className="text-greyscale-7 mt-2 grow text-[14px]"
|
||||||
content={content || text}
|
content={content || text}
|
||||||
smallImage
|
smallImage
|
||||||
/>
|
/>
|
||||||
<Row className="mt-2 items-center gap-6 text-xs text-gray-500">
|
<Row
|
||||||
|
className={clsx(
|
||||||
|
'ml-2 items-center gap-2 text-xs text-gray-500 transition-opacity',
|
||||||
|
showActions ? '' : 'opacity-0'
|
||||||
|
)}
|
||||||
|
>
|
||||||
{onReplyClick && (
|
{onReplyClick && (
|
||||||
<button
|
<Button
|
||||||
className="font-bold hover:underline"
|
className="font-bold hover:underline"
|
||||||
onClick={onReplyClick}
|
onClick={onReplyClick}
|
||||||
|
size="2xs"
|
||||||
|
color="gray-white"
|
||||||
>
|
>
|
||||||
Reply
|
<ReplyIcon className="h-5 w-5" />
|
||||||
</button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{tips && <Tipper comment={comment} tips={tips} />}
|
{tips && <Tipper comment={comment} tips={tips} />}
|
||||||
{(contract.openCommentBounties ?? 0) > 0 && (
|
{(contract.openCommentBounties ?? 0) > 0 && (
|
||||||
<AwardBountyButton comment={comment} contract={contract} />
|
<AwardBountyButton comment={comment} contract={contract} />
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</Row>
|
||||||
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -246,3 +201,74 @@ export function ContractCommentInput(props: {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function FeedCommentHeader(props: {
|
||||||
|
comment: ContractComment
|
||||||
|
contract: Contract
|
||||||
|
}) {
|
||||||
|
const { comment, contract } = props
|
||||||
|
const {
|
||||||
|
userUsername,
|
||||||
|
userName,
|
||||||
|
commenterPositionProb,
|
||||||
|
commenterPositionShares,
|
||||||
|
commenterPositionOutcome,
|
||||||
|
createdTime,
|
||||||
|
bountiesAwarded,
|
||||||
|
} = comment
|
||||||
|
const betOutcome = comment.betOutcome
|
||||||
|
let bought: string | undefined
|
||||||
|
let money: string | undefined
|
||||||
|
if (comment.betAmount != null) {
|
||||||
|
bought = comment.betAmount >= 0 ? 'bought' : 'sold'
|
||||||
|
money = formatMoney(Math.abs(comment.betAmount))
|
||||||
|
}
|
||||||
|
const totalAwarded = bountiesAwarded ?? 0
|
||||||
|
return (
|
||||||
|
<Row>
|
||||||
|
<div className="text-greyscale-6 mt-0.5 text-xs">
|
||||||
|
<UserLink username={userUsername} name={userName} />{' '}
|
||||||
|
<span className="text-greyscale-4">
|
||||||
|
{comment.betId == null &&
|
||||||
|
commenterPositionProb != null &&
|
||||||
|
commenterPositionOutcome != null &&
|
||||||
|
commenterPositionShares != null &&
|
||||||
|
commenterPositionShares > 0 &&
|
||||||
|
contract.outcomeType !== 'NUMERIC' && (
|
||||||
|
<>
|
||||||
|
{'is '}
|
||||||
|
<CommentStatus
|
||||||
|
prob={commenterPositionProb}
|
||||||
|
outcome={commenterPositionOutcome}
|
||||||
|
contract={contract}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{bought} {money}
|
||||||
|
{contract.outcomeType !== 'FREE_RESPONSE' && betOutcome && (
|
||||||
|
<>
|
||||||
|
{' '}
|
||||||
|
of{' '}
|
||||||
|
<OutcomeLabel
|
||||||
|
outcome={betOutcome ? betOutcome : ''}
|
||||||
|
contract={contract}
|
||||||
|
truncate="short"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<CopyLinkDateTimeComponent
|
||||||
|
prefix={contract.creatorUsername}
|
||||||
|
slug={contract.slug}
|
||||||
|
createdTime={createdTime}
|
||||||
|
elementId={comment.id}
|
||||||
|
/>
|
||||||
|
{totalAwarded > 0 && (
|
||||||
|
<span className=" text-primary ml-2 text-sm">
|
||||||
|
+{formatMoney(totalAwarded)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user