Eliminate redundant showReply/replyTo state (#917)

This commit is contained in:
Marshall Polaris 2022-09-22 12:40:44 -07:00 committed by GitHub
parent 6fe0a22a48
commit 6ee8d90bdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 51 deletions

View File

@ -11,7 +11,7 @@ import { Row } from './layout/row'
import { LoadingIndicator } from './loading-indicator'
export function CommentInput(props: {
replyToUser?: { id: string; username: string }
replyTo?: { id: string; username: string }
// Reply to a free response answer
parentAnswerOutcome?: string
// Reply to another comment
@ -19,7 +19,7 @@ export function CommentInput(props: {
onSubmitComment?: (editor: Editor) => void
className?: string
}) {
const { parentAnswerOutcome, parentCommentId, replyToUser, onSubmitComment } =
const { parentAnswerOutcome, parentCommentId, replyTo, onSubmitComment } =
props
const user = useUser()
@ -55,7 +55,7 @@ export function CommentInput(props: {
<CommentInputTextArea
editor={editor}
upload={upload}
replyToUser={replyToUser}
replyTo={replyTo}
user={user}
submitComment={submitComment}
isSubmitting={isSubmitting}
@ -67,14 +67,13 @@ export function CommentInput(props: {
export function CommentInputTextArea(props: {
user: User | undefined | null
replyToUser?: { id: string; username: string }
replyTo?: { id: string; username: string }
editor: Editor | null
upload: Parameters<typeof TextEditor>[0]['upload']
submitComment: () => void
isSubmitting: boolean
}) {
const { user, editor, upload, submitComment, isSubmitting, replyToUser } =
props
const { user, editor, upload, submitComment, isSubmitting, replyTo } = props
useEffect(() => {
editor?.setEditable(!isSubmitting)
}, [isSubmitting, editor])
@ -108,12 +107,12 @@ export function CommentInputTextArea(props: {
},
})
// insert at mention and focus
if (replyToUser) {
if (replyTo) {
editor
.chain()
.setContent({
type: 'mention',
attrs: { label: replyToUser.username, id: replyToUser.id },
attrs: { label: replyTo.username, id: replyTo.id },
})
.insertContent(' ')
.focus()

View File

@ -10,11 +10,10 @@ import clsx from 'clsx'
import {
ContractCommentInput,
FeedComment,
ReplyTo,
} from 'web/components/feed/feed-comments'
import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-time'
import { useRouter } from 'next/router'
import { User } from 'common/user'
import { useEvent } from 'web/hooks/use-event'
import { CommentTipMap } from 'web/hooks/use-tip-txns'
import { UserLink } from 'web/components/user-link'
@ -27,27 +26,11 @@ export function FeedAnswerCommentGroup(props: {
const { answer, contract, answerComments, tips } = props
const { username, avatarUrl, name, text } = answer
const [replyToUser, setReplyToUser] =
useState<Pick<User, 'id' | 'username'>>()
const [showReply, setShowReply] = useState(false)
const [replyTo, setReplyTo] = useState<ReplyTo>()
const [highlighted, setHighlighted] = useState(false)
const router = useRouter()
const answerElementId = `answer-${answer.id}`
const scrollAndOpenReplyInput = useEvent(
(comment?: ContractComment, answer?: Answer) => {
setReplyToUser(
comment
? { id: comment.userId, username: comment.userUsername }
: answer
? { id: answer.userId, username: answer.username }
: undefined
)
setShowReply(true)
}
)
useEffect(() => {
if (router.asPath.endsWith(`#${answerElementId}`)) {
setHighlighted(true)
@ -83,7 +66,9 @@ export function FeedAnswerCommentGroup(props: {
<div className="sm:hidden">
<button
className="text-xs font-bold text-gray-500 hover:underline"
onClick={() => scrollAndOpenReplyInput(undefined, answer)}
onClick={() =>
setReplyTo({ id: answer.id, username: answer.username })
}
>
Reply
</button>
@ -92,7 +77,9 @@ export function FeedAnswerCommentGroup(props: {
<div className="justify-initial hidden sm:block">
<button
className="text-xs font-bold text-gray-500 hover:underline"
onClick={() => scrollAndOpenReplyInput(undefined, answer)}
onClick={() =>
setReplyTo({ id: answer.id, username: answer.username })
}
>
Reply
</button>
@ -107,11 +94,13 @@ export function FeedAnswerCommentGroup(props: {
contract={contract}
comment={comment}
tips={tips[comment.id] ?? {}}
onReplyClick={scrollAndOpenReplyInput}
onReplyClick={() =>
setReplyTo({ id: comment.id, username: comment.userUsername })
}
/>
))}
</Col>
{showReply && (
{replyTo && (
<div className="relative ml-7">
<span
className="absolute -left-1 -ml-[1px] mt-[1.25rem] h-2 w-0.5 rotate-90 bg-gray-200"
@ -120,8 +109,8 @@ export function FeedAnswerCommentGroup(props: {
<ContractCommentInput
contract={contract}
parentAnswerOutcome={answer.number.toString()}
replyToUser={replyToUser}
onSubmitComment={() => setShowReply(false)}
replyTo={replyTo}
onSubmitComment={() => setReplyTo(undefined)}
/>
</div>
)}

View File

@ -20,6 +20,8 @@ import { Editor } from '@tiptap/react'
import { UserLink } from 'web/components/user-link'
import { CommentInput } from '../comment-input'
export type ReplyTo = { id: string; username: string }
export function FeedCommentThread(props: {
contract: Contract
threadComments: ContractComment[]
@ -27,13 +29,7 @@ export function FeedCommentThread(props: {
parentComment: ContractComment
}) {
const { contract, threadComments, tips, parentComment } = props
const [showReply, setShowReply] = useState(false)
const [replyTo, setReplyTo] = useState<{ id: string; username: string }>()
function scrollAndOpenReplyInput(comment: ContractComment) {
setReplyTo({ id: comment.userId, username: comment.userUsername })
setShowReply(true)
}
const [replyTo, setReplyTo] = useState<ReplyTo>()
return (
<Col className="relative w-full items-stretch gap-3 pb-4">
@ -48,10 +44,12 @@ export function FeedCommentThread(props: {
contract={contract}
comment={comment}
tips={tips[comment.id] ?? {}}
onReplyClick={scrollAndOpenReplyInput}
onReplyClick={() =>
setReplyTo({ id: comment.id, username: comment.userUsername })
}
/>
))}
{showReply && (
{replyTo && (
<Col className="-pb-2 relative ml-6">
<span
className="absolute -left-1 -ml-[1px] mt-[0.8rem] h-2 w-0.5 rotate-90 bg-gray-200"
@ -60,10 +58,8 @@ export function FeedCommentThread(props: {
<ContractCommentInput
contract={contract}
parentCommentId={parentComment.id}
replyToUser={replyTo}
onSubmitComment={() => {
setShowReply(false)
}}
replyTo={replyTo}
onSubmitComment={() => setReplyTo(undefined)}
/>
</Col>
)}
@ -76,7 +72,7 @@ export function FeedComment(props: {
comment: ContractComment
tips?: CommentTips
indent?: boolean
onReplyClick?: (comment: ContractComment) => void
onReplyClick?: () => void
}) {
const { contract, comment, tips, indent, onReplyClick } = props
const {
@ -174,7 +170,7 @@ export function FeedComment(props: {
{onReplyClick && (
<button
className="font-bold hover:underline"
onClick={() => onReplyClick(comment)}
onClick={onReplyClick}
>
Reply
</button>
@ -204,7 +200,7 @@ export function ContractCommentInput(props: {
contract: Contract
className?: string
parentAnswerOutcome?: string | undefined
replyToUser?: { id: string; username: string }
replyTo?: ReplyTo
parentCommentId?: string
onSubmitComment?: () => void
}) {
@ -226,7 +222,7 @@ export function ContractCommentInput(props: {
return (
<CommentInput
replyToUser={props.replyToUser}
replyTo={props.replyTo}
parentAnswerOutcome={props.parentAnswerOutcome}
parentCommentId={props.parentCommentId}
onSubmitComment={onSubmitComment}

View File

@ -92,7 +92,7 @@ export function PostCommentInput(props: {
return (
<CommentInput
replyToUser={replyToUser}
replyTo={replyToUser}
parentCommentId={parentCommentId}
onSubmitComment={onSubmitComment}
/>