adding replies toggle, filtering out responses that don't have replies

This commit is contained in:
ingawei 2022-10-04 20:33:26 -07:00
parent c115b5cca7
commit 8dd5b477d9
3 changed files with 99 additions and 65 deletions

View File

@ -0,0 +1,23 @@
import clsx from 'clsx'
import TriangleDownFillIcon from 'web/lib/icons/triangle-down-fill-icon'
import { Row } from '../layout/row'
export function ReplyToggle(props: {
seeReplies: boolean
numComments: number
onClick: () => void
}) {
const { seeReplies, numComments, onClick } = props
return (
<button className="text-left text-sm text-indigo-600" onClick={onClick}>
<Row className="items-center gap-1">
<div>
{numComments} {numComments === 1 ? 'Reply' : 'Replies'}
</div>
<TriangleDownFillIcon
className={clsx('h-2 w-2', seeReplies ? 'rotate-180' : '')}
/>
</Row>
</button>
)
}

View File

@ -36,6 +36,7 @@ import {
usePersistentState, usePersistentState,
} from 'web/hooks/use-persistent-state' } from 'web/hooks/use-persistent-state'
import { safeLocalStorage } from 'web/lib/util/local' import { safeLocalStorage } from 'web/lib/util/local'
import TriangleDownFillIcon from 'web/lib/icons/triangle-down-fill-icon'
export function ContractTabs(props: { export function ContractTabs(props: {
contract: Contract contract: Contract
@ -123,10 +124,12 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
const topLevelComments = commentsByParent['_'] ?? [] const topLevelComments = commentsByParent['_'] ?? []
const sortRow = comments.length > 0 && ( const sortRow = comments.length > 0 && (
<Row className="mb-4 items-center"> <Row className="mb-4 items-center justify-end gap-4">
<Button <BountiedContractSmallBadge contract={contract} showAmount />
size={'xs'} <Row className="items-center gap-1">
color={'gray-white'} <div className="text-greyscale-4 text-sm">Sort by:</div>
<button
className="text-greyscale-6 w-20 text-sm"
onClick={() => setSort(sort === 'Newest' ? 'Best' : 'Newest')} onClick={() => setSort(sort === 'Newest' ? 'Best' : 'Newest')}
> >
<Tooltip <Tooltip
@ -136,11 +139,13 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
: '' : ''
} }
> >
Sort by: {sort} <Row className="items-center gap-1">
{sort}
<TriangleDownFillIcon className=" h-2 w-2" />
</Row>
</Tooltip> </Tooltip>
</Button> </button>
</Row>
<BountiedContractSmallBadge contract={contract} showAmount />
</Row> </Row>
) )
@ -159,8 +164,13 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
return ( return (
<> <>
{sortRow} <Col className="flex w-full">
{sortedAnswers.map((answer) => ( <div className="mb-4 w-full border-gray-200" />
{sortedAnswers.map((answer) => {
const answerComments =
commentsByOutcome[answer.number.toString()] ?? []
if (answerComments.length > 0) {
return (
<div key={answer.id} className="relative pb-4"> <div key={answer.id} className="relative pb-4">
<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"
@ -169,14 +179,17 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
<FeedAnswerCommentGroup <FeedAnswerCommentGroup
contract={contract} contract={contract}
answer={answer} answer={answer}
answerComments={commentsByOutcome[answer.number.toString()] ?? []} answerComments={
commentsByOutcome[answer.number.toString()] ?? []
}
tips={tips} tips={tips}
/> />
</div> </div>
))} )
<Col className="mt-8 flex w-full"> } else {
<div className="text-md mt-8 mb-2 text-left">General Comments</div> return <></>
<div className="mb-4 w-full border-b border-gray-200" /> }
})}
{sortRow} {sortRow}
<ContractCommentInput className="mb-5" contract={contract} /> <ContractCommentInput className="mb-5" contract={contract} />
{generalTopLevelComments.map((comment) => ( {generalTopLevelComments.map((comment) => (

View File

@ -16,6 +16,8 @@ import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-ti
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { CommentTipMap } from 'web/hooks/use-tip-txns' import { CommentTipMap } from 'web/hooks/use-tip-txns'
import { UserLink } from 'web/components/user-link' import { UserLink } from 'web/components/user-link'
import TriangleDownFillIcon from 'web/lib/icons/triangle-down-fill-icon'
import { ReplyToggle } from '../comments/comments'
export function FeedAnswerCommentGroup(props: { export function FeedAnswerCommentGroup(props: {
contract: FreeResponseContract contract: FreeResponseContract
@ -26,6 +28,8 @@ export function FeedAnswerCommentGroup(props: {
const { answer, contract, answerComments, tips } = props const { answer, contract, answerComments, tips } = props
const { username, avatarUrl, name, text } = answer const { username, avatarUrl, name, text } = answer
const [seeReplies, setSeeReplies] = useState(false)
const [replyTo, setReplyTo] = useState<ReplyTo>() const [replyTo, setReplyTo] = useState<ReplyTo>()
const router = useRouter() const router = useRouter()
const answerElementId = `answer-${answer.id}` const answerElementId = `answer-${answer.id}`
@ -37,7 +41,6 @@ export function FeedAnswerCommentGroup(props: {
answerRef.current.scrollIntoView(true) answerRef.current.scrollIntoView(true)
} }
}, [highlighted]) }, [highlighted])
return ( return (
<Col className="relative flex-1 items-stretch gap-3"> <Col className="relative flex-1 items-stretch gap-3">
<Row <Row
@ -49,7 +52,6 @@ export function FeedAnswerCommentGroup(props: {
id={answerElementId} id={answerElementId}
> >
<Avatar username={username} avatarUrl={avatarUrl} /> <Avatar username={username} avatarUrl={avatarUrl} />
<Col className="min-w-0 flex-1 lg:gap-1"> <Col className="min-w-0 flex-1 lg:gap-1">
<div className="text-sm text-gray-500"> <div className="text-sm text-gray-500">
<UserLink username={username} name={name} /> answered <UserLink username={username} name={name} /> answered
@ -60,23 +62,11 @@ export function FeedAnswerCommentGroup(props: {
elementId={answerElementId} elementId={answerElementId}
/> />
</div> </div>
<Row className="align-items justify-between gap-2 sm:flex-row">
<Col className="align-items justify-between gap-2 sm:flex-row">
<span className="whitespace-pre-line text-lg"> <span className="whitespace-pre-line text-lg">
<Linkify text={text} /> <Linkify text={text} />
</span> </span>
<div className="sm:hidden"> <div>
<button
className="text-xs font-bold text-gray-500 hover:underline"
onClick={() =>
setReplyTo({ id: answer.id, username: answer.username })
}
>
Reply
</button>
</div>
</Col>
<div className="justify-initial hidden sm:block">
<button <button
className="text-xs font-bold text-gray-500 hover:underline" className="text-xs font-bold text-gray-500 hover:underline"
onClick={() => onClick={() =>
@ -86,8 +76,15 @@ export function FeedAnswerCommentGroup(props: {
Reply Reply
</button> </button>
</div> </div>
</Row>
<ReplyToggle
seeReplies={seeReplies}
numComments={answerComments.length}
onClick={() => setSeeReplies(!seeReplies)}
/>
</Col> </Col>
</Row> </Row>
{seeReplies && (
<Col className="gap-3 pl-1"> <Col className="gap-3 pl-1">
{answerComments.map((comment) => ( {answerComments.map((comment) => (
<FeedComment <FeedComment
@ -102,6 +99,7 @@ export function FeedAnswerCommentGroup(props: {
/> />
))} ))}
</Col> </Col>
)}
{replyTo && ( {replyTo && (
<div className="relative ml-7"> <div className="relative ml-7">
<span <span