Skip to content

Commit 2b95ff0

Browse files
committed
fix(UI): use ref-based composition state to fix Safari IME bug
1 parent 1bb8ea1 commit 2b95ff0

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/components/EmptyChatMessageInput.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const EmptyChatMessageInput = () => {
1414
const [message, setMessage] = useState('');
1515

1616
const inputRef = useRef<HTMLTextAreaElement | null>(null);
17+
const isComposing = useRef(false);
1718

1819
useEffect(() => {
1920
const handleKeyDown = (e: KeyboardEvent) => {
@@ -47,12 +48,20 @@ const EmptyChatMessageInput = () => {
4748
setMessage('');
4849
}}
4950
onKeyDown={(e) => {
50-
if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {
51+
if (e.key === 'Enter' && !e.shiftKey && !isComposing.current) {
5152
e.preventDefault();
5253
sendMessage(message);
5354
setMessage('');
5455
}
5556
}}
57+
onCompositionStart={() => {
58+
isComposing.current = true;
59+
}}
60+
onCompositionEnd={() => {
61+
setTimeout(() => {
62+
isComposing.current = false;
63+
}, 0);
64+
}}
5665
className="w-full"
5766
>
5867
<div className="flex flex-col bg-light-secondary dark:bg-dark-secondary px-3 pt-5 pb-3 rounded-2xl w-full border border-light-200 dark:border-dark-200 shadow-sm shadow-light-200/10 dark:shadow-black/20 transition-all duration-200 focus-within:border-light-300 dark:focus-within:border-dark-300">

src/components/MessageInput.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const MessageInput = () => {
1313
const [textareaRows, setTextareaRows] = useState(1);
1414
const [mode, setMode] = useState<'multi' | 'single'>('single');
1515

16+
const isComposing = useRef(false);
17+
1618
useEffect(() => {
1719
if (textareaRows >= 2 && message && mode === 'single') {
1820
setMode('multi');
@@ -54,12 +56,20 @@ const MessageInput = () => {
5456
setMessage('');
5557
}}
5658
onKeyDown={(e) => {
57-
if (e.key === 'Enter' && !e.shiftKey && !loading && !e.nativeEvent.isComposing) {
59+
if (e.key === 'Enter' && !e.shiftKey && !loading && !isComposing.current) {
5860
e.preventDefault();
5961
sendMessage(message);
6062
setMessage('');
6163
}
6264
}}
65+
onCompositionStart={() => {
66+
isComposing.current = true;
67+
}}
68+
onCompositionEnd={() => {
69+
setTimeout(() => {
70+
isComposing.current = false;
71+
}, 0);
72+
}}
6373
className={cn(
6474
'relative bg-light-secondary dark:bg-dark-secondary p-4 flex items-center overflow-visible border border-light-200 dark:border-dark-200 shadow-sm shadow-light-200/10 dark:shadow-black/20 transition-all duration-200 focus-within:border-light-300 dark:focus-within:border-dark-300',
6575
mode === 'multi' ? 'flex-col rounded-2xl' : 'flex-row rounded-full',

0 commit comments

Comments
 (0)