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

View File

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

View File

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

View File

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