Commit Graph

173 Commits

Author SHA1 Message Date
Jonathan Sykes
171a0bd127 Glass Stage buffered chip: 'Saved on device' for device copies, and measure the range around the playhead
It read the last buffered range, so seeking ahead made the figure jump, and a
device copy showed a meaningless partial percentage.
2026-10-03 01:00:09 +08:00
Jonathan Sykes
cbffa1fd8b Saves: paint progress only on Downloads rows, not on search/playlist cards
Every card of a video carries .downloading while it saves, so the progress
painter rewrote their channel line and its final repaint left 'Saving for
offline…' on the card after the save had finished.
2026-10-03 00:59:18 +08:00
Jonathan Sykes
56b3f4e449 Resumable saves: ranged downloads that survive dropped connections, reloads and app kills
Server
- /api/download/:id answers Range with a strong ETag ("<id>.<gen>") and honours
  If-Range; a stale partial gets the whole current file (streamed, so Bun does
  not re-apply the Range itself). Uploads get the same treatment.
- GET /api/download/:id/prepare never blocks: ready {gen,size,sha256,etag,ext},
  working (server still fetching), legacy (HEVC / too long / cache offline),
  failed. Recently refused prepares are remembered for 10 minutes.

Browser
- The OPFS worker saves in 8 MiB ranges, writes at the byte offset, flushes
  each chunk, retries each chunk 6 times with backoff (30 s idle timeout) and
  keeps the .part plus a .part.json sidecar naming the server copy it belongs
  to. A changed copy restarts cleanly; the finished file is hashed once and
  checked against the server's SHA-256.
- SaveQueue remembers unfinished saves and resumes them on start, online,
  return to the foreground and every 2 minutes while visible; one at a time.
- Downloads shows live MB progress, 'Preparing on server', 'Verifying', and
  paused saves with Resume and Cancel (confirmed).
- listVideos ignores the sidecars; new listPartials/discardPartial helpers.

Verified in Chromium through a connection-dropping proxy: paused at 8 MiB,
auto-resumed after a reload from byte 8388608, final SHA-256 matched.
2026-10-03 00:46:52 +08:00
Jonathan Sykes
11ddb8a970 Uploads library on the USB drive with a nightly stable-disk copy; Topic channels resolve by name
- UPLOAD_DIR moves to the USB drive; reads fall back to UPLOAD_BACKUP_DIR on the
  ytplayer-data volume, and while the drive is offline new uploads land there
- scripts/ops/uploads-backup.sh (homelab cron, 03:30) copies both ways, never
  deletes; the server removes a deleted upload from both places
- /api/channel resolves a bare channel name ('Artist - Topic') to its id via a
  search, and the client falls back to the channel name for old saved entries
2026-10-02 22:38:05 +08:00
Jonathan Sykes
53da71ceb9 Service mode: one view button (default, lyrics, video, visualizer, album art) and a text-size box
- A single dock button cycles the service view; video is skipped in audio-only mode
- Visualizer reacts to the audio where the EQ graph is available and falls back
  to an ambient pulse on iOS so background playback is never routed through Web Audio
- Album art shows the song artwork with the letterbox cropped
- A-/A+ box steps lyrics, title and channel size from -2 to +2 in every theme
- Glass Stage dock is slightly more compact
2026-10-02 21:11:15 +08:00
Jonathan Sykes
985063648f Icon-only playlist header and filter-row actions, one-row transport, resumable update download
- Playlist title wraps within 90% of the width; rename and share are icons beside it,
  and tapping the title opens the rename box showing the full name
- Offline, pin, select and delete are icon buttons to the right of the filter input
- Transport is one row again: prev, back 10, play, forward 10, next
- Update download stages each file as it arrives so a retry only fetches what is
  missing, keeps 4 requests in flight and allows 5 minutes
