Skip to content

Commit 9f1771e

Browse files
committed
fix(desktop): open emoji picker at editor caret position in chatroom
1 parent bbf5b50 commit 9f1771e

2 files changed

Lines changed: 51 additions & 14 deletions

File tree

packages/webapp/components/chat/components/MessageComposer/components/Actions/ActionButtons/EmojiButton.tsx

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,48 @@ import { twMerge } from 'tailwind-merge'
22
import Button from '../../ui/Button'
33
import Icon from '@components/TipTap/toolbar/Icon'
44
import { useMessageComposer } from '../../../hooks/useMessageComposer'
5+
import { Editor } from '@tiptap/react'
6+
import { useCallback } from 'react'
57
type Props = React.HTMLAttributes<HTMLButtonElement> & {
68
className?: string
79
size?: number
810
}
911

12+
const getCaretPositionWithScroll = (editor: Editor) => {
13+
if (!editor) return null
14+
15+
const { selection } = editor.state
16+
const coords = editor.view.coordsAtPos(selection.from)
17+
18+
return {
19+
x: coords.left + window.scrollX,
20+
y: coords.top + window.scrollY,
21+
bottom: coords.bottom + window.scrollY,
22+
right: coords.right + window.scrollX
23+
}
24+
}
25+
1026
export const EmojiButton = ({ className, size = 20, ...props }: Props) => {
1127
const { editor } = useMessageComposer()
1228

13-
const openEmojiPicker = (clickEvent: any) => {
14-
const event = new CustomEvent('toggelEmojiPicker', {
15-
detail: { clickEvent: clickEvent, editor, type: 'inserEmojiToEditor' }
16-
})
17-
document.dispatchEvent(event)
18-
}
29+
const openEmojiPicker = useCallback(
30+
(clickEvent: any) => {
31+
if (!editor) return
32+
33+
const caretPosition = getCaretPositionWithScroll(editor)
34+
35+
const event = new CustomEvent('toggelEmojiPicker', {
36+
detail: {
37+
clickEvent: clickEvent,
38+
editor,
39+
type: 'inserEmojiToEditor',
40+
coordinates: caretPosition
41+
}
42+
})
43+
document.dispatchEvent(event)
44+
},
45+
[editor]
46+
)
1947

2048
return (
2149
<Button

packages/webapp/components/chat/hooks/useEmojiBoxHandler.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const useEmojiBoxHandler = (emojiPikerRef: any, messageContainerRef: any)
2727
const message = e.detail?.message
2828
const type = e.detail.type
2929
const editor = e.detail?.editor
30+
const coordinates = e.detail?.coordinates
3031
setEditor(editor)
3132
setEventTypes(type)
3233

@@ -36,15 +37,23 @@ export const useEmojiBoxHandler = (emojiPikerRef: any, messageContainerRef: any)
3637
const emojiButtonWidth = 24
3738
const chatEditorHeight = 153
3839

39-
// Use getBoundingClientRect if positioning relative to an element
40-
const rect =
41-
event.currentTarget?.getBoundingClientRect() || event.target?.getBoundingClientRect()
42-
if (!rect) {
43-
console.error('rect is null')
44-
return
40+
let newTop, newLeft
41+
42+
if (coordinates) {
43+
// Use provided coordinates
44+
newTop = coordinates.y || coordinates.top
45+
newLeft = coordinates.x || coordinates.left
46+
} else {
47+
// Fallback to DOM positioning
48+
const rect =
49+
event.currentTarget?.getBoundingClientRect() || event.target?.getBoundingClientRect()
50+
if (!rect) {
51+
console.error('rect is null')
52+
return
53+
}
54+
newTop = rect.bottom + window.scrollY
55+
newLeft = rect.left + window.scrollX
4556
}
46-
let newTop = rect.bottom + window.scrollY
47-
let newLeft = rect.left + window.scrollX
4857

4958
// Adjust for right and bottom edges
5059
if (newLeft + clientWidth + emojiButtonWidth > window.innerWidth) {

0 commit comments

Comments
 (0)