From 64ab548593c2042facf6c55bec56a91b071d205d Mon Sep 17 00:00:00 2001 From: Ben Miller Date: Wed, 31 Dec 2025 01:08:12 -0700 Subject: [PATCH] Fix Shopify video preview propagation on save Updates logic to detect processing state (including READY-but-no-sources race condition) and propagates contentUrl updates to the frontend immediately. --- src/MediaManager.html | 4 +++- src/services/MediaService.test.ts | 25 +++++++++++++++++++++++++ src/services/MediaService.ts | 17 +++++++++++++++++ src/services/ShopifyMediaService.ts | 1 + 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/MediaManager.html b/src/MediaManager.html index 84a0218..394937c 100644 --- a/src/MediaManager.html +++ b/src/MediaManager.html @@ -464,7 +464,7 @@ style="display:none; background-color:#fffbeb; color:#92400e; padding:12px; border-radius:8px; margin: 0 16px 12px 16px; font-size:13px; border:1px solid #fcd34d; align-items:flex-start; gap:8px;">
- Some videos are still being transcoded by Drive. The video preview might not work yet, but they can still be saved, + Some videos are still being processed. The video preview might not work yet, but they can still be saved, reordered, or deleted.
@@ -1516,6 +1516,8 @@ console.log("[MediaManager] Processing complete for " + item.filename); item.isProcessing = false; item.thumbnail = newItem.thumbnail; + item.contentUrl = newItem.contentUrl; // Propagate URL + item.source = newItem.source; // Propagate source update (synced) changed = true; } } diff --git a/src/services/MediaService.test.ts b/src/services/MediaService.test.ts index 3668072..10e68c4 100644 --- a/src/services/MediaService.test.ts +++ b/src/services/MediaService.test.ts @@ -304,4 +304,29 @@ describe("MediaService Robust Sync", () => { expect(item.isProcessing).toBe(true) expect(item.thumbnail).toContain("data:image/svg+xml;base64") }) + + test("Processing: Marks item as processing if Shopify status is PROCESSING", () => { + const folder = driveService.getOrCreateFolder("SKU_SHOP_PROCESS", "root") + + // Drive File + const blob = { getName: () => "vid.mp4", getBytes: () => [], getMimeType: () => "video/mp4", getThumbnail: () => ({ getBytes: () => [] }) } as any + const f = driveService.saveFile(blob, folder.getId()) + driveService.updateFileProperties(f.getId(), { shopify_media_id: "gid://shopify/Media/Proc1" }) + + // Shopify Media (Processing) + shopifyService.getProductMedia = jest.fn().mockReturnValue([ + { + id: "gid://shopify/Media/Proc1", + filename: "vid.mp4", + mediaContentType: "VIDEO", + status: "PROCESSING", + preview: { image: { originalSrc: null } } // Preview might be missing during processing + } + ]) + + const state = mediaService.getUnifiedMediaState("SKU_SHOP_PROCESS", "pid") + const item = state.find(s => s.id === f.getId()) + + expect(item.isProcessing).toBe(true) + }) }) diff --git a/src/services/MediaService.ts b/src/services/MediaService.ts index d9339b9..bc9c006 100644 --- a/src/services/MediaService.ts +++ b/src/services/MediaService.ts @@ -106,6 +106,8 @@ export class MediaService { if (props['custom_thumbnail_id']) customThumbnailId = props['custom_thumbnail_id']; if (props['parent_video_id']) parentVideoId = props['parent_video_id']; + console.log(`[DEBUG] File ${f.getName()} Props:`, JSON.stringify(props)); + } catch (e) { console.warn(`Failed to get properties for ${f.getName()}`) } @@ -239,6 +241,21 @@ export class MediaService { console.log(`[MediaService] Using Sidecar Thumbnail for ${d.file.getName()}`); thumbnail = sidecarThumbMap.get(d.file.getId()) || ""; isProcessing = true; // SHOW HOURGLASS (Request #3) + } else if (match && ( + match.status === 'PROCESSING' || + match.status === 'UPLOADED' || + (match.mediaContentType === 'VIDEO' && (!match.sources || match.sources.length === 0) && match.status !== 'FAILED') + )) { + // Shopify Processing (Explicit Status OR Ready-but-missing-sources) + console.log(`[MediaService] Shopify Media is Processing: ${d.file.getName()} (Status: ${match.status}, Sources: ${match.sources ? match.sources.length : 0})`); + isProcessing = true; + // Use Drive thumb as fallback if Shopify preview not ready + if (!thumbnail) { + try { + const nativeThumb = `data:image/jpeg;base64,${Utilities.base64Encode(d.file.getThumbnail().getBytes())}`; + if (nativeThumb.length > 100) thumbnail = nativeThumb; + } catch(e) {} + } } else { // 2. Native / Fallback try { diff --git a/src/services/ShopifyMediaService.ts b/src/services/ShopifyMediaService.ts index fb5e892..0867c44 100644 --- a/src/services/ShopifyMediaService.ts +++ b/src/services/ShopifyMediaService.ts @@ -73,6 +73,7 @@ export class ShopifyMediaService implements IShopifyMediaService { id alt mediaContentType + status preview { image { originalSrc