Cloud Upload v2 — Client Enhancements (Pre-Brief)
Status: Pre-brief for PM shaping
Source: Deferred items from briefs/cloud-upload-v1.md
Designer involvement: Required for batch upload queue UI and upload history view
Researcher: Not needed — all items are well-understood patterns
Context
Cloud upload v1 shipped 2026-03-18: single file upload via toolbar button → file picker → PUT to server → rescan. Server-side is complete (nginx, cron, Lisp endpoint all deployed). These items are purely client-side enhancements to the existing UploadService.
Candidates (client-side only)
1. Multi-file / album batch upload
What: Select multiple files in the file picker, upload sequentially (or parallel?), show queue with per-file progress.
Why: Uploading an album track-by-track is painful. Users want to select 12 files and walk away.
Design questions:
- Queue UI: where does it live? Popover from the upload button? Dedicated panel section? Sheet?
- Progress: per-file progress bars or one aggregate bar?
- Failure handling: skip failed files and continue, or stop on first error?
- Ordering: preserve file picker order? Sort by filename?
Existing code to extend:
UploadService.swift (currently single-file), CloudHeaderView upload control
Estimate: Medium — UploadService needs queue state, new SwiftUI list view for queue
2. Drag-and-drop from Finder
What: Drag audio files from Finder onto the Cloud panel → triggers upload.
Why: More natural than click → file picker for users who have files visible in Finder.
Design questions:
- Drop target: entire Cloud panel? Just the header bar? A dedicated drop zone?
- Visual feedback: highlight border on drag hover?
- Multi-file: if batch upload isn't built yet, accept single file only?
Existing code to extend: Cloud panel views (
.onDrop modifier), UploadService
Estimate: Small — mostly a .onDrop handler that calls UploadService.startUpload()
3. Upload from "now playing" context menu
What: Right-click a local track in a playlist → "Upload to Cloud". Uploads the track's source file.
Why: "I'm listening to this, I want it in the cloud too" — zero-friction path.
Design questions:
- Only for local tracks (not cloud tracks, obviously)
- What if the track's source file was deleted? (SwiftData Track has filePath)
- Success feedback: toast? Inline indicator on the track row?
Existing code to extend: Context menus in
PlaylistView/TrackRow, UploadService
Estimate: Small — add menu item, read track.filePath, call upload
4. Auto-upload toggle
What: Setting in Preferences: "Auto-upload local tracks to cloud after playback" or "Auto-upload imported tracks".
Why: Set and forget — everything you play locally ends up in the cloud.
Design questions:
- Trigger: on import? On first play? On add to playlist?
- Scope: all tracks or only tracks in specific playlists?
- Dedup: what if it's already in the cloud? (v1 has no dedup — server-side concern)
- This feels like it could be surprising/annoying if enabled by accident
Existing code to extend: Settings, AudioEngine/PlayerViewModel play hooks, UploadService
Estimate: Small-Medium — simple toggle + hook, but the UX implications need thought
5. Upload history view
What: List of past uploads with status (success/failed), filename, timestamp, server response.
Why: "Did that upload finish? What did I upload yesterday?"
Design questions:
- Persistence: SwiftData? UserDefaults? In-memory only (lost on restart)?
- UI location: section in Cloud panel? Settings tab? Separate sheet?
- Actions: retry failed? Clear history?
- How much history to keep? (last 50? last 7 days?)
Existing code to extend: New model + view, UploadService logs completions
Estimate: Medium — needs persistence model, new view, UploadService hooks
Suggested grouping for PM
Quick wins (ship together, small appetite):
- Upload from context menu (#3)
- Drag-and-drop from Finder (#2)
Batch upload (own brief, medium appetite):
- Multi-file upload (#1) — designer needed for queue UI
- Upload history (#5) — designer needed, pairs naturally with batch
Defer further:
- Auto-upload (#4) — needs more thought on UX implications, dedup dependency
Server-side items (not in this pre-brief)
- Server-side dedup (chromaprint/acoustid) — needs server work
- Resumable uploads — needs server protocol changes
- Beets on synchronous path — server architecture change