mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-11 17:30:00 +02:00
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>
10 KiB
10 KiB
XtremFlow Apple TV Modern Theme - Integration Guide
Quick Start
1. Theme is Already Active
The new Apple TV modern theme is automatically applied in main.dart:
MaterialApp(
theme: AppTheme.darkTheme,
// Mobile variant (auto-selected based on platform)
// darkTheme: MobileTheme.darkTheme,
)
2. Using Colors
import 'lib/core/theme/app_colors.dart';
// Primary brand color (Cyan)
Container(color: AppColors.primary)
// Text colors with hierarchy
Text('Title', style: TextStyle(color: AppColors.textPrimary))
Text('Subtitle', style: TextStyle(color: AppColors.textSecondary))
// Semantic colors
FloatingActionButton(
backgroundColor: AppColors.success,
child: Icon(Icons.check),
)
// Category indicators
Chip(
label: Text('Movies'),
backgroundColor: AppColors.movies,
)
3. Using Spacing
import 'lib/core/theme/app_theme.dart';
// Fixed spacing
Padding(
padding: EdgeInsets.all(AppTheme.spacing16),
child: Text('Content'),
)
// Symmetric spacing
SizedBox(
height: AppTheme.spacing24,
)
// Mobile-safe margins
Container(
margin: EdgeInsets.symmetric(
horizontal: AppTheme.spacing32, // 32px on desktop
vertical: AppTheme.spacing16, // 16px vertical
),
child: content,
)
4. Using Typography
import 'package:google_fonts/google_fonts.dart';
// Via theme (preferred)
Text(
'Hero Title',
style: Theme.of(context).textTheme.displayLarge,
)
// Manual override
Text(
'Custom Text',
style: GoogleFonts.outfit(
fontSize: 24,
fontWeight: FontWeight.w700,
color: AppColors.textPrimary,
),
)
// Common styles
headline: Theme.of(context).textTheme.headlineMedium
button: Theme.of(context).textTheme.labelLarge
body: Theme.of(context).textTheme.bodyMedium
5. Core Widgets
GlassContainer
- Glassmorphism effect with blur + gradient
- Use for overlays, headers, premium cards
GlassContainer(
padding: EdgeInsets.all(16),
borderRadius: AppTheme.radiusLg,
child: YourWidget(),
)
GlassCard
- Interactive glass card with animations
- Auto scales on hover/tap
GlassCard(
interactive: true,
onTap: () => handleTap(),
child: ContentHere(),
)
ChannelCard
- Live TV channel card
- Features: Live badge, favorite button, EPG info
- Responsive sizing
ChannelCard(
streamId: channel.id,
name: channel.name,
iconUrl: channel.logo,
currentProgram: 'Breaking Bad',
isLive: true,
playlist: playlistConfig,
onTap: () => playChannel(channel),
)
TvModernCard
- Content card for movies/shows
- Features: Rating, year, badge, progress bar
- Playing state indicator
TvModernCard(
id: item.id,
title: 'Stranger Things',
imageUrl: 'https://...',
rating: '8.7/10',
year: '2024',
badge: 'NEW',
badgeColor: AppColors.primary,
progress: 0.35, // 35% watched
onPlayTap: () => playContent(item),
)
HeroCarousel
- Full-screen featured content slider
- Auto-play with manual controls
HeroCarousel(
items: [
HeroCarouselItem(
id: '1',
title: 'Breaking Bad',
subtitle: 'Complete Series',
imageUrl: 'https://...',
badge: 'BINGE-WORTHY',
onPlay: () => play(),
onTap: () => showDetails(),
),
],
autoPlay: true,
)
TvChannelGrid
- Responsive grid for channels
- Auto-adjusts columns based on screen size
TvChannelGrid(
children: channels.map((ch) => ChannelCard(
streamId: ch.id,
name: ch.name,
// ...
)).toList(),
)
// Responsive behavior:
// >1920px: 6 columns
// >1600px: 5 columns
// >1280px: 4 columns
// >960px: 3 columns
// Else: 2 columns
TvHorizontalList
- Horizontal scrollable content list with title
- Smooth scroll animation
TvHorizontalList(
title: 'Continue Watching',
children: items.map((item) => TvModernCard(...)).toList(),
itemWidth: 200,
spacing: 16,
)
TvTopNavBar
- Premium header navigation
- Search, notifications, profile
TvTopNavBar(
title: 'XtremFlow',
onSearch: () => showSearch(),
onNotifications: () => showNotifications(),
onProfile: () => showProfile(),
notificationCount: 3,
)
TvSideNav
- Vertical navigation menu
- Category/section navigation
TvSideNav(
items: [
TvNavItem(label: 'Home', icon: Icons.home),
TvNavItem(label: 'Live', icon: Icons.tv),
TvNavItem(label: 'Movies', icon: Icons.movie),
],
selectedIndex: 0,
onItemSelected: (idx) => _navigate(idx),
)
Layout Patterns
Hero Section
SizedBox(
height: 360,
child: Stack(
children: [
HeroCarousel(items: featuredItems),
// Additional overlay elements
],
),
)
Content Grid with Header
Column(
children: [
// Navigation
TvTopNavBar(title: 'Browse'),
// Content
Expanded(
child: TvChannelGrid(
children: channelCards,
),
),
],
)
Dual Navigation Layout
Row(
children: [
// Side navigation
SizedBox(
width: 240,
child: TvSideNav(...),
),
// Main content
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
HeroCarousel(...),
TvHorizontalList(title: 'Trending', ...),
TvHorizontalList(title: 'Recently Added', ...),
],
),
),
),
],
)
Animation Patterns
Button Hover
AnimatedScale(
scale: _isHovered ? 1.05 : 1.0,
duration: AppTheme.durationMd,
curve: AppTheme.curveDefault,
child: GestureDetector(
onTap: onTap,
child: YourButton(),
),
)
Fade Transition
FadeTransition(
opacity: animation,
child: ContentWidget(),
)
Page Transition
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: AppTheme.durationLg,
pageBuilder: (_, __, ___) => NextPage(),
transitionsBuilder: (_, anim, __, child) {
return ScaleTransition(scale: anim, child: child);
},
),
)
Mobile Specific
Bottom Navigation Demo
Scaffold(
body: pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (idx) => setState(() => _currentIndex = idx),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
// More items...
],
),
)
Responsive Grid (Mobile)
// On mobile, TvChannelGrid auto-adjusts to 2 columns
SingleChildScrollView(
child: TvChannelGrid(
padding: EdgeInsets.all(AppTheme.spacing16), // Mobile padding
children: channels,
),
)
Common Mistakes to Avoid
❌ Don't
// Using old colors
Container(color: Color(0xFF6C63FF)) // Old purple
// Inconsistent spacing
Padding(padding: EdgeInsets.only(left: 23)) // Non-standard
// Wrong font
Text('Title', style: GoogleFonts.inter(...)) // Should be Outfit
// Manual animation
AnimationController with hardcoded Duration(milliseconds: 250)
// Missing glass effect
Card(color: AppColors.surface) // Should use GlassContainer
✅ Do
// Use theme colors
Container(color: AppColors.primary)
// Standard spacing
Padding(padding: EdgeInsets.all(AppTheme.spacing16))
// Correct typography
Text('Title', style: Theme.of(context).textTheme.headlineMedium)
// Theme animations
duration: AppTheme.durationMd
curve: AppTheme.curveDefault
// Premium widgets
GlassContainer(
child: content,
)
File Structure
lib/
├── core/
│ ├── theme/
│ │ ├── app_colors.dart ← Colors + gradients
│ │ └── app_theme.dart ← Typography + theme data
│ └── widgets/
│ ├── glass_container.dart ← Glassmorphism
│ ├── hero_carousel.dart ← Featured content slider
│ ├── tv_channel_grid.dart ← Responsive grid
│ ├── tv_modern_card.dart ← Content cards
│ ├── tv_nav_widgets.dart ← Navigation widgets
│ ├── tv_focusable_card.dart ← Focus state (legacy)
│ └── [other core widgets]
├── features/
│ └── iptv/
│ └── widgets/
│ ├── channel_card.dart ← TV channel card
│ └── [feature widgets]
└── mobile/
└── theme/
└── mobile_theme.dart ← Mobile-adapted theme
main.dart ← Theme applied here
DESIGN_SYSTEM.md ← Full documentation
Troubleshooting
Colors look washed out
- Ensure
scaffoldBackgroundColor: AppColors.backgroundis set - Check OLED display settings (true black optimization)
- Verify contrast ratio is ≥ 4.5:1
Animations feel jerky
- Use
AppTheme.durationMdandcurveDefault - Avoid nested AnimationControllers
- Check frame rate (should be 60fps)
Cards don't have glass effect
- Use
GlassContainerorGlassCard, not plainContainer - Ensure
BackdropFilterparent is not constrained - Set
blur: 15.0for standard effect
Text is hard to read
- Use
textSecondaryfor medium emphasis (60% grey) - Never use
textTertiaryon dark backgrounds (insufficient contrast) - Increase letter spacing for headings
Layout breaks on mobile
- Use
TvChannelGridfor automatic responsive behavior - Test with
MediaQuery.of(context).size.width - Set
minimumSizefor buttons on mobile
Performance Optimization
Image Loading
// Good
CachedNetworkImage(
imageUrl: url,
placeholder: (context, url) => SkeletonLoader(),
cacheManager: CacheManager.instance,
)
// Bad
Image.network(url) // No caching
List Rendering
// Good
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) => ItemCard(items[index]),
)
// Bad
ListView(
children: items.map((item) => ItemCard(item)).toList(),
) // All items rendered upfront
Avoiding Jank
// Use repaint boundaries
RepaintBoundary(
child: AnimatedCard(...),
)
// Disable shadows during scroll
if (!isScrolling) {
boxShadow: [BoxShadow(...)]
}
// Use const constructors
const SizedBox(height: 16)
Version History
| Version | Date | Changes |
|---|---|---|
| 2.0 | 2026-03-26 | Apple TV Modern redesign, new color palette, premium widgets |
| 1.0 | 2024-XX-XX | Initial theme system |
Support & Questions
For detailed documentation, see: DESIGN_SYSTEM.md For components, check: lib/core/widgets/ For examples, see: lib/features/iptv/
Status: ✅ Production Ready