Insert at mention on reply

This commit is contained in:
Sinclair Chen 2022-08-03 16:15:34 -07:00
parent 5a811b417d
commit adda267b5b
3 changed files with 39 additions and 32 deletions

View File

@ -31,9 +31,9 @@ export function FeedAnswerCommentGroup(props: {
const { answer, contract, comments, tips, bets, user } = props const { answer, contract, comments, tips, bets, user } = props
const { username, avatarUrl, name, text } = answer const { username, avatarUrl, name, text } = answer
const [replyToUsername, setReplyToUsername] = useState('') const [replyToUser, setReplyToUser] =
useState<Pick<User, 'id' | 'username'>>()
const [showReply, setShowReply] = useState(false) const [showReply, setShowReply] = useState(false)
const [inputRef, setInputRef] = useState<HTMLTextAreaElement | null>(null)
const [highlighted, setHighlighted] = useState(false) const [highlighted, setHighlighted] = useState(false)
const router = useRouter() const router = useRouter()
@ -70,9 +70,15 @@ export function FeedAnswerCommentGroup(props: {
const scrollAndOpenReplyInput = useEvent( const scrollAndOpenReplyInput = useEvent(
(comment?: Comment, answer?: Answer) => { (comment?: Comment, answer?: Answer) => {
setReplyToUsername(comment?.userUsername ?? answer?.username ?? '') setReplyToUser(
comment ?? answer
? {
id: comment?.userId ?? (answer as Answer).userId,
username: comment?.userUsername ?? (answer as Answer).username,
}
: undefined
)
setShowReply(true) setShowReply(true)
// TODO: focus
} }
) )
@ -89,10 +95,6 @@ export function FeedAnswerCommentGroup(props: {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [betsByCurrentUser.length, user, answer.number]) }, [betsByCurrentUser.length, user, answer.number])
useEffect(() => {
if (showReply && inputRef) inputRef.focus()
}, [inputRef, showReply])
useEffect(() => { useEffect(() => {
if (router.asPath.endsWith(`#${answerElementId}`)) { if (router.asPath.endsWith(`#${answerElementId}`)) {
setHighlighted(true) setHighlighted(true)
@ -171,11 +173,8 @@ export function FeedAnswerCommentGroup(props: {
betsByCurrentUser={betsByCurrentUser} betsByCurrentUser={betsByCurrentUser}
commentsByCurrentUser={commentsByCurrentUser} commentsByCurrentUser={commentsByCurrentUser}
parentAnswerOutcome={answer.number.toString()} parentAnswerOutcome={answer.number.toString()}
replyToUsername={replyToUsername} replyToUser={replyToUser}
onSubmitComment={() => { onSubmitComment={() => setShowReply(false)}
setShowReply(false)
setReplyToUsername('')
}}
/> />
</div> </div>
)} )}

View File

@ -40,7 +40,8 @@ export function FeedCommentThread(props: {
}) { }) {
const { contract, comments, bets, tips, smallAvatar, parentComment } = props const { contract, comments, bets, tips, smallAvatar, parentComment } = props
const [showReply, setShowReply] = useState(false) const [showReply, setShowReply] = useState(false)
const [replyToUsername, setReplyToUsername] = useState('') const [replyToUser, setReplyToUser] =
useState<{ id: string; username: string }>()
const betsByUserId = groupBy(bets, (bet) => bet.userId) const betsByUserId = groupBy(bets, (bet) => bet.userId)
const user = useUser() const user = useUser()
const commentsList = comments.filter( const commentsList = comments.filter(
@ -50,9 +51,8 @@ export function FeedCommentThread(props: {
commentsList.unshift(parentComment) commentsList.unshift(parentComment)
function scrollAndOpenReplyInput(comment: Comment) { function scrollAndOpenReplyInput(comment: Comment) {
setReplyToUsername(comment.userUsername) setReplyToUser({ id: comment.userId, username: comment.userUsername })
setShowReply(true) setShowReply(true)
//TODO focus
} }
return ( return (
@ -83,12 +83,9 @@ export function FeedCommentThread(props: {
(c) => c.userId === user?.id (c) => c.userId === user?.id
)} )}
parentCommentId={parentComment.id} parentCommentId={parentComment.id}
replyToUsername={replyToUsername} replyToUser={replyToUser}
parentAnswerOutcome={comments[0].answerOutcome} parentAnswerOutcome={comments[0].answerOutcome}
onSubmitComment={() => { onSubmitComment={() => setShowReply(false)}
setShowReply(false)
setReplyToUsername('')
}}
/> />
</Col> </Col>
)} )}
@ -323,7 +320,7 @@ export function CommentInput(props: {
contract: Contract contract: Contract
betsByCurrentUser: Bet[] betsByCurrentUser: Bet[]
commentsByCurrentUser: Comment[] commentsByCurrentUser: Comment[]
replyToUsername?: string replyToUser?: { 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
@ -336,7 +333,7 @@ export function CommentInput(props: {
commentsByCurrentUser, commentsByCurrentUser,
parentAnswerOutcome, parentAnswerOutcome,
parentCommentId, parentCommentId,
replyToUsername, replyToUser,
onSubmitComment, onSubmitComment,
} = props } = props
const user = useUser() const user = useUser()
@ -430,7 +427,7 @@ export function CommentInput(props: {
<CommentInputTextArea <CommentInputTextArea
editor={editor} editor={editor}
upload={upload} upload={upload}
replyToUsername={replyToUsername ?? ''} replyToUser={replyToUser}
user={user} user={user}
submitComment={submitComment} submitComment={submitComment}
isSubmitting={isSubmitting} isSubmitting={isSubmitting}
@ -445,7 +442,7 @@ export function CommentInput(props: {
export function CommentInputTextArea(props: { export function CommentInputTextArea(props: {
user: User | undefined | null user: User | undefined | null
replyToUsername: string replyToUser?: { id: string; username: string }
editor: Editor | null editor: Editor | null
upload: any upload: any
submitComment: (id?: string) => void submitComment: (id?: string) => void
@ -459,7 +456,7 @@ export function CommentInputTextArea(props: {
submitComment, submitComment,
presetId, presetId,
isSubmitting, isSubmitting,
replyToUsername, replyToUser,
} = props } = props
const isMobile = (useWindowSize().width ?? 0) < 768 // TODO: base off input device (keybord vs touch) const isMobile = (useWindowSize().width ?? 0) < 768 // TODO: base off input device (keybord vs touch)
@ -473,7 +470,11 @@ export function CommentInputTextArea(props: {
} }
useEffect(() => { useEffect(() => {
editor?.setOptions({ if (!editor) {
return
}
// submit on Enter key
editor.setOptions({
editorProps: { editorProps: {
handleKeyDown: (view, event) => { handleKeyDown: (view, event) => {
if ( if (
@ -491,10 +492,17 @@ export function CommentInputTextArea(props: {
}, },
}, },
}) })
// insert at mention
if (replyToUser) {
editor.commands.insertContentAt(0, {
type: 'mention',
attrs: { label: replyToUser.username, id: replyToUser.id },
})
editor.commands.focus()
}
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [editor]) }, [editor])
// TODO: make at mention show up at beginning
return ( return (
<> <>
<Row className="gap-1.5 text-gray-700"> <Row className="gap-1.5 text-gray-700">

View File

@ -36,7 +36,7 @@ export function GroupChat(props: {
const [scrollToMessageId, setScrollToMessageId] = useState('') const [scrollToMessageId, setScrollToMessageId] = useState('')
const [scrollToMessageRef, setScrollToMessageRef] = const [scrollToMessageRef, setScrollToMessageRef] =
useState<HTMLDivElement | null>(null) useState<HTMLDivElement | null>(null)
const [replyToUsername, setReplyToUsername] = useState('') const [replyToUser, setReplyToUser] = useState<any>()
const router = useRouter() const router = useRouter()
const isMember = user && group.memberIds.includes(user?.id) const isMember = user && group.memberIds.includes(user?.id)
@ -80,7 +80,7 @@ export function GroupChat(props: {
}, [messages, router.asPath]) }, [messages, router.asPath])
function onReplyClick(comment: Comment) { function onReplyClick(comment: Comment) {
setReplyToUsername(comment.userUsername) setReplyToUser({ id: comment.userId, username: comment.userUsername })
} }
async function submitMessage() { async function submitMessage() {
@ -93,7 +93,7 @@ export function GroupChat(props: {
await createCommentOnGroup(group.id, editor.getJSON(), user) await createCommentOnGroup(group.id, editor.getJSON(), user)
editor.commands.clearContent() editor.commands.clearContent()
setIsSubmitting(false) setIsSubmitting(false)
setReplyToUsername('') setReplyToUser(undefined)
focusInput() focusInput()
} }
function focusInput() { function focusInput() {
@ -159,7 +159,7 @@ export function GroupChat(props: {
editor={editor} editor={editor}
upload={upload} upload={upload}
user={user} user={user}
replyToUsername={replyToUsername} replyToUser={replyToUser}
submitComment={submitMessage} submitComment={submitMessage}
isSubmitting={isSubmitting} isSubmitting={isSubmitting}
/> />