Selaa lähdekoodia

fix(app): skip editor reconcile during IME composition (#17041)

Chris Yang 5 kuukautta sitten
vanhempi
sitoutus
cf7ca9b2f7
1 muutettua tiedostoa jossa 31 lisäystä ja 16 poistoa
  1. 31 16
      packages/app/src/components/prompt-input.tsx

+ 31 - 16
packages/app/src/components/prompt-input.tsx

@@ -490,6 +490,18 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
     setComposing(false)
   }
 
+  const handleCompositionStart = () => {
+    setComposing(true)
+  }
+
+  const handleCompositionEnd = () => {
+    setComposing(false)
+    requestAnimationFrame(() => {
+      if (composing()) return
+      reconcile(prompt.current().filter((part) => part.type !== "image"))
+    })
+  }
+
   const agentList = createMemo(() =>
     sync.data.agent
       .filter((agent) => !agent.hidden && agent.mode !== "primary")
@@ -680,24 +692,27 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
     }
   }
 
-  createEffect(
-    on(
-      () => prompt.current(),
-      (currentParts) => {
-        const inputParts = currentParts.filter((part) => part.type !== "image")
+  const reconcile = (input: Prompt) => {
+    if (mirror.input) {
+      mirror.input = false
+      if (isNormalizedEditor()) return
 
-        if (mirror.input) {
-          mirror.input = false
-          if (isNormalizedEditor()) return
+      renderEditorWithCursor(input)
+      return
+    }
 
-          renderEditorWithCursor(inputParts)
-          return
-        }
+    const dom = parseFromDOM()
+    if (isNormalizedEditor() && isPromptEqual(input, dom)) return
 
-        const domParts = parseFromDOM()
-        if (isNormalizedEditor() && isPromptEqual(inputParts, domParts)) return
+    renderEditorWithCursor(input)
+  }
 
-        renderEditorWithCursor(inputParts)
+  createEffect(
+    on(
+      () => prompt.current(),
+      (parts) => {
+        if (composing()) return
+        reconcile(parts.filter((part) => part.type !== "image"))
       },
     ),
   )
@@ -1208,8 +1223,8 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
               spellcheck={store.mode === "normal"}
               onInput={handleInput}
               onPaste={handlePaste}
-              onCompositionStart={() => setComposing(true)}
-              onCompositionEnd={() => setComposing(false)}
+              onCompositionStart={handleCompositionStart}
+              onCompositionEnd={handleCompositionEnd}
               onBlur={handleBlur}
               onKeyDown={handleKeyDown}
               classList={{