2026-10-02 20:59:51 +08:00
Claude
ee248d2303 IndexedDB search library (1000x100, 15-day copies, Update search), server video metadata for instant local results 2026-10-02 02:15:28 +00:00
Claude
14e2307a92 Keep search results with thumbnails until cleared in Settings; add stale-while-revalidate search and longer asset caching 2026-10-01 22:04:51 +00:00
Claude
61a8f63385 Make the channel name a visible link directly under the title 2026-10-01 21:54:39 +00:00
Claude
8c463f3834 Rebuild the Glass Stage A-B quick row and restyle the title block with a verified badge 2026-10-01 21:51:38 +00:00
Claude
6bf2636864 Bring Glass Stage closer to the mockup: HUD chips, sleep card, chapter badge, A-B group, playlist banner and P2P strip 2026-10-01 21:45:44 +00:00
Claude
19973c75c0 Add the Glass Stage layout theme with overlay controls, 10 s skips, quick chips and stacked tiles 2026-10-01 21:40:20 +00:00
Claude
36fc5ff9e4 Merge Queue and Playlist into one Add button and put Service mode in the common actions 2026-10-01 21:17:37 +00:00
Claude
859ecd2255 Move speaker and playback mode beside the volume slider with a volume-aware icon 2026-10-01 21:13:27 +00:00
Claude
b3a43c66db Label the fullscreen button, add a mini fullscreen icon and show A-B markers beside it 2026-10-01 21:09:00 +00:00
Claude
25e7a28b6a Merge shuffle, repeat list and loop one into one playback mode button 2026-10-01 21:03:48 +00:00
Claude
f9cb7edeb2 Replace transport emoji with centred SVG icons and distinguish loop-one from repeat-list 2026-10-01 21:02:23 +00:00
Claude
9f313f61af Move secondary player controls into a More controls sheet 2026-10-01 20:58:15 +00:00
Claude
88f878b8eb Move rarely used video actions into a More actions sheet 2026-10-01 20:55:04 +00:00
Claude
9eb5e98048 Add Gallery action beside Save and an icon-only refresh beside Play all 2026-10-01 20:39:17 +00:00
Claude
02b337fcbc Add save-to-device export, server export route and an On other devices P2P list 2026-10-01 18:53:00 +00:00
Claude
9d74769029 Add deck tabs, uniform action buttons, lyric reports in the player panel and a song list in the lyrics studio 2026-09-30 15:57:11 +00:00
Claude
e64880c163 Redesign playlist header, player deck, now-playing actions and lyrics panel layout 2026-09-30 15:29:44 +00:00
Claude
04a74ab45d Redesign service-mode controls and add per-profile wrong-lyric-line reports 2026-09-30 15:15:07 +00:00
Claude
c8837befed Download a verified file from another device over WebRTC 2026-09-30 07:54:34 +00:00
Claude
8d57a654c1 Let a device hand a file to the server for hashing and validation 2026-09-30 07:50:38 +00:00
Claude
61d0274896 Show peer availability with stale markers and add Sharing settings 2026-09-30 07:45:13 +00:00
Claude
c629ff5836 Register devices and report verified holdings to the server 2026-09-30 07:38:47 +00:00
Claude
6af96622dd Add the on-device IndexedDB file registry and hash saves while downloading 2026-09-30 07:31:18 +00:00
Claude
b24366d6c0 Warm the stream cache for likely next plays 2026-09-30 06:53:48 +00:00
Claude
7781e0a116 Add startup, search and play timing marks plus yt-dlp duration logs 2026-09-30 06:41:50 +00:00
Jonathan Sykes
56d0838391 support shareable search links via a ?q= URL parameter 2026-09-30 00:19:20 +08:00
Jonathan Sykes
74777ef87f show a lightning icon on recent searches that will load instantly 2026-09-30 00:18:22 +08:00
Jonathan Sykes
4f0ee45980 cache recent search results locally so re-running one is instant 2026-09-30 00:16:35 +08:00
Jonathan Sykes
6480b314d5 remember recent searches on-device and show them under the search box 2026-09-29 22:08:16 +08:00
Jonathan Sykes
ba697e5d11 floor service-mode lyric font size and space out verses 2026-09-26 02:11:07 +08:00
Jonathan Sykes
05e85a0a3f Give untimed lyrics one uniform line size in service mode 2026-09-24 08:34:09 +08:00
Jonathan Sykes
d64c5f2613 Lift the section rail clear of the floating mini player 2026-09-22 14:58:31 +08:00
Jonathan Sykes
aa92fb1f05 Count a bottom bar that stops above the home indicator when placing the rail 2026-09-22 14:33:31 +08:00
Jonathan Sykes
c9e021a045 Keep the watch party panel above the bottom bars so its leave button is reachable 2026-09-22 14:23:39 +08:00
Jonathan Sykes
6c4571cb33 Measure the bottom bars so the section rail is never hidden behind the mini player 2026-09-22 14:09:03 +08:00
Jonathan Sykes
530d07d920 Add a mobile section rail that follows the scroll, jumps between cards and folds the one you are on 2026-09-22 13:47:26 +08:00
Jonathan Sykes
987697e759 Paint saved playlists before the launch sync and swap a background-downloaded update instantly 2026-09-22 13:27:12 +08:00
Jonathan Sykes
2a4526578f Show lyrics in place of the video for watch parties and sing-alongs 2026-09-21 21:03:46 +08:00
Jonathan Sykes
b983c6ca3c Fetch lyrics from LRCLIB (synced when available) and serve an admin media library of uploaded video and audio with cover art and embedded lyrics 2026-09-20 05:59:50 +08:00
Jonathan Sykes
9c1ec4ac51 Add presenter view, stats, lyrics worker, watch party with voice chat, timestamp sharing, soundbites, notes, transcript search, PiP, EQ, sleep fade, gestures and external players; fix the crossfade end-of-song race 2026-09-20 00:07:12 +08:00
Jonathan Sykes
ca07e1fdf1 Add gapless and crossfade playlist transitions with a mode toggle, and a waveform seek bar for audio-only playback 2026-09-19 16:12:33 +08:00
Jonathan Sykes
71fc51fb50 Add a lyrics-only service mode view with the sung line centred and auto-sized, and a free local faster-whisper script to transcribe saved songs 2026-09-19 08:33:00 +08:00
Jonathan Sykes
b82f17cd46 Add phone remote control: pair a phone with a 6-digit code or QR to drive a desktop instance's playback, queue, volume, sleep timer and service mode 2026-09-18 20:19:00 +08:00
Jonathan Sykes
524db986d2 Add shared synced lyrics, chapters and personal bookmarks with revision history, API tokens and an admin page 2026-09-18 18:10:10 +08:00