The gradient Container in the playlist selection and admin screens sized
itself to its content rather than the viewport: under the loose body
constraints, SingleChildScrollView and Wrap both shrink-wrap, so the
gradient was painted only across a 436 px band (48 padding + 340 card +
48 padding) with the rest of the screen falling through to bare black.
BoxConstraints.expand() forces full coverage.
Also:
- both screens now use AppColors.backgroundGradient. The previous ramp
ran surfaceContainerLowest -> background -> baseLevel0, i.e. dark to
lighter to dark, which put a pale band across the middle
- the playlist card was a 3% cream translucent plate, so it took on
whatever sat behind it instead of resting on it; it is now an opaque
surface (surfaceContainerLow, surfaceContainerHigh on hover) with the
lift() shadow at rest and the ember focus halo on hover
- Scaffold backgroundColor pinned to baseLevel0 so route transitions
never flash pure black
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The security hardening in 60d3f42 moved /api/epg, /api/recordings and
/api/season-passes behind authMiddleware, but the Flutter client still
called them through bare package:http. Those requests carry no
Authorization header, and on web BrowserClient sets withCredentials to
false so the session cookie is not sent either — every call came back
401. Symptoms: empty TV guide, empty recordings list, empty season
passes.
Adds AuthedHttp, a thin wrapper that injects the same token ApiClient
and XtreamService already use (localStorage['auth_token']), and routes
the 13 affected calls through it.
subtitle_service is left on plain http: it fetches third-party subtitle
URLs, not our API, and must not leak the session token.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replaces the Projector Noir palette with "Warm Cinema" and rebuilds the
web players around a shared, event-driven engine.
Design
- app_colors: warm charcoal (#0B0908), cream (#F3E9DF), ember (#D9541F);
adds posterScrim/heroScrim gradients, lift()/emberFocus() shadows,
const cream-alpha tokens replacing Colors.whiteNN, and primaryFill,
a deeper ember reserved for text-bearing fills so white labels clear
the 4.5:1 AA threshold that #D9541F alone does not
- app_theme / mobile_theme: Fraunces (display serif) + Karla (body),
tighter radii, 20+ component themes
- glass_container: opaque layered surfaces replace the blurred glass
- themed_loading_screen restyled; players and boot splash follow
Performance
- drop every BackdropFilter: backdrop blur forced a full framebuffer
read per frame per card, the main source of scroll jank
- bundle Fraunces/Karla as assets so google_fonts stops fetching from
fonts.gstatic.com at startup
- bound image decode size on 12 sites: a 40-poster grid drops from
~240 MB to a few tens of MB of GPU memory
Players (new shared engine: web/xf-player-core.js)
- start on media events instead of polling the buffer every 100-200 ms
- hls.js/mpegts.js loaded on demand, so ~213 KB of mpegts is never
fetched for HLS streams
- liveSyncDurationCount 10 -> 2, startFragPrefetch on, testBandwidth
off, MPEG-TS initial stash 512 KB -> 64 KB
- adaptive escalation fast -> balanced -> safe after repeated stalls in
a 60 s window, applied live for HLS so there is no visible cut
Preserved from the recent streaming work on main: server-side quality
selection, stable player viewId, the turbo direct MPEG-TS path, vendored
library cache headers and the CI/Docker changes. Only the theme layer and
the player front-end were replaced; GlassCard stays in ui_components.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
player_lite (Live TV desktop) ignored set_volume messages from Flutter,
so mute/unmute button had no effect. Added handler matching player.html.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Removed TabBar/TabBarView complexity
- Keep only recordings list display
- Simplified to show only recordings without guide TV and season passes tabs
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Implement parallel fetching for categories and streams in Live, VOD, and Series
- Add persistent local storage caching for instant UI population
- Optimize JSON parsing logic for large datasets
- Implement failover to local cache when network is unavailable
- Add playback lock to XtreamService to delay EPG during stream init
- Increase MPEG-TS stash buffer to 512KB for better stability
- Enable liveBufferLatencyChasing to prevent stream drift
- Tune HLS parameters for balanced speed and reliability