Repository navigation
Media: Show determinate GIF conversion progress in the upload snackbar - #80329
adamsilverstein wants to merge 17 commits into
Conversation
The conversion loop knows the exact frame count up front, so per-frame progress is precise. Add an onProgress callback to convertGifToVideo(), throttled to whole-percent increments, and dispatch the previously unused updateItemProgress action from transcodeGifItem. A new getProgressById selector resolves progress for an attachment, matching sideload companions via additionalData.post. See #80325.
Replace the indeterminate spinner overlay with a determinate ProgressBar while a long-running client-side operation reports progress for the block's attachment, so authors converting long animated GIFs can see how far along the conversion is. See #80325.
Fast conversions can emit ~100 whole-percent reports in a couple of seconds. Each dispatch synchronously re-renders every upload-store consumer in the editor, which saturates the main thread and starves painting - the progress bar was in the DOM but never drawn. Allow at most one dispatch per 250ms (the final report always goes through). Verified in the editor: the bar now paints and advances visibly during conversion. See #80325.
|
Size Change: +466 B (+0.01%) Total Size: 7.65 MB 📦 View Changed
|
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Flaky tests detected in 2970d39. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/29788532163
|
…o add/gif-conversion-progress
The default ProgressBar is a 1.5px hairline in theme foreground color, nearly invisible over noisy GIF frames or dark video posters. Thicken it and give it media-relative contrast: white indicator on a dark translucent track, with a light outline and drop shadow so the track extent stays visible over dark media.
…o add/gif-conversion-progress
…rogress # Conflicts: # packages/upload-media/src/store/private-actions.ts # packages/upload-media/src/store/test/private-actions.js # packages/upload-media/src/store/utils/video-conversion.ts # packages/video-conversion/CHANGELOG.md # packages/video-conversion/README.md # packages/video-conversion/src/index.ts # packages/video-conversion/src/video-conversion-worker.ts
|
@jasmussen - I tried moving the progress indicator to the snackbar in 2970d39: the block canvas is untouched now (the image keeps its existing fade), and Since progress now lives on the upload queue item itself (readable via Screenshots
|
|
Honestly that looks pretty good at a glance! Did you make the actual progressbar hairline thicker? It's intentionally 1.5px which is small but visible and elegant. If it's unchanged, IMO, this could work. I still think there's a larger vision we can unpack at a later time. |
The height is set explicitly in https://github.com/WordPress/gutenberg/pull/80329/changes#diff-96ffb1246440442d4d45343faaa6ee39c03d36f5757ee78124ad42a94e2abe51R28, I will try removing that height style to capture a screenshot of what it looks like without that. |
|
Height removed:
I think thats about 2px vs 4 px? How does that look @jasmussen? |
The 1.5px hairline is an intentional part of the component's design and reads fine on the snackbar, so drop the 4px height override and keep only the width and foreground-color adjustments.
|
That looks perfect. In general for all our reused componentry, the less CSS we can add on top of it, the better, so it all looks the same across every instance! Nice. |
|
Thanks for the reviews and approval @jasmussen. I'll leave this open a bit longer to get a code review as well, and I think we can land this before the next Beta. |
|
I like the idea of a progress bar and when it displays I quite like the look of it, too. The main issue I've run into in testing is just that for the majority of smaller GIFs I upload the conversion stage is so quick it effectively looks like a flicker, rather than a good bit of visual feedback. I.e. in the following, the progress bar only shows for a frame or two: 2026-07-23.14.17.24.mp4This is probably more of a design question, but if I'm wondering if we should stick with either the spinner or the progress bar, and not switch from spinner to progress bar to spinner? I imagine the blocker to using a progress bar overall is that we then sort of need to bake in the overall progress across the entire upload sequence rather than just the GIF processing stage? |
Came to do some manual testing and I can't see the progress bar at all. I think I'm doing something wrong. I understand there's an upper limit, but I tried:
GIFs, and all only show the upload snackbar, no progress indicator. Kapture.2026-07-23.at.14.31.58.mp4To confirm, I'm using latest Chrome running this branch freshly built. (also checked playground) Here's one of the GIFs I'm using (5.7MB)
|
Ha its too fast now!
@ramonjd Can you confirm the companion video is generated for you (you can watch for it sideloading in the network panel, check your uploads folder or check if you have an option to transform the gif to a video). Note that videos with transparency are not converted. @andrewserong can you also confirm you are getting the conversion working? |
Yep, the videos are being converted to video for me, it's just that the processing stage for some of these test GIFs is so quick. As such, I'd probably suggest we take a look at this PR for 7.2 rather than 7.1 and see if we can have the progress bar contain the whole upload progress between conversion + file uploads etc, rather than switching between spinner + progress bar and back again. One nuance there is that the server-side / non-client-side path will probably never be able to have an accurate progress bar since we don't have the same level of insights into what the real progress will be, so I imagine there'll still be a case where we want to sometimes show progress bar and sometimes a spinner. What do you reckon? Does this change feel like a must have for 7.1? |
Thanks for the help. I used a different gif from https://commons.wikimedia.org/wiki/Category:Animated_GIF_files_between_50_MP_and_100_MP and now I can reproduce what @andrewserong is experiencing. mp4 is being generated fine 👍🏻 This is a 15MB GIF: Kapture.2026-07-24.at.13.02.49.mp4 |
Nope. For sure lets punt to 7.2. I'm curious if you throttle your CPU (in the performance tab) can you get the progress bar to display? I think the optimization PRs just made it really efficient so maybe we don't even need this. |
|
If we decide to enable Animated GIF sub-sizes, the processing time increases dramatically so we may want to show progress... but the indicator may be more of a "processing image X of Y" string vs a bar. |
Yeah, funnily enough CPU throttling (even by 20x) doesn't make much of a difference to the duration of when the progress bar is showing for me 🤷
Gotcha, yeah, sounds like a good thing to review all together when we pick up that work for 7.2 👍 |
Interesting... I'll give it another test! |
…rogress # Conflicts: # packages/editor/CHANGELOG.md # packages/editor/src/components/upload-progress-snackbar/stories/index.story.tsx # packages/editor/src/components/upload-progress-snackbar/test/index.js
# Conflicts: # packages/editor/src/components/upload-progress-snackbar/index.jsx # packages/editor/src/components/upload-progress-snackbar/test/index.jsdom.test.jsx # packages/upload-media/src/store/test/private-actions.js
🤖 PR meta 🤖📦 Bundle sizeSize Change: +485 B (+0.01%) Total Size: 8.21 MB 📦 View Changed
⚡ PerformanceShow the resultsClient side metrics exclude the server response time. front-end-block-theme
front-end-classic-theme
media-processing
media-upload
post-editor
site-editor
🏁 Flaky testsShow the failuresSome tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information. can use focal point picker to set the focal point of the cover image in
|
These files run under Vitest, where `jest` is not defined. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RtZdDWdC33cNHfY4U238A5
…rogress # Conflicts: # packages/editor/src/components/upload-progress-snackbar/index.jsx # packages/video-conversion/README.md
|
Closing this as not planned, we can tackle progress for other operations like gif->gif subsizes in a follow up. |






What?
Fixes #80325.
Shows determinate progress in the editor's upload progress snackbar while an animated GIF is being converted to a video: the snackbar's spinner is replaced with a determinate
ProgressBarand the label switches from "Uploading" to "Processing". The block canvas is untouched - the image keeps its existing fade treatment.Follows the direction in this review comment: an earlier iteration overlaid the progress bar on the Image block itself, which doesn't scale to small images and puts per-item processing UI on the block rather than in the shared upload surface.
Why?
Converting a long animated GIF to a video (#76942, #80072) can take tens of seconds: every frame is decoded and re-encoded via WebCodecs. #80260 fixed the outright hang, but during a legitimately long conversion the author only sees an indeterminate spinner with no indication of how far along the conversion is or whether it is making progress at all.
Exact progress is available for free: the conversion loop reads the total frame count up front (
ImageDecodertrack.frameCount) and processes frames one at a time, soframesDone / frameCountis precise. Encoder backpressure happens inside the same loop, so the frame index tracks wall-clock progress closely.How?
Data layer:
convertGifToVideo()in@wordpress/video-conversionaccepts an optionalonProgresscallback reporting a 0–1 fraction. It is throttled to whole-percent increments so a thousand-frame GIF doesn't flood the worker message channel. The worker RPC layer (comctx) proxies top-level function arguments across the worker boundary, so the callback passes straight through.transcodeGifItem()in@wordpress/upload-mediadispatches the previously dormantupdateItemProgress()action from that callback. (QueueItem.progress, theUPDATE_PROGRESSreducer case, andgetItemProgress()already existed with no producers or consumers.) Dispatches are additionally time-gated to one per 250ms: without this, a fast conversion emits ~100 reports in a couple of seconds and each dispatch synchronously re-renders every upload-store consumer in the editor, saturating the main thread so the browser never paints the bar. The final report always goes through.getItems()selector; no new store API is added.UI:
UploadProgressSnackbarlooks for a queue item reporting progress below 100 (the conversion runs on a sideload companion item, so the full queue is scanned rather than just the originals it counts). While one exists, the notice icon slot renders a determinateProgressBar(from@wordpress/components) instead of theSpinner, and the label reads "Processing — file.gif" (with the usual "x of y" form for batches).--wp-components-color-foregroundcustom property, 4px tall, 48px wide) and the notice text is indented to clear the wider icon slot.Out of scope: network upload progress for the resulting video file (
apiFetchdoesn't expose upload progress; for long GIFs the conversion phase dominates).Testing Instructions
The states can also be reviewed in Storybook:
Editor/UploadProgressSnackbar.Unit tests:
Note: there is no e2e assertion for the transient Processing state because conversion of the small e2e GIF fixtures completes in well under a second, which would make the assertion flaky. The data flow (worker progress reports, throttling, snackbar states) is covered by unit tests.
Screenshots
(Updated screenshot of the snackbar's Processing state incoming.)