Skip to content

fix: replace broken image fallback with proper error state in ZoomableImage (#1184)Fix/UI flicker missing images#1239

Closed
nonehxrry wants to merge 2 commits intoAOSSIE-Org:mainfrom
nonehxrry:fix/ui-flicker-missing-images
Closed

fix: replace broken image fallback with proper error state in ZoomableImage (#1184)Fix/UI flicker missing images#1239
nonehxrry wants to merge 2 commits intoAOSSIE-Org:mainfrom
nonehxrry:fix/ui-flicker-missing-images

Conversation

@nonehxrry
Copy link

@nonehxrry nonehxrry commented Mar 21, 2026

Fixes #1184

Problem

The onError handler in ZoomableImage.tsx was setting
img.src = '/placeholder.svg' which triggered another error
if the SVG was missing, causing an infinite flicker loop.

Solution

  • Added hasError state to track image load failures
  • Added useEffect to reset error state when navigating to new image
  • When image fails to load, shows a clean fallback UI with
    "Image could not be loaded" message and the file path
  • No more infinite error loop — onError sets state once and React
    removes the broken <img> element

Testing

  1. Add a folder to PictoPy
  2. Delete the folder from disk
  3. Open PictoPy and click on an image from deleted folder
  4. Verify: clean error message shown instead of white flicker

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling for image loading failures—now displays a clear error message instead of silently loading a placeholder.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 21, 2026

Walkthrough

Modified ZoomableImage.tsx to eliminate UI flickering when image loads fail. Added state-driven error tracking that displays an error panel instead of attempting placeholder fallback, preventing infinite error cycles and visual flicker.

Changes

Cohort / File(s) Summary
Image Error Handling
frontend/src/components/Media/ZoomableImage.tsx
Added hasError state and useEffect to reset error on path changes. Replaced placeholder fallback with conditional rendering: displays styled error panel when load fails, otherwise renders image via convertFileSrc(). Prevents error loop cascades.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

TypeScript/JavaScript

Suggested reviewers

  • rahulharpal1603

Poem

🐰 A hop, a skip, through broken frames,
No more the flicker, no more the shame,
When images fade to paths unknown,
A gentle message, kindly shown. ✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: replacing broken image fallback with proper error state in ZoomableImage component.
Linked Issues check ✅ Passed The PR fully implements all coding requirements from issue #1184: introduces hasError state, adds useEffect to reset on imagePath change, and renders fallback UI instead of placeholder.
Out of Scope Changes check ✅ Passed All changes in ZoomableImage.tsx are directly scoped to fixing the image load error handling and preventing UI flicker as specified in issue #1184.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting to assertive to make CodeRabbit's nitpick more issues in your PRs.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
frontend/src/components/Media/ZoomableImage.tsx (1)

424-453: Consider preventing zoom/pan interactions on the error UI.

The error fallback is rendered inside TransformComponent, which means users can still zoom and pan the error message. This may be unintended UX behavior.

Consider either:

  1. Moving the error UI outside TransformWrapper entirely, or
  2. Disabling interactions when in error state by conditionally setting panning.disabled and wheel.disabled based on hasError.

Additionally, for accessibility, consider adding role="alert" to announce the error state to screen readers.

♻️ Suggested accessibility improvement
          {hasError ? (
            <div
+             role="alert"
              className="flex flex-col items-center justify-center gap-4 rounded-lg bg-gray-900 p-12 text-center"
              style={{ minWidth: '320px', minHeight: '220px' }}
            >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/Media/ZoomableImage.tsx` around lines 424 - 453, The
error UI is rendered inside TransformComponent which allows zoom/pan even when
hasError is true; either move the error fallback out of
TransformWrapper/TransformComponent or disable interactions when hasError by
setting TransformWrapper/TransformComponent props like panning.disabled and
wheel.disabled based on hasError, and add role="alert" to the error container
for screen reader announcement; update the conditional that renders the error UI
around hasError and adjust TransformWrapper/TransformComponent usage accordingly
(refer to hasError, TransformWrapper, TransformComponent, panning.disabled,
wheel.disabled, and add role="alert").
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@frontend/src/components/Media/ZoomableImage.tsx`:
- Around line 424-453: The error UI is rendered inside TransformComponent which
allows zoom/pan even when hasError is true; either move the error fallback out
of TransformWrapper/TransformComponent or disable interactions when hasError by
setting TransformWrapper/TransformComponent props like panning.disabled and
wheel.disabled based on hasError, and add role="alert" to the error container
for screen reader announcement; update the conditional that renders the error UI
around hasError and adjust TransformWrapper/TransformComponent usage accordingly
(refer to hasError, TransformWrapper, TransformComponent, panning.disabled,
wheel.disabled, and add role="alert").

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9eca17a5-de1f-4f4f-a0d5-9f8b40ac571e

📥 Commits

Reviewing files that changed from the base of the PR and between 8274ebd and e39e96d.

📒 Files selected for processing (1)
  • frontend/src/components/Media/ZoomableImage.tsx

@SIDDHANTCOOKIE
Copy link

Hey thanks for contributing but currently we are closing all prs that are linked to unreviewed issues please wait for mentors to discuss the issue mention your issue with some idea in the discord channel and wait for them to assign it to you then go ahead with the pr!
https://discord.com/channels/1022871757289422898/1311271974630330388

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.

BUG: UI flicker occurs for missing or invalid image paths

2 participants