Eliminate redundant showReply/replyTo state (#917)
This commit is contained in:
parent
6fe0a22a48
commit
6ee8d90bdb
|
@ -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()
|
||||||
|
|
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -92,7 +92,7 @@ export function PostCommentInput(props: {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CommentInput
|
<CommentInput
|
||||||
replyToUser={replyToUser}
|
replyTo={replyToUser}
|
||||||
parentCommentId={parentCommentId}
|
parentCommentId={parentCommentId}
|
||||||
onSubmitComment={onSubmitComment}
|
onSubmitComment={onSubmitComment}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user