Clean up a bunch of duplicated work in the comments list stuff
This commit is contained in:
parent
1758e9edc9
commit
8017e34110
|
@ -54,6 +54,13 @@ export function ContractTabs(props: {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const generalBets = outcomeType === 'FREE_RESPONSE' ? [] : visibleBets
|
||||||
|
const generalComments = comments.filter(
|
||||||
|
(comment) =>
|
||||||
|
comment.answerOutcome === undefined &&
|
||||||
|
(outcomeType === 'FREE_RESPONSE' ? comment.betId === undefined : true)
|
||||||
|
)
|
||||||
|
|
||||||
const commentActivity =
|
const commentActivity =
|
||||||
outcomeType === 'FREE_RESPONSE' ? (
|
outcomeType === 'FREE_RESPONSE' ? (
|
||||||
<>
|
<>
|
||||||
|
@ -69,8 +76,8 @@ export function ContractTabs(props: {
|
||||||
<div className={'mb-4 w-full border-b border-gray-200'} />
|
<div className={'mb-4 w-full border-b border-gray-200'} />
|
||||||
<ContractCommentsActivity
|
<ContractCommentsActivity
|
||||||
contract={contract}
|
contract={contract}
|
||||||
bets={visibleBets}
|
bets={generalBets}
|
||||||
comments={comments}
|
comments={generalComments}
|
||||||
tips={tips}
|
tips={tips}
|
||||||
user={user}
|
user={user}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { FeedCommentThread, CommentInput } from './feed-comments'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
||||||
import { LiquidityProvision } from 'common/liquidity-provision'
|
import { LiquidityProvision } from 'common/liquidity-provision'
|
||||||
import { sortBy, uniq } from 'lodash'
|
import { groupBy, sortBy, uniq } from 'lodash'
|
||||||
import { Col } from 'web/components/layout/col'
|
import { Col } from 'web/components/layout/col'
|
||||||
|
|
||||||
export function ContractBetsActivity(props: {
|
export function ContractBetsActivity(props: {
|
||||||
|
@ -62,47 +62,35 @@ export function ContractCommentsActivity(props: {
|
||||||
user: User | null | undefined
|
user: User | null | undefined
|
||||||
}) {
|
}) {
|
||||||
const { bets, contract, comments, user, tips } = props
|
const { bets, contract, comments, user, tips } = props
|
||||||
|
const betsByUserId = groupBy(bets, (bet) => bet.userId)
|
||||||
const nonFreeResponseComments = comments.filter(
|
const commentsByUserId = groupBy(comments, (c) => c.userId)
|
||||||
(comment) =>
|
const commentsByParentId = groupBy(comments, (c) => c.replyToCommentId ?? '_')
|
||||||
comment.answerOutcome === undefined &&
|
const topLevelComments = commentsByParentId['_'] ?? []
|
||||||
(contract.outcomeType === 'FREE_RESPONSE'
|
|
||||||
? comment.betId === undefined
|
|
||||||
: true)
|
|
||||||
)
|
|
||||||
const nonFreeResponseBets =
|
|
||||||
contract.outcomeType === 'FREE_RESPONSE' ? [] : bets
|
|
||||||
|
|
||||||
const betsByCurrentUser = nonFreeResponseBets.filter(
|
|
||||||
(bet) => bet.userId === user?.id
|
|
||||||
)
|
|
||||||
const commentsByCurrentUser = nonFreeResponseComments.filter(
|
|
||||||
(comment) => comment.userId === user?.id
|
|
||||||
)
|
|
||||||
|
|
||||||
const parentComments = comments.filter((comment) => !comment.replyToCommentId)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<CommentInput
|
<CommentInput
|
||||||
contract={contract}
|
contract={contract}
|
||||||
betsByCurrentUser={betsByCurrentUser}
|
betsByCurrentUser={(user && betsByUserId[user.id]) ?? []}
|
||||||
commentsByCurrentUser={commentsByCurrentUser}
|
commentsByCurrentUser={(user && commentsByUserId[user.id]) ?? []}
|
||||||
/>
|
/>
|
||||||
{parentComments.map((parent, idx) => (
|
{topLevelComments.map((parent, idx) => (
|
||||||
<div key={parent.id} className={'relative pb-4'}>
|
<div key={parent.id} className={'relative pb-4'}>
|
||||||
{idx !== parentComments.length - 1 ? (
|
{idx !== topLevelComments.length - 1 ? (
|
||||||
<span
|
<span
|
||||||
className="absolute top-5 left-5 -ml-px h-[calc(100%-2rem)] w-0.5 bg-gray-200"
|
className="absolute top-5 left-5 -ml-px h-[calc(100%-2rem)] w-0.5 bg-gray-200"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<FeedCommentThread
|
<FeedCommentThread
|
||||||
|
user={user}
|
||||||
contract={contract}
|
contract={contract}
|
||||||
parentComment={parent}
|
parentComment={parent}
|
||||||
comments={comments}
|
threadComments={commentsByParentId[parent.id] ?? []}
|
||||||
tips={tips}
|
tips={tips}
|
||||||
bets={bets}
|
bets={bets}
|
||||||
|
betsByUserId={betsByUserId}
|
||||||
|
commentsByUserId={commentsByUserId}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -130,6 +118,10 @@ export function FreeResponseContractCommentsActivity(props: {
|
||||||
})
|
})
|
||||||
.filter((answer) => answer != null)
|
.filter((answer) => answer != null)
|
||||||
|
|
||||||
|
const betsByUserId = groupBy(bets, (bet) => bet.userId)
|
||||||
|
const commentsByUserId = groupBy(comments, (c) => c.userId)
|
||||||
|
const commentsByOutcome = groupBy(comments, (c) => c.answerOutcome ?? '_')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{answers.map((answer) => (
|
{answers.map((answer) => (
|
||||||
|
@ -142,9 +134,11 @@ export function FreeResponseContractCommentsActivity(props: {
|
||||||
contract={contract}
|
contract={contract}
|
||||||
user={user}
|
user={user}
|
||||||
answer={answer}
|
answer={answer}
|
||||||
comments={comments}
|
answerComments={commentsByOutcome[answer.number.toString()]}
|
||||||
tips={tips}
|
tips={tips}
|
||||||
bets={bets}
|
bets={bets}
|
||||||
|
betsByUserId={betsByUserId}
|
||||||
|
commentsByUserId={commentsByUserId}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Answer } from 'common/answer'
|
import { Answer } from 'common/answer'
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
|
import { FreeResponseContract } from 'common/contract'
|
||||||
import { ContractComment } from 'common/comment'
|
import { ContractComment } from 'common/comment'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { Col } from 'web/components/layout/col'
|
import { Col } from 'web/components/layout/col'
|
||||||
|
@ -15,20 +16,31 @@ import {
|
||||||
} from 'web/components/feed/feed-comments'
|
} from 'web/components/feed/feed-comments'
|
||||||
import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-time'
|
import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-time'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { groupBy } from 'lodash'
|
import { Dictionary } from 'lodash'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { useEvent } from 'web/hooks/use-event'
|
import { useEvent } from 'web/hooks/use-event'
|
||||||
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
||||||
|
|
||||||
export function FeedAnswerCommentGroup(props: {
|
export function FeedAnswerCommentGroup(props: {
|
||||||
contract: any
|
contract: FreeResponseContract
|
||||||
user: User | undefined | null
|
user: User | undefined | null
|
||||||
answer: Answer
|
answer: Answer
|
||||||
comments: ContractComment[]
|
answerComments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
|
betsByUserId: Dictionary<Bet[]>
|
||||||
|
commentsByUserId: Dictionary<ContractComment[]>
|
||||||
}) {
|
}) {
|
||||||
const { answer, contract, comments, tips, bets, user } = props
|
const {
|
||||||
|
answer,
|
||||||
|
contract,
|
||||||
|
answerComments,
|
||||||
|
tips,
|
||||||
|
bets,
|
||||||
|
betsByUserId,
|
||||||
|
commentsByUserId,
|
||||||
|
user,
|
||||||
|
} = props
|
||||||
const { username, avatarUrl, name, text } = answer
|
const { username, avatarUrl, name, text } = answer
|
||||||
|
|
||||||
const [replyToUser, setReplyToUser] =
|
const [replyToUser, setReplyToUser] =
|
||||||
|
@ -38,11 +50,6 @@ export function FeedAnswerCommentGroup(props: {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const answerElementId = `answer-${answer.id}`
|
const answerElementId = `answer-${answer.id}`
|
||||||
const betsByUserId = groupBy(bets, (bet) => bet.userId)
|
|
||||||
const commentsByUserId = groupBy(comments, (comment) => comment.userId)
|
|
||||||
const commentsList = comments.filter(
|
|
||||||
(comment) => comment.answerOutcome === answer.number.toString()
|
|
||||||
)
|
|
||||||
const betsByCurrentUser = (user && betsByUserId[user.id]) ?? []
|
const betsByCurrentUser = (user && betsByUserId[user.id]) ?? []
|
||||||
const commentsByCurrentUser = (user && commentsByUserId[user.id]) ?? []
|
const commentsByCurrentUser = (user && commentsByUserId[user.id]) ?? []
|
||||||
const isFreeResponseContractPage = !!commentsByCurrentUser
|
const isFreeResponseContractPage = !!commentsByCurrentUser
|
||||||
|
@ -155,7 +162,7 @@ export function FeedAnswerCommentGroup(props: {
|
||||||
</Row>
|
</Row>
|
||||||
<CommentRepliesList
|
<CommentRepliesList
|
||||||
contract={contract}
|
contract={contract}
|
||||||
commentsList={commentsList}
|
comments={answerComments}
|
||||||
betsByUserId={betsByUserId}
|
betsByUserId={betsByUserId}
|
||||||
smallAvatar={true}
|
smallAvatar={true}
|
||||||
bets={bets}
|
bets={bets}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ContractComment } from 'common/comment'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { Contract } from 'common/contract'
|
import { Contract } from 'common/contract'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { minBy, maxBy, groupBy, partition, sumBy, Dictionary } from 'lodash'
|
import { minBy, maxBy, partition, sumBy, Dictionary } from 'lodash'
|
||||||
import { useUser } from 'web/hooks/use-user'
|
import { useUser } from 'web/hooks/use-user'
|
||||||
import { formatMoney } from 'common/util/format'
|
import { formatMoney } from 'common/util/format'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
@ -31,28 +31,30 @@ import { Content, TextEditor, useTextEditor } from '../editor'
|
||||||
import { Editor } from '@tiptap/react'
|
import { Editor } from '@tiptap/react'
|
||||||
|
|
||||||
export function FeedCommentThread(props: {
|
export function FeedCommentThread(props: {
|
||||||
|
user: User | null | undefined
|
||||||
contract: Contract
|
contract: Contract
|
||||||
comments: ContractComment[]
|
threadComments: ContractComment[]
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
parentComment: ContractComment
|
parentComment: ContractComment
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
|
betsByUserId: Dictionary<Bet[]>
|
||||||
|
commentsByUserId: Dictionary<ContractComment[]>
|
||||||
}) {
|
}) {
|
||||||
const { contract, comments, bets, tips, parentComment } = props
|
const {
|
||||||
|
user,
|
||||||
|
contract,
|
||||||
|
threadComments,
|
||||||
|
commentsByUserId,
|
||||||
|
bets,
|
||||||
|
betsByUserId,
|
||||||
|
tips,
|
||||||
|
parentComment,
|
||||||
|
} = props
|
||||||
const [showReply, setShowReply] = useState(false)
|
const [showReply, setShowReply] = useState(false)
|
||||||
const [replyToUser, setReplyToUser] = useState<{
|
const [replyTo, setReplyTo] = useState<{ id: string; username: string }>()
|
||||||
id: string
|
|
||||||
username: string
|
|
||||||
}>()
|
|
||||||
const betsByUserId = groupBy(bets, (bet) => bet.userId)
|
|
||||||
const user = useUser()
|
|
||||||
const commentsList = comments.filter(
|
|
||||||
(comment) =>
|
|
||||||
parentComment.id && comment.replyToCommentId === parentComment.id
|
|
||||||
)
|
|
||||||
commentsList.unshift(parentComment)
|
|
||||||
|
|
||||||
function scrollAndOpenReplyInput(comment: ContractComment) {
|
function scrollAndOpenReplyInput(comment: ContractComment) {
|
||||||
setReplyToUser({ id: comment.userId, username: comment.userUsername })
|
setReplyTo({ id: comment.userId, username: comment.userUsername })
|
||||||
setShowReply(true)
|
setShowReply(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +66,7 @@ export function FeedCommentThread(props: {
|
||||||
/>
|
/>
|
||||||
<CommentRepliesList
|
<CommentRepliesList
|
||||||
contract={contract}
|
contract={contract}
|
||||||
commentsList={commentsList}
|
comments={[parentComment].concat(threadComments)}
|
||||||
betsByUserId={betsByUserId}
|
betsByUserId={betsByUserId}
|
||||||
tips={tips}
|
tips={tips}
|
||||||
bets={bets}
|
bets={bets}
|
||||||
|
@ -79,12 +81,10 @@ export function FeedCommentThread(props: {
|
||||||
<CommentInput
|
<CommentInput
|
||||||
contract={contract}
|
contract={contract}
|
||||||
betsByCurrentUser={(user && betsByUserId[user.id]) ?? []}
|
betsByCurrentUser={(user && betsByUserId[user.id]) ?? []}
|
||||||
commentsByCurrentUser={comments.filter(
|
commentsByCurrentUser={(user && commentsByUserId[user.id]) ?? []}
|
||||||
(c) => c.userId === user?.id
|
|
||||||
)}
|
|
||||||
parentCommentId={parentComment.id}
|
parentCommentId={parentComment.id}
|
||||||
replyToUser={replyToUser}
|
replyToUser={replyTo}
|
||||||
parentAnswerOutcome={comments[0].answerOutcome}
|
parentAnswerOutcome={parentComment.answerOutcome}
|
||||||
onSubmitComment={() => setShowReply(false)}
|
onSubmitComment={() => setShowReply(false)}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -95,7 +95,7 @@ export function FeedCommentThread(props: {
|
||||||
|
|
||||||
export function CommentRepliesList(props: {
|
export function CommentRepliesList(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
commentsList: ContractComment[]
|
comments: ContractComment[]
|
||||||
betsByUserId: Dictionary<Bet[]>
|
betsByUserId: Dictionary<Bet[]>
|
||||||
tips: CommentTipMap
|
tips: CommentTipMap
|
||||||
scrollAndOpenReplyInput: (comment: ContractComment) => void
|
scrollAndOpenReplyInput: (comment: ContractComment) => void
|
||||||
|
@ -105,7 +105,7 @@ export function CommentRepliesList(props: {
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
contract,
|
contract,
|
||||||
commentsList,
|
comments,
|
||||||
betsByUserId,
|
betsByUserId,
|
||||||
tips,
|
tips,
|
||||||
smallAvatar,
|
smallAvatar,
|
||||||
|
@ -115,7 +115,7 @@ export function CommentRepliesList(props: {
|
||||||
} = props
|
} = props
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{commentsList.map((comment, commentIdx) => (
|
{comments.map((comment, commentIdx) => (
|
||||||
<div
|
<div
|
||||||
key={comment.id}
|
key={comment.id}
|
||||||
id={comment.id}
|
id={comment.id}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user