2022-05-17 15:55:26 +00:00
|
|
|
import { Answer } from 'common/answer'
|
2022-10-14 05:07:54 +00:00
|
|
|
import {
|
|
|
|
Contract,
|
|
|
|
FreeResponseContract,
|
|
|
|
MultipleChoiceContract,
|
|
|
|
} from 'common/contract'
|
|
|
|
import React, { useEffect, useRef, useState } from 'react'
|
2022-05-17 15:55:26 +00:00
|
|
|
import { Col } from 'web/components/layout/col'
|
|
|
|
import { Row } from 'web/components/layout/row'
|
|
|
|
import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-time'
|
|
|
|
import { useRouter } from 'next/router'
|
2022-08-30 15:38:59 +00:00
|
|
|
import { UserLink } from 'web/components/user-link'
|
2022-10-14 05:07:54 +00:00
|
|
|
import { FeedCommentThread } from './feed-comments'
|
|
|
|
import { AnswerCommentInput } from '../comment-input'
|
|
|
|
import { ContractComment } from 'common/comment'
|
|
|
|
import { Dictionary, sortBy } from 'lodash'
|
|
|
|
import { getAnswerColor } from '../answers/answers-panel'
|
|
|
|
import Curve from 'web/public/custom-components/curve'
|
|
|
|
import { CommentTipMap } from 'web/hooks/use-tip-txns'
|
|
|
|
import { useChartAnswers } from '../charts/contract/choice'
|
2022-05-17 15:55:26 +00:00
|
|
|
|
2022-10-14 05:07:54 +00:00
|
|
|
export function CommentsAnswer(props: {
|
|
|
|
answer: Answer
|
|
|
|
contract: Contract
|
|
|
|
color: string
|
|
|
|
}) {
|
|
|
|
const { answer, contract, color } = props
|
|
|
|
const { username, name, text } = answer
|
2022-05-17 15:55:26 +00:00
|
|
|
const answerElementId = `answer-${answer.id}`
|
2022-10-14 05:07:54 +00:00
|
|
|
|
|
|
|
const { isReady, asPath } = useRouter()
|
|
|
|
const [highlighted, setHighlighted] = useState(false)
|
2022-09-22 19:58:40 +00:00
|
|
|
const answerRef = useRef<HTMLDivElement>(null)
|
2022-06-08 23:09:49 +00:00
|
|
|
|
2022-05-17 15:55:26 +00:00
|
|
|
useEffect(() => {
|
2022-10-14 05:07:54 +00:00
|
|
|
if (isReady && asPath.endsWith(`#${answerElementId}`)) {
|
|
|
|
setHighlighted(true)
|
|
|
|
}
|
|
|
|
}, [isReady, asPath, answerElementId])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (highlighted && answerRef.current) {
|
2022-09-22 19:58:40 +00:00
|
|
|
answerRef.current.scrollIntoView(true)
|
2022-05-17 15:55:26 +00:00
|
|
|
}
|
2022-09-22 19:58:40 +00:00
|
|
|
}, [highlighted])
|
2022-05-17 15:55:26 +00:00
|
|
|
|
|
|
|
return (
|
2022-10-14 05:07:54 +00:00
|
|
|
<Row>
|
|
|
|
<div
|
|
|
|
className="w-2"
|
|
|
|
style={{
|
|
|
|
background: color ? color : '#B1B1C7',
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<Col className="w-fit bg-gray-100 py-1 pl-2 pr-2">
|
|
|
|
<Row className="gap-2">
|
|
|
|
<div className="text-greyscale-4 text-xs">
|
|
|
|
<UserLink username={username} name={name} /> answered
|
|
|
|
<CopyLinkDateTimeComponent
|
|
|
|
prefix={contract.creatorUsername}
|
|
|
|
slug={contract.slug}
|
|
|
|
createdTime={answer.createdTime}
|
|
|
|
elementId={answerElementId}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</Row>
|
|
|
|
<div className="text-sm">{text}</div>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export function FreeResponseComments(props: {
|
|
|
|
contract: FreeResponseContract | MultipleChoiceContract
|
|
|
|
answerResponse: Answer | undefined
|
|
|
|
onCancelAnswerResponse?: () => void
|
|
|
|
topLevelComments: ContractComment[]
|
|
|
|
commentsByParent: Dictionary<[ContractComment, ...ContractComment[]]>
|
|
|
|
tips: CommentTipMap
|
|
|
|
}) {
|
|
|
|
const {
|
|
|
|
contract,
|
|
|
|
answerResponse,
|
|
|
|
onCancelAnswerResponse,
|
|
|
|
topLevelComments,
|
|
|
|
commentsByParent,
|
|
|
|
tips,
|
|
|
|
} = props
|
|
|
|
const answersArray = useChartAnswers(contract).map((answer) => answer.text)
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{answerResponse && (
|
|
|
|
<AnswerCommentInput
|
|
|
|
contract={contract}
|
|
|
|
answerResponse={answerResponse}
|
|
|
|
onCancelAnswerResponse={onCancelAnswerResponse}
|
|
|
|
answersArray={answersArray}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
{topLevelComments.map((parent) => {
|
|
|
|
if (parent.answerOutcome === undefined) {
|
|
|
|
return (
|
|
|
|
<FeedCommentThread
|
|
|
|
key={parent.id}
|
|
|
|
contract={contract}
|
|
|
|
parentComment={parent}
|
|
|
|
threadComments={sortBy(
|
|
|
|
commentsByParent[parent.id] ?? [],
|
|
|
|
(c) => c.createdTime
|
|
|
|
)}
|
|
|
|
tips={tips}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
const answer = contract.answers.find(
|
|
|
|
(answer) => answer.id === parent.answerOutcome
|
|
|
|
)
|
|
|
|
if (answer === undefined) {
|
|
|
|
console.error('Could not find answer that matches ID')
|
|
|
|
return <></>
|
|
|
|
}
|
|
|
|
const color = getAnswerColor(answer, answersArray)
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Row className="relative">
|
|
|
|
<div className="absolute -bottom-1 left-1.5">
|
|
|
|
<Curve size={32} strokeWidth={1} color="#D8D8EB" />
|
|
|
|
</div>
|
|
|
|
<div className="ml-[38px]">
|
|
|
|
<CommentsAnswer
|
|
|
|
answer={answer}
|
|
|
|
contract={contract}
|
|
|
|
color={color}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</Row>
|
|
|
|
<div className="w-full pt-1">
|
|
|
|
<FeedCommentThread
|
|
|
|
key={parent.id}
|
|
|
|
contract={contract}
|
|
|
|
parentComment={parent}
|
|
|
|
threadComments={sortBy(
|
|
|
|
commentsByParent[parent.id] ?? [],
|
|
|
|
(c) => c.createdTime
|
|
|
|
)}
|
|
|
|
tips={tips}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
})}
|
|
|
|
</>
|
2022-05-17 15:55:26 +00:00
|
|
|
)
|
|
|
|
}
|