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>
Full visual refonte replacing the generic neon-blue glass look:
- palette: warm film-black surface ladder, tungsten amber primary,
warm taupe secondary, verdigris teal tertiary; semantic and
category colors retuned to match (coral live, gold movies)
- typography: Syne (display/headlines) + Instrument Sans (body/UI)
replace Space Grotesk/Inter/Outfit across all screens
- glassmorphism tokens warmed (amber inner glow, warm-white borders)
- web player theme.css + index.html loader mirror the new tokens
- hardcoded Colors.blue* in streaming settings and recordings tabs
now use AppColors tokens
- DESIGN_SYSTEM.md updated to v3.0 Projector Noir
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The frontend CI job ran `flutter analyze` from the repo root, which also
analyzed the bin/ server package without its dependencies resolved
(shelf_router, sqlite3, bcrypt, test), producing hundreds of
uri_does_not_exist errors. bin/ is a standalone package covered by the
backend job, so it is now excluded from root analysis.
Also:
- Remove all unused fields/variables flagged as analyzer warnings
(api_client, cache_service, player_screen, subtitle_service,
live_tv_tab, mobile screens)
- Run `flutter analyze --no-fatal-infos` in CI: pre-existing deprecation
infos (withOpacity, dart:html) stay non-fatal while errors and warnings
still fail the build
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Security:
- Replace unsalted SHA-256 password hashing with bcrypt (lazy rehash on login)
- Add authenticated /api/xtream-api gateway: Xtream credentials are injected
server-side and never sent to the frontend; /api/playlists no longer
returns passwords
- Redact credentials from all logs (login body, proxy/FFmpeg/scheduler URLs)
- Add auth to recordings, EPG, season-passes and streaming routes
(HttpOnly session cookie for hls.js; loopback bypass for local FFmpeg)
- Lock player postMessage to same-origin in both directions
- Vendor and pin hls.js 1.6.7 / mpegts.js 1.7.3 (drop CDN @latest)
- Fix rate limiter (client IP was never resolved), add login rate limit,
restrict CORS, add CSP Report-Only, block private-IP SSRF targets,
fix path traversal in recording log retrieval, chmod 777 -> 770
- Remove dead HiveService (seeded admin/admin into IndexedDB with SHA-256)
- Fix authMiddleware not populating 'user' context (getPlaylist ignored the
logged-in user; admin purge always returned 403)
Streaming:
- New FfmpegSessionManager: process registry, idle reaper (4 min live /
15 min VOD), orphan cleanup at startup, clean SIGTERM shutdown,
fast-fail with stderr instead of 30 s timeout
- Quality selection (source/high/medium/low) for live and VOD; source mode
streams with -c:v copy (zero transcoding); selector wired into the player
- Concurrent recordings (MAX_CONCURRENT_RECORDINGS, default 2); conflicts
retry on the next tick instead of silently failing
- Lower live latency (HLS window 20 -> 10 segments, liveSync 10 -> 3)
- Fix recording log lookup (.mp4 vs .mkv mismatch)
Design:
- Replace hardcoded colors with AppColors tokens (12 files)
- web/theme.css syncs HTML players with the Flutter palette
- DPAD/keyboard navigation (arrow-key focus, player shortcuts)
- Tooltips on player icon buttons, Semantics on content cards
- Remove 7 dead widgets broken since the Stitch merge
Quality:
- bin/test/: 21 unit tests (bcrypt, redaction, traversal, SSRF, recording
conflicts) plus a quality-selector widget test
- GitHub Actions CI (analyze + test + build web)
- Archive stale status docs into docs/archive/
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Replace deprecated GlassContainer(opacity:/hasBorder:) calls in
dashboard_screen.dart and player_screen.dart with .glass() constructor.
- Fix epg_grid_screen.dart missing provider import and Playlist type mismatch.
- Delete broken/unreferenced files: network_service.dart, epg_grid_screen.dart.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Resolved conflicts by keeping remote functional features (RecordingScheduler,
FFmpeg HLS transcoding, mobile player, channel cards) and restoring local
Stitch theme foundation (app_colors, app_theme, glass_container, mobile_theme).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the legacy Apple TV-style purple/cyan theme with the full
Google Stitch Cyber-Cinematic Glass design system across the
entire app (desktop + mobile).
- New Material 3 dark ColorScheme: background #121317, primary
#adc6ff, primaryContainer #4b8eff, surface containers, etc.
- Typography: Space Grotesk (headlines) + Inter (body/labels)
- 3-level glassmorphism via GlassContainer: base, glass, floating
- Primary gradient: #007AFF → #00C6FF with blue glow effects
- Removed old compatibility aliases (focusColor, border, textPrimary,
textSecondary); all code now uses semantic Stitch tokens
- Systematically replaced all Colors.white/black/red/grey and
GoogleFonts.roboto/outfit with Stitch equivalents
- All 36 lib/ files updated, zero compilation errors
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- tv_channel_grid.dart: guard screenWidth <= 0 / NaN / Infinite on first
Flutter Web layout pass (previously caused NaN ~/ 225.03 crash cascade).
Also use .clamp(1.0, infinity) on item width for belt-and-suspenders safety.
Fix invalid 'padding.vertical as double?' cast in TvHorizontalList by using
padding.resolve(TextDirection.ltr).top instead.
- playlist_api_service.dart: remove silent catch-and-return-empty in
getPlaylists(). Exceptions now propagate to the Riverpod FutureProvider
so the UI shows the real error state (with Retry button) instead of
a misleading 'No playlists available' when the API call actually failed
(e.g., 401 Unauthorized or network error).
Fixed playlist loading failure by ensuring the auth token is automatically
restored from localStorage when ApiClient initializes. Previously, the token
was stored but never restored, causing 401 Unauthorized errors on API calls.
Added _restoreTokenFromStorage() method to ApiClient constructor to load
and apply stored token immediately on app startup. This ensures all API
calls (including playlist fetching) have proper authentication.
Fixes: "I still don't have a playlist" issue where playlists were not loading
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Fixed NaN error in TvChannelGrid width calculation by properly resolving
EdgeInsetsGeometry to concrete values before arithmetic operations.
EdgeInsetsGeometry.horizontal can return NaN/infinity, causing invalid
width calculations.
Changed from: padding.horizontal
To: padding.resolve(TextDirection.ltr).left + padding.resolve(TextDirection.ltr).right
This ensures we get concrete padding values before division operations.
Fixes: Unsupported operation: Result of truncating division is NaN: NaN ~/ 225.0357142857143
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Fixed NaN errors in FFmpeg bitrate argument generation by ensuring integer
conversion happens before integer division. The double multiplication (1.5, 2.0)
was happening before the ~/ operator, causing NaN values. Now properly converts
to int first, then divides.
- maxRateArg: ((bitrateBps * 1.5).toInt() ~/ 1000)
- bufferSizeArg: ((bitrateBps * 2).toInt() ~/ 1000)
Fixes: Unsupported operation: Result of truncating division is NaN
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Introduced a comprehensive visual reference for the Apple TV design system, including color palette, component specifications, typography, shadow elevation system, and animation timing guide.
- Detailed button states, card components, text styles, and navigation focus flow for improved user experience.
- Included accessibility considerations and a testing checklist to ensure compliance with design standards.
chore: Complete redesign of XtremFlow Apple TV theme
- Updated color palette to align with Apple TV aesthetics, enhancing sophistication and premium feel.
- Optimized typography for better readability at 10ft viewing distance.
- Improved focus states for remote navigation clarity.
- Implemented a new 5-level shadow system for cinematic depth.
- Refined glass effects for a premium appearance.
- Ensured all components are accessible and comfortable for remote use.
refactor(ui_components): adjust animation durations for smoother transitions
fix(dashboard): rename border property to hasBorder for clarity
fix(player): rename border property to hasBorder for consistency
- Updated ChannelCard widget to include live indicator, favorite button, and EPG information with smooth animations and skeleton loading for images.
- Introduced MobileTheme for touch-optimized layouts, adapting Apple TV design principles for mobile screens.
- Added TvChannelGrid for responsive channel layouts with flexible column counts and smooth animations.
- Created TvModernCard for displaying content with interactive hover states, progress indicators, and context menu support.
- Implemented TvTopNavBar and TvSideNav for improved navigation with glassmorphism effects and user-friendly interactions.
- Developed TvFloatingMenu for context-aware actions with smooth reveal animations.
- Implemented DownloadService for managing download tasks, including start, pause, resume, and cancel functionalities.
- Created SubtitleService for handling subtitle tracks, parsing SRT and WebVTT formats, and downloading subtitles.
- Added ContinueWatchingWidget to display user's watch history with progress indicators.
- Developed QualitySelectorWidget for selecting video quality during playback, including auto quality adjustment.
- Introduced TrendingWidget and RecentlyAddedWidget to showcase trending and recently added content.