Skip to content

fix(media): retry image loading for pasted clipboard images#1928

Merged
piorpua merged 1 commit intomainfrom
fix/issue-794
Mar 31, 2026
Merged

fix(media): retry image loading for pasted clipboard images#1928
piorpua merged 1 commit intomainfrom
fix/issue-794

Conversation

@kaizhou-lab
Copy link
Copy Markdown
Collaborator

Summary

  • Fix race condition where pasted clipboard images show "Image not found" placeholder permanently
  • Root cause: buildDisplayMessage rewrites temp file paths to workspace paths before backend copyFilesToDirectory completes, so FilePreview.getImageBase64 gets ENOENT and returns a placeholder SVG that never gets retried
  • Add retry logic (5 retries, 800ms interval) to FilePreview that detects the placeholder SVG and re-attempts loading

Related Issues

Closes #794, closes #1170

Test Plan

  • Unit tests for retry logic (5 tests covering success, retry, max retries, non-image files, cleanup on unmount)
  • Type check passes
  • Lint and format pass

@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 30, 2026

Code Review:fix(media): retry image loading for pasted clipboard images (#1928)

变更概述

本 PR 修复了粘贴剪贴板图片后出现「Image not found」占位图永远不消失的竞态问题。在 FilePreview 组件中新增重试逻辑(最多 5 次,间隔 800ms),当检测到 getImageBase64 返回的是占位 SVG 时自动重试加载。同时新增了 5 个单元测试覆盖成功、重试、最大重试、非图片文件和卸载清理场景。


方案评估

结论:✅ 方案合理

方案正确识别了根本原因(buildDisplayMessage 在后端 copyFilesToDirectory 完成前就重写了路径),在 UI 层通过重试机制规避了时序问题,而非修改后端流程,这是一个务实且影响面最小的修复。重试参数(5 次 × 800ms = 最多 4 秒等待)对用户体验合理。cleanup 函数正确处理了组件卸载时的取消逻辑,避免了内存泄漏和状态更新竞态。


问题清单

🔵 LOW — 不必要的三元表达式

文件src/renderer/components/media/FilePreview.tsx,第 121 行

问题代码

preview={imageUrl ? true : false}

问题说明:oxlint no-unneeded-ternary 警告。将真值转为布尔值可直接使用 !!Boolean()

修复建议

preview={!!imageUrl}

🔵 LOW — 未使用的 waitFor 导入

文件tests/unit/FilePreview.dom.test.tsx,第 7 行

问题代码

import { render, screen, waitFor, act } from '@testing-library/react';

问题说明:oxlint no-unused-vars 警告。waitFor 已导入但未在任何测试中使用。

修复建议

import { render, screen, act } from '@testing-library/react';

汇总

# 严重级别 文件 问题
1 🔵 LOW FilePreview.tsx:121 不必要的三元表达式
2 🔵 LOW FilePreview.dom.test.tsx:7 未使用的 waitFor 导入

结论

批准合并 — 代码逻辑正确,方案合理,测试覆盖充分。仅存在两个 lint 级别的小问题,不影响功能。


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

CONCLUSION: APPROVED
IS_CRITICAL_PATH: false
PR_NUMBER: 1928

@piorpua piorpua added bot:ci-waiting CI failed and author notified — snoozed until new commits are pushed and removed bot:reviewing Review in progress (mutex) labels Mar 30, 2026
…ce condition

When pasting clipboard images, buildDisplayMessage rewrites the temp file
path to a workspace path before the backend finishes copying the file.
FilePreview's getImageBase64 call would fail with ENOENT and permanently
show the 'Image not found' placeholder SVG.

Add retry logic (up to 5 retries, 800ms apart) that detects the placeholder
response and re-attempts loading. Once the backend copy completes, the retry
succeeds and the image renders correctly.

Closes #794, closes #1170
@piorpua piorpua added bot:reviewing Review in progress (mutex) and removed bot:ci-waiting CI failed and author notified — snoozed until new commits are pushed labels Mar 31, 2026
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 31, 2026

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

@piorpua piorpua merged commit 81e2809 into main Mar 31, 2026
17 checks passed
@piorpua piorpua deleted the fix/issue-794 branch March 31, 2026 07:32
@piorpua piorpua added bot:done Auto-merged by bot and removed bot:reviewing Review in progress (mutex) labels Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:done Auto-merged by bot

Projects

None yet

2 participants