Skip to content

feat: 拖拽文件夹到输入框自动插入路径文本#5447

Open
ttmouse wants to merge 4 commits into
esengine:main-v2from
ttmouse:pr/folder-drag-path
Open

feat: 拖拽文件夹到输入框自动插入路径文本#5447
ttmouse wants to merge 4 commits into
esengine:main-v2from
ttmouse:pr/folder-drag-path

Conversation

@ttmouse

@ttmouse ttmouse commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Summary

从 Finder 拖拽文件夹到 Composer 输入框区域时,自动将文件夹的绝对路径作为纯文本插入输入框,而不是报错或添加为附件。

Changes

  • Go (app.go): 工作区外的目录拖拽不再报错,返回 DroppedItem{Kind:"folder", Path, IsDir:true},使用 filepath.ToSlash 确保 Windows 兼容
  • Frontend (types.ts): DroppedItem.kind 增加 "folder" 类型
  • Frontend (Composer.tsx): 在 attachDroppedPaths 中新增 kind==="folder" 分支,用 textRef 追加路径文本到输入框(支持连续拖拽、不覆盖已有文本)
  • Test: 新增 TestAttachDroppedOutsideWorkspaceDirReturnsFolder 覆盖新路径
  • Mock (bridge.ts): dev mock 支持 folder 分支

Review

  • macOS 实测通过
  • 已有文本不丢失(追加而非覆盖)
  • 连续拖拽多个文件夹无竞态条件
  • Go 测试全部通过(6/6)
  • wails build 编译通过
  • 多重走查(pr-review + ponytail-review + review)所有 blocker 已修复

Refs #5370

Note: this PR covers the folder-drag portion of #5370 only; the font-size/custom scaling request remains open for follow-up.

ttmouse added 3 commits June 27, 2026 16:44
When a folder is dragged from the OS file manager into the composer input
area via the Wails native file-drop bridge, its absolute path is now
inserted as plain text in the textarea - rather than erroring or adding
an attachment.

Changes:
- Go (app.go): outside-workspace directories now return DroppedItem with
  Kind="folder" and the original absolute path instead of erroring
- Frontend (types.ts): add "folder" to DroppedItem.kind union
- Frontend (Composer.tsx): handle kind="folder" by inserting the path
  as text via setTextCaretEnd, with automatic spacing
- Test (attach_dropped_test.go): add
  TestAttachDroppedOutsideWorkspaceDirReturnsFolder

Closes: esengine#5370
…ng it

The onFilesDropped callback captures attachDroppedPaths from the first
render (empty deps []), so  in the closure is always the initial
empty string. This caused folder path drops to overwrite any existing
input content.

Fix: read current textarea value from taRef.current.value (the live DOM)
instead of the stale  closure variable.
Addresses all issues found by multi-review (pr-review + ponytail-review + review):

1. [Blocker] Windows: filepath.ToSlash() on dropped folder path for
   cross-platform consistency with workspaceRelativeIn & SaveAttachmentFile
2. [Blocker] Race condition: use textRef (already synced with text state)
   instead of stale closure 'text' or taRef DOM value; update textRef
   immediately within the loop to prevent interleaved drops from colliding
3. [Blocker] textarea-unmount fallback: textRef.current always holds the
   latest value, never the stale initial empty string
4. [Warning] DroppedItem.Kind comment updated to include "folder"
5. [Warning] DroppedItem.IsDir set to true for folder kind
6. [Warning] Mock AttachDropped now returns kind="folder" for paths
   without a file extension (dev-only heuristic)
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) labels Jun 27, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: acd7980a62

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1233 to +1237
const currentText = textRef.current;
const sep = currentText.length > 0 && !currentText.endsWith(" ") ? " " : "";
const next = currentText + sep + item.path + " ";
textRef.current = next;
setTextCaretEnd(next);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Insert dropped folders into the source draft

When a folder drop is still awaiting app.AttachDropped and the user switches tabs/sessions, this branch appends to textRef.current and calls setTextCaretEnd, which always mutates the currently active composer. The surrounding attachment/workspace paths deliberately use sourceDraftKey so async drop results land in the draft where the drop started; folders now leak the path into the newly active draft and leave the original draft unchanged in that scenario.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修复。在插入前检查 activeDraftKeyRef.current !== sourceDraftKey,如果用户已切换会话则跳过插入。commit 105c86b

Comment thread desktop/attach_dropped_test.go Outdated
Comment on lines +252 to +253
if got.Path != outsideDir {
t.Fatalf("got path=%q, want %q (the original absolute path)", got.Path, outsideDir)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize the expected folder path in the new test

When this desktop package is tested on Windows, outsideDir contains backslashes from filepath.Join, but AttachDropped intentionally returns filepath.ToSlash(path) for folders, so this assertion fails even though the implementation did what the production code now specifies. Compare against filepath.ToSlash(outsideDir) (or otherwise normalize both sides) to keep the test portable for Windows desktop development.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修复。断言改为 filepath.ToSlash(outsideDir),Windows 上也能正常工作。commit 105c86b

…lization

Addresses 2 Codex inline review comments on PR esengine#5447:

1. Composer.tsx: check activeDraftKeyRef before inserting folder path
   text to prevent leaking into the wrong session when the user
   switches tabs mid-drop (follows the same pattern as attachments).

2. attach_dropped_test.go: compare against filepath.ToSlash(outsideDir)
   so the test passes on Windows where filepath.Join produces backslashes
   but AttachDropped now returns ToSlash'd paths.
@ttmouse

ttmouse commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

已处理 Codex 的 P2 建议:

  1. Composer.tsx — 文件夹路径插入前检查 activeDraftKeyRef.current !== sourceDraftKey,防止切换会话后路径插入错误输入框(commit 105c86b
  2. attach_dropped_test.go — 断言改为 filepath.ToSlash(outsideDir),Windows 上也能通过(commit 105c86b

两个修复已一起 push 到 pr/folder-drag-path。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop Wails desktop app (desktop/**) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant