From 4330325bfc371607bfefd4517340b01fea22aadf Mon Sep 17 00:00:00 2001 From: ZhenYi <434836402@qq.com> Date: Sat, 18 Apr 2026 11:39:16 +0800 Subject: [PATCH] fix(frontend): skip tracking effect update when caret is at end of text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: after onCategoryEnter sets value="@ai:", the MentionInput sync effect sets innerHTML with the new content. The browser caret may be at position 2 (not moved from the user's perspective), but prevCursorRef was 4. The tracking effect read DOM caret=2 and overwrote ms.setCursorOffset(4) → cursor jumped to position 2. Fix: skip tracking effect update when: - count (DOM caret) is at end of text (ms.value.length), AND - prevCursorRef was also at end of text This means the caret hasn't actually moved from the user's POV (just positioned by the browser after innerHTML), so don't update state. --- src/components/room/RoomChatPanel.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/room/RoomChatPanel.tsx b/src/components/room/RoomChatPanel.tsx index fd1af43..da82307 100644 --- a/src/components/room/RoomChatPanel.tsx +++ b/src/components/room/RoomChatPanel.tsx @@ -104,8 +104,13 @@ const ChatInputArea = memo(function ChatInputArea({ count += node.length; } if (count !== prevCursorRef.current) { - prevCursorRef.current = count; - ms.setCursorOffset(count); + // Skip update when caret is at end of text (programmatic value change + // that already positioned the caret — the caret hasn't moved from the + // user's perspective). Only update on real user-initiated cursor movement. + if (count !== ms.value.length || prevCursorRef.current !== ms.value.length) { + prevCursorRef.current = count; + ms.setCursorOffset(count); + } } });