Insert at mention on reply
This commit is contained in:
parent
5a811b417d
commit
adda267b5b
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user