Commit Graph

56 Commits

Author SHA1 Message Date
Jonathan Sykes
838798ca9b Build the new Bento Hub shell and browsing tiles 2026-10-04 03:09:15 +08:00
Jonathan Sykes
04b620e3c7 Polish download action buttons in Classic and Glass Stage 2026-10-04 02:48:08 +08:00
Jonathan Sykes
2042c9b6fc Recover related videos with bounded discovery and retryable fallbacks 2026-10-04 02:42:02 +08:00
Jonathan Sykes
df4acfc9f1 Keep iPhone audio playing through background handoffs 2026-10-04 02:29:10 +08:00
Jonathan Sykes
536555e12d Add selectable fullscreen orientation and an iPhone landscape overlay 2026-10-04 02:26:54 +08:00
Jonathan Sykes
3c0adb2577 Keep Glass Stage section navigation and panel content clear of playback chrome 2026-10-03 21:45:34 +08:00
Jonathan Sykes
5661eea6e6 Preview compatible fragmented MP4 transfers while saving the verified copy 2026-10-03 20:43:03 +08:00
Jonathan Sykes
08ff8398b5 Transfer saved songs directly between paired devices with resumable OPFS writes 2026-10-03 20:32:45 +08:00
Jonathan Sykes
5e78374efb Explain save failures and keep download diagnostics available 2026-10-03 19:23:07 +08:00
Jonathan Sykes
f2c9459a54 Unify Glass Stage navigation and page controls with Now Playing 2026-10-03 18:19:56 +08:00
Jonathan Sykes
8ea92c1aac Report phone playback metadata once per browser session 2026-10-03 17:56:01 +08:00
Jonathan Sykes
ca836e0cd2 Align saved video actions and confirm storage removal 2026-10-03 16:10:46 +08:00
Jonathan Sykes
cf9b6f4133 Clarify download states and make the empty page useful 2026-10-03 16:05:42 +08:00
Jonathan Sykes
0374e19396 Add lazy piano transcription and optional leased server worker 2026-10-03 15:47:53 +08:00
Jonathan Sykes
d4354d220e Preserve and display bilingual and phonetic lyric cues 2026-10-03 15:20:52 +08:00
Jonathan Sykes
c8ab741d72 Upgrade to ten-band EQ with migrated curves and headphone widening 2026-10-03 15:16:09 +08:00
Jonathan Sykes
0b3e82a768 Add voice search and large-control Car mode 2026-10-03 15:10:30 +08:00
Jonathan Sykes
172e8231f0 Import worship setlists with confirmed song matches and keys 2026-10-03 15:09:51 +08:00
Jonathan Sykes
de89508bf4 Add centre-panned vocal reduction to live and saved audio 2026-10-03 14:59:44 +08:00
Jonathan Sykes
7d84fdb3dc Add transparent OBS lyrics output through presenter pairing 2026-10-03 14:58:20 +08:00
Jonathan Sykes
05e05ebace Add learnable MIDI pedal controls with hot-plug support 2026-10-03 14:56:06 +08:00
Jonathan Sykes
b72d2e36a6 Add floating synced lyrics with picture-in-picture fallback 2026-10-03 14:54:23 +08:00
Jonathan Sykes
d7721045fb Add host-approved party suggestions and live upvotes 2026-10-03 14:52:10 +08:00
Jonathan Sykes
75dbc468cc Add download controls and device storage breakdown 2026-10-03 14:47:57 +08:00
Jonathan Sykes
09ae6a2a85 Organize settings into searchable sections with responsive navigation 2026-10-03 14:42:39 +08:00
Jonathan Sykes
ea9e11d054 Loudness levelling (EBU R128, -14 LUFS) measured in the browser with WebAssembly
- frontend/wasm/loudness.c → loudness-wasm.js (1.5 KB, base64-embedded; built by
  scripts/build-loudness-wasm.sh with clang or Zig's clang): K-weighting + 100 ms
  energy steps. loudness.js does the 400 ms gating (abs -70 LUFS, rel -10 LU)
  with an identical JS fallback. EBU Tech 3341 sine cases measure -23.0/-33.0
  on both engines; a real track reads -21.7 vs ffmpeg ebur128 -21.8.
- The device measures from audio it already has (saved copy or the server
  cache's m4a sidecar, songs up to 12 min, decoded natively at 22.05 kHz) and
  reports the number to /api/loudness, so each song is measured once for
  everyone; the server stores numbers only, no audio processing.
- The EQ graph gains a level stage (gain -> limiter) that eases each track
  toward -14 LUFS (-12..+9 dB). Settings -> Playback -> Level volume: on by
  default on Android/desktop, opt-in on iPhone (Web Audio stops sound when the
  screen locks there).
2026-10-03 07:44:44 +08:00
Jonathan Sykes
5154ef5f75 Collect discovered video metadata and recommend videos from listening history 2026-10-03 07:16:51 +08:00
Jonathan Sykes
343eb53d89 Redesign Classic layout for desktop and mobile 2026-10-03 06:44:22 +08:00
Jonathan Sykes
91627dc0a9 Share target: shared YouTube links play, shared audio/video uploads to the user's library; page shortcuts
- manifest share_target (POST multipart: title/text/url + audio/video files)
  and eight shortcuts (Search, Queue, Saved, Downloads, History, Library,
  Notes, Settings). /?view=<page> now actually opens that page — the old
  shortcuts pointed at it but nothing read it.
- sw.js receives the share: files are parked in the ytp-share-inbox cache (not
  a versioned shell cache, so deploys never evict it) and the app is opened;
  links/text go to /?shared=. A server POST /share-target fallback covers the
  first visit before a worker is in control (links only).
- The app plays a YouTube link found anywhere in the shared text (watch,
  youtu.be, shorts, live, embed, music; keeps t=), otherwise searches the text.
  /?shared=<link> also works from an iOS Shortcut (iOS has no share target).
- Shared files upload with progress to PUT /api/uploads/shared and join a
  "Shared uploads" playlist; network failures stay in the inbox for the next
  open, refusals are dropped with the reason.
- The public route is bounded: audio/video only (ffprobe-validated, error text
  without server paths), 500 MB per file, 2 GB and 20 a day per device, 50 GB
  for all shared uploads, one at a time per device (all env-tunable). Shared
  uploads are unlisted: reachable by id, never in anyone else's search.
  uploads gains owner + listed columns (idempotent ALTER).
2026-10-03 01:33:51 +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
Claude
0d92accd1d Run SHA-256 as WebAssembly with JS fallback; note ffmpeg.wasm as deferred 2026-10-02 11:10:51 +00:00
Claude
1b10a994dd Version-stamped static URLs cached forever, thumbnail cache 25000 with throttled trimming 2026-10-02 02:11:38 +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
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
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
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
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
b56be586ee Add an incremental SHA-256 library for the browser and node tests 2026-09-30 07:27:31 +00:00
Claude
663a33573a Self-host the three web fonts and drop the render-blocking Google Fonts CSS 2026-09-30 06:47:04 +00: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
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
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
Jonathan Sykes
91dab289c3 Show the update banner only when the running build differs from the server and make Refresh UI land the new shell on flaky links 2026-09-13 17:42:50 +08:00
Jonathan Sykes
49198ff239 Cache video thumbnails for offline use 2026-08-15 07:26:56 +00:00
Jonathan Sykes
ed9f93b0b7 fix: stop playback stutter and save failures via async yt-dlp, per-download OPFS workers, lazy playback blobs, GPU composite trims, and landscape pane scrolling 2026-07-02 23:40:49 +08:00
Claude Worker
8018060d26 feat: update ready keeps showing even after updating
Task #61 completed by ClaudeQueue

ClaudeQueue
2026-07-01 17:40:50 +00:00