Add best sort to FR contracts

This commit is contained in:
Ian Philips 2022-10-03 16:38:12 -06:00
parent 84aaeece9f
commit a1dcf8d168

View File

@ -93,98 +93,36 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
const tipsOrBountiesAwarded =
Object.keys(tips).length > 0 || comments.some((c) => c.bountiesAwarded)
const sortedComments = sortBy(comments, (c) =>
sort === 'Newest'
? c.createdTime
: // Is this too magic? If there are tips/bounties, 'Best' shows your own comments made within the last 10 minutes first, then sorts by score
// replied to answers/comments are NOT newest, otherwise newest first
const shouldBeNewestFirst = (c: ContractComment) =>
c.replyToCommentId == undefined &&
(contract.outcomeType === 'FREE_RESPONSE'
? c.betId === undefined && c.answerOutcome == undefined
: true)
// TODO: links to comments are broken because tips load after render and
// comments will reorganize themselves if there are tips/bounties awarded
const sortedComments = sortBy(comments, [
sort === 'Best'
? (c) =>
// Is this too magic? If there are tips/bounties, 'Best' shows your own comments made within the last 10 minutes first, then sorts by score
tipsOrBountiesAwarded &&
c.createdTime > Date.now() - 10 * MINUTE_MS &&
c.userId === me?.id
c.userId === me?.id &&
shouldBeNewestFirst(c)
? -Infinity
: -((c.bountiesAwarded ?? 0) + sum(Object.values(tips[c.id] ?? [])))
)
: (c) => c,
(c) => (!shouldBeNewestFirst(c) ? c.createdTime : -c.createdTime),
])
const commentsByParent = groupBy(
sortedComments,
(c) => c.replyToCommentId ?? '_'
)
const topLevelComments = commentsByParent['_'] ?? []
// Top level comments are reverse-chronological, while replies are chronological
if (sort === 'Newest') topLevelComments.reverse()
if (contract.outcomeType === 'FREE_RESPONSE') {
const sortedAnswers = sortBy(
contract.answers,
(a) => -getOutcomeProbability(contract, a.id)
)
const commentsByOutcome = groupBy(
comments,
(c) => c.answerOutcome ?? c.betOutcome ?? '_'
)
const generalTopLevelComments = topLevelComments.filter(
(c) => c.answerOutcome === undefined && c.betId === undefined
)
return (
<>
{sortedAnswers.map((answer) => (
<div key={answer.id} className="relative pb-4">
<span
className="absolute top-5 left-5 -ml-px h-[calc(100%-2rem)] w-0.5 bg-gray-200"
aria-hidden="true"
/>
<FeedAnswerCommentGroup
contract={contract}
answer={answer}
answerComments={sortBy(
commentsByOutcome[answer.number.toString()] ?? [],
(c) => c.createdTime
)}
tips={tips}
/>
</div>
))}
<Col className="mt-8 flex w-full">
<div className="text-md mt-8 mb-2 text-left">General Comments</div>
<div className="mb-4 w-full border-b border-gray-200" />
<ContractCommentInput className="mb-5" contract={contract} />
{generalTopLevelComments.map((comment) => (
<FeedCommentThread
key={comment.id}
contract={contract}
parentComment={comment}
threadComments={commentsByParent[comment.id] ?? []}
tips={tips}
/>
))}
</Col>
</>
)
} else {
// TODO: links to comments are broken because tips load after render and
// comments will reorganize themselves if there are tips/bounties awarded
const tipsOrBountiesAwarded =
Object.keys(tips).length > 0 || comments.some((c) => c.bountiesAwarded)
const commentsByParent = groupBy(
sortBy(comments, (c) =>
sort === 'Newest'
? -c.createdTime
: // Is this too magic? If there are tips/bounties, 'Best' shows your own comments made within the last 10 minutes first, then sorts by score
tipsOrBountiesAwarded &&
c.createdTime > Date.now() - 10 * MINUTE_MS &&
c.userId === me?.id
? -Infinity
: -((c.bountiesAwarded ?? 0) + sum(Object.values(tips[c.id] ?? [])))
),
(c) => c.replyToCommentId ?? '_'
)
const topLevelComments = commentsByParent['_'] ?? []
return (
<>
<ContractCommentInput className="mb-5" contract={contract} />
{comments.length > 0 && (
const sortRow = comments.length > 0 && (
<Row className="mb-4 items-center">
<Button
size={'xs'}
@ -204,8 +142,60 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
<BountiedContractSmallBadge contract={contract} showAmount />
</Row>
)}
)
if (contract.outcomeType === 'FREE_RESPONSE') {
const sortedAnswers = sortBy(
contract.answers,
(a) => -getOutcomeProbability(contract, a.id)
)
const commentsByOutcome = groupBy(
sortedComments,
(c) => c.answerOutcome ?? c.betOutcome ?? '_'
)
const generalTopLevelComments = topLevelComments.filter(
(c) => c.answerOutcome === undefined && c.betId === undefined
)
return (
<>
{sortRow}
{sortedAnswers.map((answer) => (
<div key={answer.id} className="relative pb-4">
<span
className="absolute top-5 left-5 -ml-px h-[calc(100%-2rem)] w-0.5 bg-gray-200"
aria-hidden="true"
/>
<FeedAnswerCommentGroup
contract={contract}
answer={answer}
answerComments={commentsByOutcome[answer.number.toString()] ?? []}
tips={tips}
/>
</div>
))}
<Col className="mt-8 flex w-full">
<div className="text-md mt-8 mb-2 text-left">General Comments</div>
<div className="mb-4 w-full border-b border-gray-200" />
{sortRow}
<ContractCommentInput className="mb-5" contract={contract} />
{generalTopLevelComments.map((comment) => (
<FeedCommentThread
key={comment.id}
contract={contract}
parentComment={comment}
threadComments={commentsByParent[comment.id] ?? []}
tips={tips}
/>
))}
</Col>
</>
)
} else {
return (
<>
{sortRow}
<ContractCommentInput className="mb-5" contract={contract} />
{topLevelComments.map((parent) => (
<FeedCommentThread
key={parent.id}