Просмотр исходного кода

fix: prompt input multi line input

Adam 2 месяцев назад
Родитель
Сommit
7e682a95c4
1 измененных файлов с 40 добавлено и 24 удалено
  1. 40 24
      packages/desktop/src/components/prompt-input.tsx

+ 40 - 24
packages/desktop/src/components/prompt-input.tsx

@@ -380,31 +380,47 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
   const parseFromDOM = (): Prompt => {
     const newParts: Prompt = []
     let position = 0
-    editorRef.childNodes.forEach((node) => {
-      if (node.nodeType === Node.TEXT_NODE) {
-        if (node.textContent) {
-          const content = node.textContent
-          newParts.push({ type: "text", content, start: position, end: position + content.length })
-          position += content.length
-        }
-      } else if (node.nodeType === Node.ELEMENT_NODE && (node as HTMLElement).dataset.type) {
-        switch ((node as HTMLElement).dataset.type) {
-          case "file":
-            const content = node.textContent!
-            newParts.push({
-              type: "file",
-              path: (node as HTMLElement).dataset.path!,
-              content,
-              start: position,
-              end: position + content.length,
-            })
-            position += content.length
-            break
-          default:
-            break
-        }
-      }
+
+    const pushText = (content: string) => {
+      if (!content) return
+      newParts.push({ type: "text", content, start: position, end: position + content.length })
+      position += content.length
+    }
+
+    const rangeText = (range: Range) => {
+      const fragment = range.cloneContents()
+      const container = document.createElement("div")
+      container.append(fragment)
+      return container.innerText
+    }
+
+    const files = Array.from(editorRef.querySelectorAll<HTMLElement>("[data-type=file]"))
+    let last: HTMLElement | undefined
+
+    files.forEach((file) => {
+      const before = document.createRange()
+      before.selectNodeContents(editorRef)
+      if (last) before.setStartAfter(last)
+      before.setEndBefore(file)
+      pushText(rangeText(before))
+
+      const content = file.textContent ?? ""
+      newParts.push({
+        type: "file",
+        path: file.dataset.path!,
+        content,
+        start: position,
+        end: position + content.length,
+      })
+      position += content.length
+      last = file
     })
+
+    const after = document.createRange()
+    after.selectNodeContents(editorRef)
+    if (last) after.setStartAfter(last)
+    pushText(rangeText(after))
+
     if (newParts.length === 0) newParts.push(...DEFAULT_PROMPT)
     return newParts
   }