13 Commits

Author SHA1 Message Date
Jonathan Sykes
3ad2e40606 Refresh Windows release artifacts and sync build outputs 2026-06-21 16:15:30 +08:00
Jonathan Sykes
b67e40348b Move all completed items to Done section with commit hashes 2026-06-14 15:30:00 +08:00
Jonathan Sykes
d15d9021b7 Add cache cap, playlist export/import, yt-dlp build flag
Cache cap: dropdown setting (no limit / 1/2/5/10 GB) stored in
settings.cacheCap (actual eviction handled by native side).
Export: downloads playlists as JSON via Blob. Import: file reader
merges new playlists by id. yt-dlp: feature gate 'embed-ytdlp'
(default on), skip with --no-default-features for faster debug builds.

Files:
- frontend/app.js: exportPlaylists/importPlaylists, cache cap select
- src-tauri/Cargo.toml: [features] embed-ytdlp
- src-tauri/src/main.rs: #[cfg(feature = embed-ytdlp)] guards
2026-06-14 15:29:10 +08:00
Jonathan Sykes
c6b8dfceb8 Add rotating quick-search chips, video_id sanitize, retry button
Rotating chips: 4 sets of 4 chips rotate every 8 seconds on the
hero landing. Sanitize video_id: new sanitizeId() strips path
separators and dangerous chars. Retry button: appears on stream
extraction failure, re-triggers Player.loadVideo.

Files:
- frontend/app.js: sanitizeId(), CHIP_SETS + rotateChips(),
  retry button in loadVideo catch
2026-06-14 15:23:14 +08:00
Jonathan Sykes
c1855a1a91 Add persistent mini now-playing bar
Fixed bar at bottom of window when video is playing. Shows title,
channel, progress, play/pause toggle. Click to restore player view.

Files:
- frontend/index.html: mini-bar markup
- frontend/app.js: showMiniBar/hideMiniBar/updateMiniBar, wiring
- frontend/styles.css: .mini-bar, .mini-bar-inner, .mini-progress styles
2026-06-14 15:18:57 +08:00
Jonathan Sykes
4376cd9e88 Add up-next queue panel
Shows upcoming videos in the autoplay queue below now-playing meta.
Clickable to jump to any video. Hidden when queue has 1 item or empty.
Updates on playFromList, playNext, playPrev. Hidden in empty player state.

Files:
- frontend/index.html: upnext section in player pane
- frontend/app.js: renderUpNext(), wired into playFromList/playNext/playPrev
- frontend/styles.css: .upnext, .upnext-item, .upnext-list styles
2026-06-14 14:44:52 +08:00
Jonathan Sykes
0ba0f56a54 Add drag-to-reorder within playlists
Cards in playlist view are draggable. Visual feedback: opacity on
source card, accent border on drop target. Reorder persists to store.

Files:
- frontend/app.js: dragSource state, drag/drop handlers on cards,
  container-level dragover guard in wireUI
- frontend/styles.css: .card.dragging, .card.drag-over styles
2026-06-14 14:41:05 +08:00
Jonathan Sykes
a4d6b825d5 Replace single toast with stacked toast queue
Multiple toasts can appear simultaneously, capped at 3. Oldest
toast auto-evicts when cap is reached. Each toast auto-dismisses
with a fade-up exit animation.

- frontend/app.js: toast() now creates DOM elements in toastContainer
- frontend/index.html: single #toast replaced with #toastContainer
- frontend/styles.css: .toast-container flexbox row, .toast-exit animation
2026-06-14 14:36:07 +08:00
Jonathan Sykes
ddfa1494c6 Remember and restore last playback position per video
Saves playback position to store on pause and periodically every
10s during playback. Restores position (>1s) when the same video
is loaded again, showing a 'Resumed from 0:42' toast.

Files:
- frontend/app.js: resumePositions in data, save in pause/timeupdate,
  restore in Player.afterLoad, boot merge includes resumePositions
2026-06-14 14:31:19 +08:00
Jonathan Sykes
81aced9bc5 Add download progress bar on card thumbnails
Replaces pulse-only state with a visible progress bar animation:
- Indeterminate bar slides across the bottom of card thumbnails during download
- markCardCacheState dynamically adds/removes the bar element
- renderCard includes the bar for newly rendered downloading cards
- Now-playing button already showed ' Saving…' state

Files:
- frontend/app.js: dl-progress in renderCard, markCardCacheState dynamic bar
- frontend/styles.css: .dl-progress, .dl-bar with dlSlide animation
2026-06-14 14:23:52 +08:00
Jonathan Sykes
c676786144 Add keyboard-shortcut help overlay
Press '?' to open a styled overlay showing all keyboard shortcuts,
Esc to close. Lists Space (play/pause), arrow keys (seek/volume),
F (fullscreen), M (mute), ? (help), Esc (close).

Files:
- frontend/app.js: toggleShortcutHelp(), wireShortcutHelp(), '?' and Esc handlers
- frontend/index.html: shortcut-overlay markup with .shortcut-grid
- frontend/styles.css: .shortcut-overlay, .shortcut-panel, .shortcut-row, kbd styles
2026-06-14 14:19:42 +08:00
Jonathan Sykes
da2ad27244 Add loading skeletons for search results
Replace bare 'Searching…' text with 8 animated skeleton cards that
mirror the real card layout (thumbnail, title, channel, menu dot).
Shimmer animation sweeps across placeholder blocks until results arrive.

Files:
- frontend/app.js: showSearchSkeletons() function, wired into search submit
- frontend/styles.css: .skeleton-card, .skeleton-shimmer, .skeleton-line, .skeleton-dot styles with shimmer animation
2026-06-14 14:14:05 +08:00
Jonathan Sykes
460aaae234 Add empty-state designs for empty playlists and history
Replaces bare status text with visual empty-state components:
- History: clock icon, 'Nothing watched yet' title, description, 'Search videos' CTA
- Playlist: music icon, 'This playlist is empty' title, description with tip, 'Browse videos' CTA
- Search: unchanged (hero landing handles this case)
- CTA buttons navigate to search view for quick action
2026-06-14 13:55:48 +08:00