made a custom component, beautiful curve thingy

This commit is contained in:
ingawei 2022-10-06 17:51:58 -07:00
parent 7e29733144
commit c8d2e19c3e
3 changed files with 35 additions and 137 deletions

View File

@ -3,7 +3,7 @@ import { getOutcomeProbability } from 'common/calculate'
import { Pagination } from 'web/components/pagination'
import { FeedBet } from '../feed/feed-bets'
import { FeedLiquidity } from '../feed/feed-liquidity'
import { FeedAnswerCommentGroup } from '../feed/feed-answer-comment-group'
import { CommentsAnswer } from '../feed/feed-answer-comment-group'
import { FeedCommentThread, ContractCommentInput } from '../feed/feed-comments'
import { groupBy, sortBy, sum } from 'lodash'
import { Bet } from 'common/bet'
@ -157,59 +157,22 @@ const CommentsTabContent = memo(function CommentsTabContent(props: {
)
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
// )
// console.log('answer: ', sortedAnswers)
// console.log('comments by outcome:', commentsByOutcome)
return (
<>
{sortRow}
<ContractCommentInput className="mb-5" contract={contract} />
{topLevelComments.map((parent) => {
if (parent.answerOutcome != undefined) {
const answer = sortedAnswers.find(
const answer = contract.answers.find(
(answer) => answer.id === parent.answerOutcome
)
if (answer === undefined) {
console.error('Could not find answer that matches ID')
return <></>
} else {
const { username, avatarUrl, name, text } = answer
const answerElementId = `answer-${answer.id}`
return (
<>
<Row className="bg-greyscale-2 w-fit gap-1 rounded-t-xl rounded-bl-xl px-2 py-2">
<div className="ml-2">
<Avatar
username={username}
avatarUrl={avatarUrl}
size="xxs"
/>
</div>
<Col>
<Row className="gap-1">
<div className="text-greyscale-6 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-greyscale-7 text-sm">{text}</div>
</Col>
</Row>
<CommentsAnswer answer={answer} contract={contract} />
<Row>
<div className="ml-2">
<Curve size={28} strokeWidth={1} color="#B1B1C7" />

View File

@ -1,5 +1,5 @@
import { Answer } from 'common/answer'
import { FreeResponseContract } from 'common/contract'
import { Contract, FreeResponseContract } from 'common/contract'
import { ContractComment } from 'common/comment'
import React, { useEffect, useRef, useState } from 'react'
import { Col } from 'web/components/layout/col'
@ -20,40 +20,17 @@ import TriangleDownFillIcon from 'web/lib/icons/triangle-down-fill-icon'
import { ReplyToggle } from '../comments/comments'
import { ReplyIcon } from '@heroicons/react/solid'
export function FeedAnswerCommentGroup(props: {
contract: FreeResponseContract
answer: Answer
answerComments: ContractComment[]
tips: CommentTipMap
}) {
const { answer, contract, answerComments, tips } = props
export function CommentsAnswer(props: { answer: Answer; contract: Contract }) {
const { answer, contract } = props
const { username, avatarUrl, name, text } = answer
const [seeReplies, setSeeReplies] = useState(false)
const [replyTo, setReplyTo] = useState<ReplyTo>()
const router = useRouter()
const answerElementId = `answer-${answer.id}`
const highlighted = router.asPath.endsWith(`#${answerElementId}`)
const answerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
if (highlighted && answerRef.current != null) {
answerRef.current.scrollIntoView(true)
}
}, [highlighted])
return (
<Col className="relative flex-1 items-stretch gap-3">
<Row
className={clsx(
'gap- space-x-3 pt-4 transition-all duration-1000',
highlighted ? `-m-2 my-3 rounded bg-indigo-500/[0.2] p-2` : ''
)}
ref={answerRef}
id={answerElementId}
>
<Avatar username={username} avatarUrl={avatarUrl} size="sm" />
<Col className="min-w-0 flex-1">
<Row className="bg-greyscale-2 w-fit gap-1 rounded-t-xl rounded-bl-xl px-2 py-2">
<div className="ml-2">
<Avatar username={username} avatarUrl={avatarUrl} size="xxs" />
</div>
<Col>
<Row className="gap-1">
<div className="text-greyscale-6 text-xs">
<UserLink username={username} name={name} /> answered
<CopyLinkDateTimeComponent
@ -63,70 +40,9 @@ export function FeedAnswerCommentGroup(props: {
elementId={answerElementId}
/>
</div>
{/* <Row className="align-items justify-between gap-2 sm:flex-row"> */}
<span className="text-md whitespace-pre-line">
<Linkify text={text} />
</span>
{/* <div>
<button
className="text-xs font-bold text-gray-500 hover:underline"
onClick={() =>
setReplyTo({ id: answer.id, username: answer.username })
}
>
Reply
</button>
</div> */}
{/* </Row> */}
<Row className="w-full">
<ReplyToggle
seeReplies={seeReplies}
numComments={answerComments.length}
onClick={() => setSeeReplies(!seeReplies)}
/>
<div className="justify-self-end">
<button
className="text-greyscale-5"
onClick={() =>
setReplyTo({ id: answer.id, username: answer.username })
}
>
<ReplyIcon className="h-5 w-5" />
</button>
</div>
</Row>
</Col>
</Row>
{seeReplies && (
<Col className="w-full gap-3 pl-1">
{answerComments.map((comment) => (
<FeedComment
key={comment.id}
indent={true}
contract={contract}
comment={comment}
tips={tips[comment.id] ?? {}}
onReplyClick={() =>
setReplyTo({ id: comment.id, username: comment.userUsername })
}
/>
))}
</Col>
)}
{replyTo && (
<div className="relative ml-7">
<span
className="bg-greyscale-2 absolute -left-1 -ml-[1px] mt-[1.25rem] h-2 w-0.5 rotate-90"
aria-hidden="true"
/>
<ContractCommentInput
contract={contract}
parentAnswerOutcome={answer.number.toString()}
replyTo={replyTo}
onSubmitComment={() => setReplyTo(undefined)}
/>
</div>
)}
</Col>
</Row>
<div className="text-greyscale-7 text-sm">{text}</div>
</Col>
</Row>
)
}

View File

@ -0,0 +1,19 @@
export default function Curve({
size = 24,
color = '#B1B1C7',
strokeWidth = 2,
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 18 18"
width={size}
height={size}
fill="none"
stroke={color}
stroke-width={strokeWidth}
>
<path d="M5.02,0V5.24c0,4.3,3.49,7.79,7.79,7.79h5.2" />
</svg>
)
}