Fix Slate crash after inserting emoji from picker/autocomplete

This commit is contained in:
2026-07-13 02:40:02 +10:00
parent b711646b58
commit 687f139719
5 changed files with 53 additions and 21 deletions

View File

@@ -1,7 +1,6 @@
import React, { KeyboardEventHandler, useCallback, useRef, useState } from 'react';
import { isKeyHotkey } from 'is-hotkey';
import { Editor } from 'slate';
import { ReactEditor } from 'slate-react';
import { IconButton, Line, PopOut } from 'folds';
import { Icon, Icons } from '../../components/icons';
import {
@@ -13,6 +12,7 @@ import {
getAutocompleteQuery,
createEmoticonElement,
moveCursor,
safeFocusEditor,
} from '../../components/editor';
import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board';
import { UseStateProvider } from '../../components/UseStateProvider';
@@ -84,7 +84,7 @@ export function ForumChatComposer({
const handleCloseAutocomplete = useCallback(() => {
setAutocompleteQuery(undefined);
ReactEditor.focus(editor);
safeFocusEditor(editor);
}, [editor]);
return (
@@ -136,15 +136,15 @@ export function ForumChatComposer({
returnFocusOnDeactivate={false}
onEmojiSelect={handleEmoticonSelect}
onCustomEmojiSelect={handleEmoticonSelect}
requestClose={() => {
setEmojiBoardTab((t) => {
if (t) {
if (!mobileOrTablet()) ReactEditor.focus(editor);
return undefined;
}
return t;
});
}}
requestClose={() => {
setEmojiBoardTab((t) => {
if (t) {
if (!mobileOrTablet()) safeFocusEditor(editor);
return undefined;
}
return t;
});
}}
/>
}
>

View File

@@ -10,7 +10,6 @@ import React, {
import { useAtom, useAtomValue } from 'jotai';
import { isKeyHotkey } from 'is-hotkey';
import { EventType, IContent, MsgType, RelationType, Room } from 'matrix-js-sdk';
import { ReactEditor } from 'slate-react';
import { Transforms, Editor } from 'slate';
import { Box, Dialog, IconButton, Line, Overlay, OverlayBackdrop, OverlayCenter, PopOut, Scroll, Text, color, config, toRem } from 'folds';
@@ -32,6 +31,7 @@ import {
EmoticonAutocomplete,
createEmoticonElement,
moveCursor,
safeFocusEditor,
resetEditorHistory,
customHtmlEqualsPlainText,
trimCustomHtml,
@@ -559,7 +559,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
const handleCloseAutocomplete = useCallback(() => {
setAutocompleteQuery(undefined);
ReactEditor.focus(editor);
safeFocusEditor(editor);
}, [editor]);
const handleEmoticonSelect = (key: string, shortcode: string) => {
@@ -803,7 +803,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
requestClose={() => {
setEmojiBoardTab((t) => {
if (t) {
if (!mobileOrTablet()) ReactEditor.focus(editor);
if (!mobileOrTablet()) safeFocusEditor(editor);
return undefined;
}
return t;

View File

@@ -8,7 +8,6 @@ import React, {
import { Box, Chip, IconButton, Line, PopOut, RectCords, Spinner, Text, as, config } from 'folds';
import { Icon, Icons } from '../../../components/icons';
import { Editor, Transforms } from 'slate';
import { ReactEditor } from 'slate-react';
import { IContent, IMentions, MatrixEvent, RelationType, Room } from 'matrix-js-sdk';
import { isKeyHotkey } from 'is-hotkey';
import {
@@ -27,6 +26,7 @@ import {
htmlToEditorInput,
moveCursor,
plainToEditorInput,
safeFocusEditor,
toMatrixCustomHTML,
toPlainText,
trimCustomHtml,
@@ -185,7 +185,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
);
const handleCloseAutocomplete = useCallback(() => {
ReactEditor.focus(editor);
safeFocusEditor(editor);
setAutocompleteQuery(undefined);
}, [editor]);
@@ -208,7 +208,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
});
editor.insertFragment(initialValue);
if (!mobileOrTablet()) ReactEditor.focus(editor);
if (!mobileOrTablet()) safeFocusEditor(editor);
}, [editor, getPrevBodyAndFormattedBody, isMarkdown]);
useEffect(() => {
@@ -300,7 +300,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
requestClose={() => {
setAnchor((v) => {
if (v) {
if (!mobileOrTablet()) ReactEditor.focus(editor);
if (!mobileOrTablet()) safeFocusEditor(editor);
return undefined;
}
return v;