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,24 +93,56 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
const tipsOrBountiesAwarded = const tipsOrBountiesAwarded =
Object.keys(tips).length > 0 || comments.some((c) => c.bountiesAwarded) Object.keys(tips).length > 0 || comments.some((c) => c.bountiesAwarded)
const sortedComments = sortBy(comments, (c) => // replied to answers/comments are NOT newest, otherwise newest first
sort === 'Newest' const shouldBeNewestFirst = (c: ContractComment) =>
? c.createdTime c.replyToCommentId == undefined &&
: // 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 (contract.outcomeType === 'FREE_RESPONSE'
tipsOrBountiesAwarded && ? c.betId === undefined && c.answerOutcome == undefined
c.createdTime > Date.now() - 10 * MINUTE_MS && : true)
c.userId === me?.id
? -Infinity // TODO: links to comments are broken because tips load after render and
: -((c.bountiesAwarded ?? 0) + sum(Object.values(tips[c.id] ?? []))) // 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 &&
shouldBeNewestFirst(c)
? -Infinity
: -((c.bountiesAwarded ?? 0) + sum(Object.values(tips[c.id] ?? [])))
: (c) => c,
(c) => (!shouldBeNewestFirst(c) ? c.createdTime : -c.createdTime),
])
const commentsByParent = groupBy( const commentsByParent = groupBy(
sortedComments, sortedComments,
(c) => c.replyToCommentId ?? '_' (c) => c.replyToCommentId ?? '_'
) )
const topLevelComments = commentsByParent['_'] ?? [] const topLevelComments = commentsByParent['_'] ?? []
// Top level comments are reverse-chronological, while replies are chronological
if (sort === 'Newest') topLevelComments.reverse() const sortRow = comments.length > 0 && (
<Row className="mb-4 items-center">
<Button
size={'xs'}
color={'gray-white'}
onClick={() => setSort(sort === 'Newest' ? 'Best' : 'Newest')}
>
<Tooltip
text={
sort === 'Best'
? 'Highest tips + bounties first. Your new comments briefly appear to you first.'
: ''
}
>
Sort by: {sort}
</Tooltip>
</Button>
<BountiedContractSmallBadge contract={contract} showAmount />
</Row>
)
if (contract.outcomeType === 'FREE_RESPONSE') { if (contract.outcomeType === 'FREE_RESPONSE') {
const sortedAnswers = sortBy( const sortedAnswers = sortBy(
@ -118,14 +150,16 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
(a) => -getOutcomeProbability(contract, a.id) (a) => -getOutcomeProbability(contract, a.id)
) )
const commentsByOutcome = groupBy( const commentsByOutcome = groupBy(
comments, 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 (
<> <>
{sortRow}
{sortedAnswers.map((answer) => ( {sortedAnswers.map((answer) => (
<div key={answer.id} className="relative pb-4"> <div key={answer.id} className="relative pb-4">
<span <span
@ -135,10 +169,7 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
<FeedAnswerCommentGroup <FeedAnswerCommentGroup
contract={contract} contract={contract}
answer={answer} answer={answer}
answerComments={sortBy( answerComments={commentsByOutcome[answer.number.toString()] ?? []}
commentsByOutcome[answer.number.toString()] ?? [],
(c) => c.createdTime
)}
tips={tips} tips={tips}
/> />
</div> </div>
@ -146,6 +177,7 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
<Col className="mt-8 flex w-full"> <Col className="mt-8 flex w-full">
<div className="text-md mt-8 mb-2 text-left">General Comments</div> <div className="text-md mt-8 mb-2 text-left">General Comments</div>
<div className="mb-4 w-full border-b border-gray-200" /> <div className="mb-4 w-full border-b border-gray-200" />
{sortRow}
<ContractCommentInput className="mb-5" contract={contract} /> <ContractCommentInput className="mb-5" contract={contract} />
{generalTopLevelComments.map((comment) => ( {generalTopLevelComments.map((comment) => (
<FeedCommentThread <FeedCommentThread
@ -160,52 +192,10 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
</> </>
) )
} else { } 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 ( return (
<> <>
{sortRow}
<ContractCommentInput className="mb-5" contract={contract} /> <ContractCommentInput className="mb-5" contract={contract} />
{comments.length > 0 && (
<Row className="mb-4 items-center">
<Button
size={'xs'}
color={'gray-white'}
onClick={() => setSort(sort === 'Newest' ? 'Best' : 'Newest')}
>
<Tooltip
text={
sort === 'Best'
? 'Highest tips + bounties first. Your new comments briefly appear to you first.'
: ''
}
>
Sort by: {sort}
</Tooltip>
</Button>
<BountiedContractSmallBadge contract={contract} showAmount />
</Row>
)}
{topLevelComments.map((parent) => ( {topLevelComments.map((parent) => (
<FeedCommentThread <FeedCommentThread
key={parent.id} key={parent.id}