feat(media): implement video processing polling and fallback
This commit adds robust handling for Google Drive videos that are still processing (lacking thumbnails). Changes include: 1. Backend (MediaService.ts): Implement try/catch around thumbnail generation. If it fails, return a placeholder and flag the item as 'isProcessing'. 2. Frontend (MediaManager.html): - Add polling logic to check for updates on processing items every 15s. - Add UI support for processing state: slate background, centered animated hourglass emoji. - Implement sand animation (toggling hourglass state) and rotation animation (180deg flip on poll event). - Fix badges and positioning issues.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -111,6 +111,8 @@ export class MediaService {
|
|||||||
// Match Logic (Strict ID Match Only)
|
// Match Logic (Strict ID Match Only)
|
||||||
driveFileStats.forEach(d => {
|
driveFileStats.forEach(d => {
|
||||||
let match = null
|
let match = null
|
||||||
|
let isProcessing = false
|
||||||
|
let thumbnail = "";
|
||||||
|
|
||||||
// 1. ID Match
|
// 1. ID Match
|
||||||
if (d.shopifyId) {
|
if (d.shopifyId) {
|
||||||
@ -120,22 +122,37 @@ export class MediaService {
|
|||||||
|
|
||||||
// NO Filename Fallback matching per new design "Strict Linkage"
|
// NO Filename Fallback matching per new design "Strict Linkage"
|
||||||
|
|
||||||
|
if (match && match.preview && match.preview.image && match.preview.image.originalSrc) {
|
||||||
|
thumbnail = match.preview.image.originalSrc;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// Try to get Drive thumbnail
|
||||||
|
thumbnail = `data:image/jpeg;base64,${Utilities.base64Encode(d.file.getThumbnail().getBytes())}`;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`Failed to get thumbnail for ${d.file.getName()} (likely processing): ${e}`);
|
||||||
|
// Return a generic placeholder (Gray 1x1 pixel) + Flag as processing
|
||||||
|
// thumbnail = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
|
||||||
|
// Better placeholder: https://ssl.gstatic.com/docs/doclist/images/icon_10_movie_list.png (Video Icon) or just gray
|
||||||
|
thumbnail = "https://ssl.gstatic.com/docs/doclist/images/icon_128_video_blue.png"; // Official Video Icon
|
||||||
|
isProcessing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unifiedState.push({
|
unifiedState.push({
|
||||||
id: d.file.getId(), // Use Drive ID as primary key
|
id: d.file.getId(), // Use Drive ID as primary key
|
||||||
driveId: d.file.getId(),
|
driveId: d.file.getId(),
|
||||||
shopifyId: match ? match.id : null,
|
shopifyId: match ? match.id : null,
|
||||||
filename: d.file.getName(),
|
filename: d.file.getName(),
|
||||||
source: match ? 'synced' : 'drive_only',
|
source: match ? 'synced' : 'drive_only',
|
||||||
thumbnail: (match && match.preview && match.preview.image && match.preview.image.originalSrc)
|
thumbnail: thumbnail,
|
||||||
? match.preview.image.originalSrc
|
|
||||||
: `data:image/jpeg;base64,${Utilities.base64Encode(d.file.getThumbnail().getBytes())}`,
|
|
||||||
status: 'active',
|
status: 'active',
|
||||||
galleryOrder: d.galleryOrder,
|
galleryOrder: d.galleryOrder,
|
||||||
mimeType: d.file.getMimeType(),
|
mimeType: d.file.getMimeType(),
|
||||||
// Prefer Shopify Video URL for playback/hover if available, otherwise Drive Download URL
|
// Prefer Shopify Video URL for playback/hover if available, otherwise Drive Download URL
|
||||||
contentUrl: (match && match.sources)
|
contentUrl: (match && match.sources)
|
||||||
? (match.sources.find((s: any) => s.mimeType === 'video/mp4')?.url || match.sources[0]?.url)
|
? (match.sources.find((s: any) => s.mimeType === 'video/mp4')?.url || match.sources[0]?.url)
|
||||||
: `https://drive.google.com/uc?export=download&id=${d.file.getId()}`
|
: `https://drive.google.com/uc?export=download&id=${d.file.getId()}`,
|
||||||
|
isProcessing: isProcessing
|
||||||
})
|
})
|
||||||
// console.log(`[MediaService] File ${d.file.getName()} (${d.file.getId()}): Mime=${d.file.getMimeType()}, ContentUrl=https://drive.google.com/uc?export=download&id=${d.file.getId()}`)
|
// console.log(`[MediaService] File ${d.file.getName()} (${d.file.getId()}): Mime=${d.file.getMimeType()}, ContentUrl=https://drive.google.com/uc?export=download&id=${d.file.getId()}`)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user