feat: cloud upload — Google Drive & S3#36
Merged
jvillegasd merged 27 commits intomainfrom Mar 5, 2026
Merged
Conversation
Adds an About page to the options sidebar showing the extension icon, dynamic version (from chrome.runtime.getManifest()), description, and a "Made with ♥ by jvillegasd" link to the GitHub profile. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add S3Client with SigV4 signing (single-part and multipart upload) - Rewrite UploadManager to support both Google Drive and S3 concurrently - Wire onBlobReady hook through download handlers to upload before blob revocation - Add UPLOADING stage, cloud action buttons, and deferred upload via file picker in popup - Add autoUpload toggles, provider presets, test connection, and CORS helper in S3 options - Fix S3 enable checkbox show/hide to match Google Drive behaviour - Add tabs to Advanced options view (Retry & Reliability, Detection Caches, Performance) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pill design - Add .seg-tabs/.seg-tab to shared.css as a reusable pill/segmented control - Remove duplicate provider-tab and advanced-tab CSS from options.html - Update popup tab bar to use seg-tabs with full-width stretch - Dissolve popup tab container with surface-1→surface-0 gradient (no hard border) - Increase seg-tabs padding and tab height for better breathing room - Fix active tab using surface-3 so it's visually elevated above surface-2 container - Remove browser focus ring from seg-tab buttons Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds passphrase-based AES-GCM encryption for the S3 secret access key stored in chrome.storage.local, closing the OWASP insecure storage gap. - New SecureStorage class (Web Crypto API only, zero deps): PBKDF2 key derivation (SHA-256, 100k iterations) + AES-GCM 256-bit encrypt/decrypt - Passphrase cached in chrome.storage.session (auto-cleared on browser close) - StorageConfig.s3 gains secretKeyEncrypted?: EncryptedBlob alongside the existing plaintext fallback for unencrypted mode (opt-in) - Options S3 tab: passphrase + confirm fields; save encrypts and clears plaintext key; load shows encrypted placeholder; test connection decrypts via session cache or prompts the user - Service worker resolveS3Secret() decrypts before upload; skips S3 with a warning if passphrase is absent after a browser restart Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-upload was architecturally unsound — it held the full file in memory across two browser contexts simultaneously (offscreen + service worker) and blocked blob URL revocation until the upload completed. Removed: - performCloudUpload() and its onBlobReady hook from blob-utils - onBlobReady option from BasePlaylistHandler, DownloadManager, and all format/recording handlers (HLS, M3U8, DASH, recording) - autoUpload field from StorageConfig, AppSettings, loadSettings, and both options UI sections (Drive + S3 checkboxes) - uploadToDrive/uploadToS3 from DownloadState, DownloadManager, handleDownloadRequest, and DownloadRequestMessage Manual deferred upload (file picker → UPLOAD_REQUEST message → handleUploadRequestMessage) is fully preserved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the single-PUT "resumable" upload with a real chunked loop: - Use correct upload endpoint (/upload/drive/v3 vs /drive/v3) - Send X-Upload-Content-Type/Length in session init request - Upload in 8 MB chunks (multiple of 256 KB per spec) with Content-Range headers - Read Range response header on 308 to advance offset from server-confirmed position - Handle 404 (session expired) and 5xx as hard errors - Wire onProgress per chunk so the UI reflects actual byte progress Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drop MULTIPART_THRESHOLD from 100 MB to PART_SIZE (10 MB) so all files ≥ 10 MB get chunked progress instead of a single blocking PUT. S3 enforces a 5 MB minimum per part (except the last), so files < 10 MB must remain as single PUT — the threshold cannot go lower than PART_SIZE. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add CloudProvider type ('googleDrive' | 's3') to shared messages
- Show inline provider picker when both providers are configured;
skip picker when only one is enabled; block upload with alert when none
- Validate selected file is video/* before reading bytes; reject otherwise
- Route uploadBlob to a single chosen provider instead of allSettled across both
- Thread provider param through download-actions → service-worker → UploadManager
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduce BaseCloudProvider abstract base class so UploadManager no longer hard-codes per-provider branching. GoogleDriveClient and S3Client now extend BaseCloudProvider and expose a unified upload() method returning Promise<string>. UploadManager replaces concrete fields with a Map<CloudProvider, BaseCloudProvider> registry — adding a new provider requires only a new subclass + one registration line. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tion Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Completed downloads in Options → History now show an "Upload to cloud" menu item. Opens a file picker, sends the file to the service worker for S3/Google Drive upload. Shows a provider chooser dialog when both are configured. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enhances the history page to provide better feedback during cloud uploads. - Displays a circular progress indicator while an upload is in progress. - Adds an "UPLOADED" badge to history items once successfully uploaded. - Keeps the "Upload to cloud" action available even after completion. - Hides uploading items from the active downloads tab so they are only tracked in history.
…uplicate guard - CANCEL_UPLOAD: async handler that awaits IDB ops and cleans up tracking maps immediately after abort, preventing zombie records on delete - Duplicate upload guard: reject if upload already in progress for same item - onStateUpdate: check abort signal to stop writes between abort and cleanup - Wire upload progress: onProgress now updates percentage and fires onStateUpdate so the cloud fill icon animates from 0% to 100% - Abort check before success write: prevent overwriting cancelled state Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace circular progress spinner with a water-fill cloud icon: gray base cloud outline + arrow fills from bottom up with accent color. Cloud borders stroke with accent, arrow interior fills with accent, both rising like water as upload percentage increases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Thread AbortSignal through BaseCloudProvider, GoogleDriveClient, and S3Client so uploads can be cancelled mid-flight - Add CANCEL_UPLOAD message type to MessageType enum - Add cancel button styling for history upload progress indicator Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Persist in-flight multipart uploadIds to chrome.storage.local so orphaned uploads can be aborted on service worker restart, preventing storage cost leaks from crashed uploads. Also restore downloads stuck in UPLOADING stage back to COMPLETED on startup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Switch from getAuthToken() to launchWebAuthFlow() so users supply their own OAuth client ID at runtime (no manifest oauth2 section needed) - Add client ID input field with step-by-step setup instructions in options - Show redirect URI dynamically so users can copy it to Google Cloud Console - Auto-save Drive settings (enabled=true) after successful authentication - Extract persistDriveSettings() to DRY save logic between button and auth - Update README with full Google Drive and S3 cloud upload setup guide - Update cloud icon to new design Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Options page now listens for UPLOAD_COMPLETE messages and UPLOADING stage transitions so history items update in real time on upload failure/completion without requiring a page refresh. Service worker broadcasts DOWNLOAD_PROGRESS after upload failure. Also reverts cloud icons back to original stroke style. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…load Was hitting the metadata API base URL instead of the upload base URL, causing a parse error on file uploads under 5 MB. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Skip error logging and UploadError wrapping for AbortError (expected on cancel). Also fix DOMException stringification producing [object DOMException]. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CLAUDE.md: Replace "(Planned)" cloud section with full documentation covering upload flow, crash resilience, Google Drive OAuth setup, provider abstraction, S3 secret encryption, and updated project structure. README.md: Already updated in prior commit — no additional changes needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
launchWebAuthFlow— no Chrome Web Store requiredBaseCloudProviderpattern — add new providers by extending the base classCloud providers
launchWebAuthFlow)Test plan
🤖 Generated with Claude Code