fix(room): handle Enter/Tab mention selection directly in ChatInputArea.handleKeyDown
Previous approach used a native addEventListener in MentionPopover to handle Enter, but it wasn't firing reliably due to complex event ordering. New approach: ChatInputArea.handleKeyDown detects @ mention directly from the DOM (not React state), reads the selected item from module-level mentionVisibleRef/mentionSelectedIdxRef, and performs the insertion directly. This completely bypasses the native listener timing issues.
This commit is contained in:
parent
b8a61b0802
commit
245384ef50
@ -157,7 +157,35 @@ const ChatInputArea = memo(function ChatInputArea({
|
||||
|
||||
if (hasMention && MENTION_POPOVER_KEYS.includes(e.key) && !e.ctrlKey && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
// Enter/Tab is handled by MentionPopover's native keydown listener
|
||||
// Enter/Tab: do mention selection directly here using module-level refs
|
||||
if ((e.key === 'Enter' || e.key === 'Tab')) {
|
||||
const suggestion = mentionVisibleRef.current[mentionSelectedIdxRef.current];
|
||||
if (suggestion && suggestion.type === 'item') {
|
||||
const textarea = textareaRef.current;
|
||||
if (!textarea) return;
|
||||
const cursorPos = textarea.selectionStart;
|
||||
const textBefore = textarea.value.substring(0, cursorPos);
|
||||
const atMatch = textBefore.match(MENTION_PATTERN);
|
||||
if (!atMatch) return;
|
||||
const [fullMatch] = atMatch;
|
||||
const startPos = cursorPos - fullMatch.length;
|
||||
const before = textarea.value.substring(0, startPos);
|
||||
const after = textarea.value.substring(cursorPos);
|
||||
const html = buildMentionHtml(suggestion.category!, suggestion.mentionId!, suggestion.label);
|
||||
const spacer = ' ';
|
||||
const newValue = before + html + spacer + after;
|
||||
const newCursorPos = startPos + html.length + spacer.length;
|
||||
onDraftChange(newValue);
|
||||
setShowMentionPopover(false);
|
||||
setTimeout(() => {
|
||||
if (textareaRef.current) {
|
||||
textareaRef.current.value = newValue;
|
||||
textareaRef.current.setSelectionRange(newCursorPos, newCursorPos);
|
||||
textareaRef.current.focus();
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user