- Update mediaHandlers.ts to accept an optional forcedThumbnailUrl in updateSpreadsheetThumbnail, enabling updates without re-fetching backend state.
- Update MediaManager.html execution plan to trigger the sheet update immediately (optimistically) using the predicted first item from the plan, running in parallel with other execution phases.
- Ensure the execution flow waits for both the sheet update and other operations to complete before finishing.
- Add failing global function verification test (GlobalFunctions.test.ts) and fix missing exports in global.ts.
- Refactor MediaManager.html UI:
- Implement
enderPlanHtml to standardize Plan (Details) and Execution views.
- Show 'Skipped' state for empty save phases.
- Visually decouple 'Sheet Update' from 'Reorder' phase.
- Separate 'Manual Link' operations into their own 'Linking' section in the plan view, distinct from Adoptions.
- Fix TypeErrors in
enderPlanHtml (undefined actions) and
enderMatch (missing DOM elements).
- Update MediaService.test.ts to match new filename constraints on reorder.
- Update mediaHandlers.test.ts to correctly spy on loose MediaService instances.
- Ensure all tests pass.
Significant performance improvements to the 'Loading media...' phase:
- Reduced client-server round trips by consolidating the initial handshake (diagnostics + media fetch) into a single backend call: getMediaManagerInitialState.
- Implemented batched Google Drive metadata retrieval in GASDriveService using the Advanced Drive API, eliminating per-file property fetching calls.
- Switched to HtmlService templates in showMediaManager to pass initial SKU/Title data directly, enabling the UI shell to appear instantly upon opening.
- Updated documentation (ARCHITECTURE.md, MEMORY.md) to clarify Webpack global assignment requirements for GAS functions.
- Verified with comprehensive updates to unit and integration tests.
- Remove recursive polling in MediaManager.html; context is now loaded once at startup.
- Optimize getSelectedProductInfo in mediaHandlers.ts to reduce SpreadsheetApp API calls.
- Update related tests to match new optimization.
- **UI Overhaul**: Moved the activity log to a dedicated, expandable card at the bottom of the Media Manager modal.
- **Styling**: Updated the log card to match the application's light theme using CSS variables (`--surface`, `--text`).
- **Log Streaming**: Replaced batch logging with real-time streaming via `CacheService` and `pollJobLogs`.
- **Session Resumption**: Implemented logic to resume log polling for active jobs upon page reload.
- **Fixes**:
- Exposed `pollJobLogs` in `global.ts` to fix "Script function not found" error.
- Updated `mediaHandlers.test.ts` with `CacheService` mocks and new signatures.
- Removed legacy auto-hide/toggle logic for the log.
- Update MediaService delegation tests in src/mediaHandlers.test.ts to use mock.results for more reliable instance retrieval.
- Fix CellImageBuilder failure in src/mediaHandlers.ts by using public Shopify thumbnail URLs for synced items and direct Drive thumbnail endpoints for non-synced items.
- Fallback to IMAGE() formula in the spreadsheet for Drive items to avoid authentication issues with native cell images.
- Add test_*.txt to .gitignore to keep the workspace clean.
- Ensure all tests pass with updated log expectations and mock data.
- Implemented "sidecar" thumbnail logic: imports video thumbnails from Google Photos as hidden Drive files to display immediately while videos process.
- Updated MediaService to serve sidecar thumbnails via server-side Base64 encoding, bypassing CORS restrictions.
- Implemented lifecycle management: detects video processing completion to automatically cleanup sidecar files and fallback to native Drive thumbnails.
- Enhanced Media Manager UI: added processing warning banner and refined processing tile styling (centered, lighter overlay).
- Upgraded Drive API to v3 and improved file creation robustness with Advanced API fallbacks.
This commit fixes a bug where videos imported from the Google Photos Picker were being downloaded as static thumbnails. Changes include: 1. Frontend (MediaManager.html): Correctly access nested 'mediaFile' properties from the Picker API response to ensure valid mimeType and filename are passed to the backend. Restored logic to force 'video/mp4' mimeType if 'mediaMetadata.video' is present. Added debug logging. 2. Backend (mediaHandlers.ts): Restored missing 'else if' block for URL handling that was causing 'No File ID' errors. Implemented logic to append '=dv' parameter for video downloads. Added safeguard to rename downloaded files to '.mp4' if the content type is video but the extension is wrong.
- Added matching wizard to MediaManager.html for linking Drive files to orphaned Shopify media on load.
- Updated MediaService.ts to extract filenames from Shopify URLs for better matching.
- Added linkDriveFileToShopifyMedia method to MediaService and exposed it via mediaHandlers and global.ts.
- Improved UX in MediaManager with image transition clearing and button state feedback.
- Resolved persistent 'SyntaxError: Unexpected token class' by refactoring 'MediaState' and 'UI' classes in MediaManager.html to standard ES5 function constructors.
- Resolved 'SyntaxError: Unexpected identifier src' by rewriting 'createCard' to use 'document.createElement' instead of template strings for dynamic media elements.
- Consolidated script tags in MediaManager.html to prevent Apps Script parser merge issues.
- Updated docs/ARCHITECTURE.md and MEMORY.md to formally document client-side constraints (No ES6 classes, strict DOM manipulation for media).
- Note: Google Drive video animate-on-hover functionality is implemented but currently pending verification/fix.
- **UI Refactor**:
- Split Media Manager header into two distinct cards: 'Product Info' and 'Upload Options'.
- 'Product Info' now displays the Product Title and SKU.
- Renamed upload buttons to 'Google Drive', 'Google Photos', and 'Your Computer' for clarity.
- Added global drag-and-drop support with overlay.
- Replaced full-screen 'Connecting' overlay with an inline spinner for better UX and log visibility.
- **Backend**:
- Renamed getSelectedSku to getSelectedProductInfo in mediaHandlers.ts to fetch and return both SKU and Title.
- Updated global.ts exports and mediaHandlers.test.ts to support the new signature.
- **Fixes**:
- Resolved an infinite loop issue in loadMedia caused by incorrect SKU state handling.
This major refactor addresses improper image matching and duplication:
- Implemented strict ID-based matching in 'MediaService', removing the greedy filename matching fallback.
- Redesigned synchronization pipeline to treat Google Drive as the Source of Truth, supporting orphan adoption (Shopify -> Drive) and secure uploads.
- Implemented 'gallery_order' using Drive file properties (supporting both v2 and v3 APIs) for stable, drag-and-drop global ordering.
- Added conditional file renaming using timestamps to enforce '_' naming convention without unnecessary renames.
- Fixed runtime errors in 'MediaService' loops and updated 'ShopifyMediaService' GraphQL mutations to match correctly schema.
- Rewrote 'MediaService.test.ts' with robust test cases for strict matching, adoption, sorting, and reordering.
- Renamed src/MediaSidebar.html to src/MediaManager.html to align with modal UI.
- Fixed race condition in Photo Picker polling preventing duplicate imports.
- Updated global.ts, initMenu.ts, and mediaHandlers.ts used in the fix.
- Fixed unit tests for mediaHandlers.
- Implement DriveService and ShopifyMediaService for backend operations
- Create MediaSidebar.html with premium UI and auto-polling
- Integrate Google Picker API for robust file selection
- Orchestrate sync logic via MediaService (Drive -> Staged Upload -> Shopify)
- Add secure config handling for API keys and tokens
- Update ppsscript.json with required OAuth scopes
- Update MEMORY.md and README.md with architecture details