diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index d2faa1893..cb9867b07 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -38,6 +38,7 @@ import { ACCEPTED_FILE_TYPES } from "./prompt-input/files" import { promptLength } from "./prompt-input/history" import { createPromptDerivedState } from "./prompt-input/derived-state" import { createPromptCommandsAndMode } from "./prompt-input/commands-mode" +import { createEditLoadEffect } from "./prompt-input/edit-load-effect" import type { PromptStore } from "./prompt-input/store-types" import type { FollowupDraft } from "./prompt-input/followup-draft" import { createPromptSubmit } from "./prompt-input/submit" @@ -273,44 +274,14 @@ export const PromptInput: Component = (props) => { addPart, } = editorInput - createEffect( - on( - () => props.edit?.id, - (id) => { - const edit = props.edit - if (!id || !edit) return - - for (const item of prompt.context.items()) { - prompt.context.remove(item.key) - } - - for (const item of edit.context) { - prompt.context.add({ - type: item.type, - path: item.path, - selection: item.selection, - comment: item.comment, - commentID: item.commentID, - commentOrigin: item.commentOrigin, - preview: item.preview, - }) - } - - setStore("mode", "normal") - setStore("popover", null) - setStore("historyIndex", -1) - setStore("savedPrompt", null) - prompt.set(edit.prompt, promptLength(edit.prompt)) - requestAnimationFrame(() => { - editorRef.focus() - setCursorPosition(editorRef, promptLength(edit.prompt)) - queueScroll() - }) - props.onEditLoaded?.() - }, - { defer: true }, - ), - ) + createEditLoadEffect({ + prompt, + setStore, + editorRef: () => editorRef, + queueScroll, + editDraft: () => props.edit, + onEditLoaded: () => props.onEditLoaded?.(), + }) const { addAttachments, addPickedPaths, removeAttachment, handlePaste } = createPromptAttachments({ editor: () => editorRef, diff --git a/packages/app/src/components/prompt-input/edit-load-effect.ts b/packages/app/src/components/prompt-input/edit-load-effect.ts new file mode 100644 index 000000000..4326582cc --- /dev/null +++ b/packages/app/src/components/prompt-input/edit-load-effect.ts @@ -0,0 +1,63 @@ +// Loads an edit / followup draft into the editor when props.edit changes. +// Extracted from prompt-input.tsx; sets up one deferred createEffect keyed on the +// edit id, so it must be called synchronously inside the component owner. + +import { createEffect, on } from "solid-js" +import type { SetStoreFunction } from "solid-js/store" +import { type Prompt, type usePrompt } from "@/context/prompt" +import { setCursorPosition } from "./editor-dom" +import { promptLength } from "./history" +import type { PromptStore } from "./store-types" +import type { FollowupDraft } from "./followup-draft" + +export interface EditLoadEffectDeps { + prompt: ReturnType + setStore: SetStoreFunction + editorRef: () => HTMLDivElement + queueScroll: () => void + editDraft: () => { id: string; prompt: Prompt; context: FollowupDraft["context"] } | undefined + onEditLoaded: () => void +} + +export function createEditLoadEffect(deps: EditLoadEffectDeps): void { + const { prompt, setStore, editorRef, queueScroll, editDraft, onEditLoaded } = deps + + createEffect( + on( + () => editDraft()?.id, + (id) => { + const edit = editDraft() + if (!id || !edit) return + + for (const item of prompt.context.items()) { + prompt.context.remove(item.key) + } + + for (const item of edit.context) { + prompt.context.add({ + type: item.type, + path: item.path, + selection: item.selection, + comment: item.comment, + commentID: item.commentID, + commentOrigin: item.commentOrigin, + preview: item.preview, + }) + } + + setStore("mode", "normal") + setStore("popover", null) + setStore("historyIndex", -1) + setStore("savedPrompt", null) + prompt.set(edit.prompt, promptLength(edit.prompt)) + requestAnimationFrame(() => { + editorRef().focus() + setCursorPosition(editorRef(), promptLength(edit.prompt)) + queueScroll() + }) + onEditLoaded() + }, + { defer: true }, + ), + ) +}