next-cloudinary icon indicating copy to clipboard operation
next-cloudinary copied to clipboard

feat: Add shimmer placeholder during AI transformation polling

Open Vaibhav91one opened this issue 1 month ago • 7 comments

Problem

When AI transformations return 423 (Locked) status during processing, broken image icons appear during polling.

PR for issue #514

Solution

Added a shimmer placeholder that displays during 423 polling:

  1. Hide broken icon synchronously via DOM manipulation
  2. Show CSS shimmer during polling
  3. Smooth transition when image loads
// Key change in onError handler
const img = options.target as HTMLImageElement;
img.style.opacity = '0';
img.style.visibility = 'hidden';
setIsPolling(true);
await pollForProcessingImage({ src });
setIsPolling(false);

Changes

  • File: src/components/CldImage/CldImage.tsx
  • Added: Shimmer placeholder with CSS animation

Testing

<CldImage removeBackground src="your-image" />

Hard refresh to see shimmer during AI processing.

Vaibhav91one avatar Oct 11 '25 12:10 Vaibhav91one

Someone is attempting to deploy a commit to the Cloudinary DevX Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Oct 11 '25 12:10 vercel[bot]

Hi, @devpatocld. Please take a look at this.

Vaibhav91one avatar Oct 13 '25 08:10 Vaibhav91one

@Vaibhav91one PR under review. Please be patient! Thank you

devpatocld avatar Oct 13 '25 17:10 devpatocld

Yes, Absolutely @eportis-cloudinary . Thank you for the feedback. After reviewing the feedback, I wanted to discuss two approaches and would like your opinion on it.

  1. Render Prop Pattern (Just like in CldUploadWidget).
// Default - no changes
<CldImage 
  src="images/woman-headphones" 
  width="500" 
  height="500" 
  alt="Portrait" 
/>

// With custom polling UI
<CldImage 
  src="images/woman-headphones" 
  width="500" 
  height="500" 
  alt="Portrait"
>
  {({ isPolling }) => isPolling && (
    <div style={{
      position: 'absolute',
      inset: 0,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      background: 'rgba(255, 255, 255, 0.9)'
    }}>
      <span>Processing...</span>
    </div>
  )}
</CldImage>

// Advanced - conditional styling
<CldImage 
  src="images/woman-headphones" 
  width="500" 
  height="500" 
  alt="Portrait"
>
  {({ isPolling }) => (
    <>
      {isPolling && <Spinner size={40} />}
      {isPolling && <p>AI processing in progress</p>}
    </>
  )}
</CldImage>

This accepts optional children function that receives isPolling boolean. User has full control over rendering logic. This matches CldUploadWidget pattern.

  1. Simple Prop
// Default - no changes
<CldImage 
  src="images/woman-headphones" 
  width="500" 
  height="500" 
  alt="Portrait" 
/>

// With custom polling UI
<CldImage 
  src="images/woman-headphones" 
  width="500" 
  height="500" 
  alt="Portrait"
  pollingFallback={
    <div style={{
      position: 'absolute',
      inset: 0,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      background: 'rgba(255, 255, 255, 0.9)'
    }}>
      <span>Processing...</span>
    </div>
  }
/>

// With component
<CldImage 
  src="images/woman-headphones" 
  width="500" 
  height="500" 
  alt="Portrait"
  pollingFallback={<Spinner />}
/>

This approach accepts optional pollingFallback prop with React component. Automatically shows/hides during polling. but there is no access to polling state for custom logic.

Vaibhav91one avatar Oct 28 '25 03:10 Vaibhav91one

Hi @eportis-cloudinary @devpatocld any update on the above?

Vaibhav91one avatar Nov 13 '25 03:11 Vaibhav91one

@Vaibhav91one None of these options is quite what I had in mind, but I do like them. I need to think this through, but unfortunately the time for Hacktoberfest reviews is coming to a close. I am going to mark this as accepted (without actually merging it), and you will be credited for a successful contribution. I'll and will follow up in the coming weeks about actually getting one of the patterns you identified, or somethign like them, merged. Thank you!

eportis-cloudinary avatar Nov 14 '25 00:11 eportis-cloudinary

@Vaibhav91one None of these options is quite what I had in mind, but I do like them. I need to think this through, but unfortunately the time for Hacktoberfest reviews is coming to a close. I am going to mark this as accepted (without actually merging it), and you will be credited for a successful contribution. I'll and will follow up in the coming weeks about actually getting one of the patterns you identified, or somethign like them, merged. Thank you!

Understood @eportis-cloudinary, Let me know what to do. I will be happy to help/contribute.

Vaibhav91one avatar Nov 14 '25 03:11 Vaibhav91one

@Vaibhav91one hi! we have sent you an email with the instructions for you to claim your swag price!

devpatocld avatar Nov 18 '25 05:11 devpatocld