Skip to content

feat(file-explorer): add SFTP copy/cut/paste with confirmation dialog and duplicate handling - #402

Open
hellonone wants to merge 17 commits into
nyakang:mainfrom
hellonone:feat/sftp-paste
Open

feat(file-explorer): add SFTP copy/cut/paste with confirmation dialog and duplicate handling#402
hellonone wants to merge 17 commits into
nyakang:mainfrom
hellonone:feat/sftp-paste

Conversation

@hellonone

@hellonone hellonone commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

功能描述

为文件浏览器增加 复制 / 剪切 / 粘贴 支持,包含快捷键、确认对话框、SFTP 侧重名冲突处理,以及传输完成后的自动目录刷新。 #292

详情

  1. 软件内文件浏览器内部的 复制|剪切 粘贴,跨会话可见,支持跨会话复制,但是为了文件安全性,跨会话的剪切不支持
  2. 读取系统剪切板,支持粘贴系统剪切板的文件,不支持从软件内的浏览器粘贴到系统
  3. 粘贴的确认对话框
  4. 快捷键注册支持
  5. 粘贴时的重名冲突处理

一些特性

  • 不支持跨会话移动
  • 同目录粘贴会被拦截并 toast 提示
  • 同样支持文件夹
  • 剪切板中没有内容时,粘贴选项禁用
  • 当先在软件内的文件浏览器复制后,再复制系统的文件,粘贴系统文件后,清空系统的剪切板,此时还能粘贴,粘贴的内容是最开始在软件内复制的文件

截图

image PixPin_2026-08-10_00-39-46

其他

大部分功能都已经手动测试,理论上没有问题

@nyakang

nyakang commented Aug 10, 2026

Copy link
Copy Markdown
Owner

@codex review

@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: 2415f93c4c

ℹ️ 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 thread src/components/panel/file-explorer/FileExplorer.tsx Outdated
Comment thread src/components/dialog/file-explorer/PasteConfirmDialog.tsx
Comment thread src-tauri/src/cmd/file_clipboard.rs
Comment thread src-tauri/src/cmd/file_clipboard.rs
@hellonone

Copy link
Copy Markdown
Contributor Author

4 条建议已全部处理完毕:

  1. 剪切粘贴遇到已存在目录时的冲突处理, 新增后端命令 move_remote_entries
  2. macOS 原生文件剪贴板问题因为没有macOS设备无法验证
  3. 确认对话框的 Enter 键交给聚焦按钮处理
  4. localhost 形式的 file URI 保留根斜杠

@nyakang

nyakang commented Aug 11, 2026

Copy link
Copy Markdown
Owner

@codex review

@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: 80f0080b08

ℹ️ 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 +2144 to +2145
copy_file_entry(app.clone(), manager.clone(), request).await?;
delete_remote_file(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not delete sources when duplicate copy is skipped

When the duplicate strategy is skip, or an ask prompt is answered with Skip, copy_file_entry emits a cancelled transfer but returns Ok(()); this code then immediately deletes the source anyway. A cut-paste onto an existing name can therefore discard the cut file without creating a new copy, so the copy pipeline must report whether it actually copied before deletion is allowed.

Useful? React with 👍 / 👎.

Comment on lines +1907 to +1908
const sourceParent = getExplorerParentDirectory(entries[0].path, "remote");
if (sourceParent && sourceParent === normalizeExplorerPath(targetDir, "remote")) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject cuts into a source descendant

For a same-session cut of directory /a, navigating to /a/b and pasting passes this check because the target is not the source's parent. The backend then copies to /a/b/a and recursively deletes /a, which also deletes the newly created destination; reject any cut target that is equal to or nested beneath any source directory.

Useful? React with 👍 / 👎.

/>
)}

<PasteConfirmDialog />

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 Mount only one global paste-confirm dialog

When the file explorer's secondary pane is open, each FileExplorerPane renders its own FileExplorerDialogs, while every PasteConfirmDialog subscribes to the same global prompt state. A paste therefore opens two overlapping alert dialogs and focus traps for one request; mount this global subscriber once above the per-pane dialog containers.

Useful? React with 👍 / 👎.

@nyakang

nyakang commented Aug 11, 2026

Copy link
Copy Markdown
Owner

感谢您的贡献!

SFTP 的复制 / 剪切 / 粘贴是一个非常实用的功能,这个 PR 已经把整体框架和不少细节实现得比较完整了。

我这边对于这部分功能还有一些想法,包括交互细节、剪切操作的数据安全以及不同场景下的行为一致性等。后续我会基于这个 PR 的实现继续完善和调整,并整合到主线中。

再次感谢你的贡献!

@nyakang nyakang changed the title feat(file-explorer): add SFTP copy/cut/paste with confirmation dialog and duplicate handling feat(file-explorer): add SFTP copy/cut/paste with confirmation dialog and duplicate handling #292 Aug 11, 2026
@nyakang nyakang changed the title feat(file-explorer): add SFTP copy/cut/paste with confirmation dialog and duplicate handling #292 feat(file-explorer): add SFTP copy/cut/paste with confirmation dialog and duplicate handling Aug 11, 2026
@nyakang nyakang linked an issue Aug 11, 2026 that may be closed by this pull request
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: 文件管理器ctrlc/v上传 优化建议

2 participants