Skip to content

fix(paste): deduplicate filenames when pasting multiple images#1931

Merged
kaizhou-lab merged 1 commit intomainfrom
fix/issue-1177
Mar 30, 2026
Merged

fix(paste): deduplicate filenames when pasting multiple images#1931
kaizhou-lab merged 1 commit intomainfrom
fix/issue-1177

Conversation

@kaizhou-lab
Copy link
Copy Markdown
Collaborator

Summary

  • When multiple clipboard images are pasted simultaneously, they generate identical filenames (second-precision timestamp HHmmss). The backend collision handler (fsBridge.createTempFile) appends _aionui_<timestamp> suffixes, but buildDisplayMessage strips these suffixes via AIONUI_TIMESTAMP_REGEX, causing all files to map to the same display path — so only one image appears in conversation details.
  • Added a usedFileNames Set in the paste loop to detect and resolve filename collisions at the source by appending _2, _3, etc. suffixes before calling createTempFile.
  • Applied the same deduplication to both clipboard image and clipboard non-image file branches.

Related Issues

Closes #1177

Test Plan

  • Unit tests added (PasteService.dom.test.ts) covering 2-image and 3-image simultaneous paste
  • Type check passes
  • Lint and format pass

…aneously

When multiple clipboard images are pasted at the same time, they generate
identical filenames (second-precision timestamp). The backend collision
handler appends _aionui_<ts> suffixes, but buildDisplayMessage strips
these suffixes, causing all files to map to the same display path.

Add a usedFileNames Set in the paste loop to detect and resolve
filename collisions at the source by appending _2, _3, etc. suffixes.

Closes #1177
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 30, 2026

Code Review:fix(paste): deduplicate filenames when pasting multiple images (#1931)

变更概述

本 PR 修复了在同一秒内粘贴多张截图时,因生成相同的时间戳文件名(pasted_image_HHmmss.png)导致只有一张图片显示在会话中的 bug。修改范围:PasteService.ts(添加去重逻辑)和 PasteService.dom.test.ts(新增单元测试)。


方案评估

结论:✅ 方案合理

在粘贴循环中引入 usedFileNames Set,在调用 createTempFile 前于客户端完成去重,选择 _2_3 等后缀递增策略。方案与项目已有模式一致,将冲突消灭在上游,优于依赖后端 _aionui_<timestamp> 后缀再由 AIONUI_TIMESTAMP_REGEX 剥离的脆弱链路。


问题清单

🔵 LOW — 去重辅助逻辑重复

文件src/renderer/services/PasteService.ts,第 173–183 行 与 第 236–245 行

问题说明:图片分支和非图片文件分支各自包含一份相同的去重逻辑。若后续需修改命名策略(如改用 (2) 格式),需同步修改两处,存在遗漏风险。

修复建议(可选,不阻塞合并):提取为内联辅助函数:

function deduplicateFileName(name: string, used: Set<string>, fallbackExt: string): string {
  if (!used.has(name)) return name;
  const extIdx = name.lastIndexOf('.');
  const base = extIdx > 0 ? name.slice(0, extIdx) : name;
  const ext = extIdx > 0 ? name.slice(extIdx) : fallbackExt;
  let counter = 2;
  while (used.has(`${base}_${counter}${ext}`)) counter++;
  return `${base}_${counter}${ext}`;
}

🔵 LOW — 测试未覆盖非图片文件分支去重

文件tests/unit/PasteService.dom.test.ts

问题说明:三个测试用例均使用 image/png 类型文件,覆盖了图片分支的去重逻辑,但未测试非图片文件出现同名时的去重行为。由于两段去重代码对称,此缺口风险较低,但技术上存在未测路径。


汇总

# 严重级别 文件 问题
1 🔵 LOW PasteService.ts:173-183, 236-245 去重逻辑重复,维护成本
2 🔵 LOW PasteService.dom.test.ts 非图片文件分支去重未测试

结论

批准合并 — 仅有两处 LOW 级问题,均不阻塞合并。核心逻辑正确,测试覆盖主路径,方案简洁合理。


本报告由本地 pr-review skill 生成,包含完整项目上下文,无截断限制。

CONCLUSION: APPROVED
IS_CRITICAL_PATH: false
PR_NUMBER: 1931

@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 30, 2026

✅ 已自动 review,无阻塞性问题,正在触发自动合并。

@piorpua piorpua added bot:ready-to-merge Bot done, code is clean — human just needs to confirm and merge and removed bot:reviewing Review in progress (mutex) labels Mar 30, 2026
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 30, 2026

⚠️ 自动合并触发失败(auto-merge 未成功启用),已标记 bot:ready-to-merge,请人工确认后合并。

@kaizhou-lab kaizhou-lab merged commit 08dd444 into main Mar 30, 2026
17 checks passed
@kaizhou-lab kaizhou-lab deleted the fix/issue-1177 branch March 30, 2026 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:ready-to-merge Bot done, code is clean — human just needs to confirm and merge

Projects

None yet

2 participants