mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-18 20:59:59 +02:00
feat: introduce streaming handlers for live TV proxy and VOD HLS transcoding using FFmpeg.
This commit is contained in:
1 parent
d22350fb89
commit
a1a8810ddc
10 files changed
+968
-612
No files matched your search
@@ -12,45 +12,58 @@ class AppColors {
|
||||
|
||||
// ============ BACKGROUNDS ============
|
||||
/// Pure black for that infinite depth look (OLED friendly)
|
||||
static const Color background = Color(0xFF000000);
|
||||
static const Color background = Color(0xFF0F1014); // Deepest Blue-Black
|
||||
|
||||
/// Very deep grey for surfaces that need to be distinct but subtle (Apple Dark Grey)
|
||||
static const Color surface = Color(0xFF1C1C1E);
|
||||
static const Color surface = Color(0xFF181920);
|
||||
|
||||
/// Slightly lighter grey for secondary surfaces or hover states
|
||||
static const Color surfaceVariant = Color(0xFF3A3A3C);
|
||||
static const Color surfaceVariant = Color(0xFF1E2028);
|
||||
|
||||
static const Color surfaceGlass =
|
||||
Color(0x1AFFFFFF); // 10% White for glass effect
|
||||
|
||||
/// Focused element background (often white in tvOS for text, or bright accent)
|
||||
static const Color focusColor = Color(0xFFFFFFFF);
|
||||
static const Color border = Color(0xFF1F1F1F);
|
||||
static const Color focusBorder = Color(0xFFFFFFFF);
|
||||
|
||||
// ============ ACCENTS ============
|
||||
/// Minimal white accent. In Apple TV, color is used sparingly.
|
||||
/// We keep a subtle blue only for specific indicators if needed.
|
||||
static const Color primary = Color(0xFFFFFFFF);
|
||||
static const Color accent = Color(0xFFE5E5E5);
|
||||
static const Color primary = Color(0xFF6C63FF);
|
||||
static const Color secondary = Color(0xFF00B4D8);
|
||||
static const Color accent = Color(0xFF00B4D8);
|
||||
|
||||
/// Primary Gradient (Subtle silver/white glow)
|
||||
/// Primary Gradient (Electric Violet to Cyan)
|
||||
static const LinearGradient primaryGradient = LinearGradient(
|
||||
colors: [Color(0xFFFFFFFF), Color(0xFFCCCCCC)],
|
||||
colors: [Color(0xFF6C63FF), Color(0xFF00B4D8)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
|
||||
// ============ TEXT ============
|
||||
static const LinearGradient backgroundGradient = LinearGradient(
|
||||
colors: [Color(0xFF0F1014), Color(0xFF131418)],
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
);
|
||||
|
||||
// Status Colors
|
||||
static const Color success = Color(0xFF00E676);
|
||||
static const Color warning = Color(0xFFFFAB00);
|
||||
static const Color error = Color(0xFFFF5252);
|
||||
static const Color info = Color(0xFF2979FF);
|
||||
|
||||
// Content Colors
|
||||
static const Color textPrimary = Color(0xFFFFFFFF);
|
||||
static const Color textSecondary = Color(0xFF9E9E9E); // Medium Grey
|
||||
static const Color textTertiary = Color(0xFF616161); // Darker Grey
|
||||
static const Color textSecondary = Color(0xFFAAAAAA);
|
||||
static const Color textTertiary = Color(0xFF666666);
|
||||
|
||||
// ============ FUNCTIONAL COLORS ============
|
||||
static const Color success = Color(0xFF4DB6AC); // Teal-ish
|
||||
static const Color warning = Color(0xFFFFB74D);
|
||||
static const Color error = Color(0xFFEF5350);
|
||||
static const Color live = Color(0xFFFF3B30); // Apple Red
|
||||
static const Color ratingGold = Color(0xFFFFD700);
|
||||
static const Color premiumGold = Color(0xFFFFA000);
|
||||
|
||||
// ============ BORDERS ============
|
||||
// Borders are usually hidden until focused
|
||||
static const Color border = Color(0xFF1F1F1F);
|
||||
static const Color focusBorder = Color(0xFFFFFFFF);
|
||||
// Category Colors
|
||||
static const Color live = Color(0xFFFF5252); // Red
|
||||
static const Color movies = Color(0xFF448AFF); // Blue
|
||||
static const Color series = Color(0xFF69F0AE); // Green
|
||||
|
||||
// ============ GLASSMORPHISM ============
|
||||
// Apple TV uses this heavily for headers/overlays
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
import 'app_colors.dart';
|
||||
|
||||
/// XtremFlow Apple TV Theme
|
||||
///
|
||||
///
|
||||
/// Focus-driven, immersive, minimal.
|
||||
class AppTheme {
|
||||
AppTheme._();
|
||||
@@ -27,27 +27,57 @@ class AppTheme {
|
||||
// ============ ANIMATION ============
|
||||
static const Duration durationFast = Duration(milliseconds: 200);
|
||||
static const Duration durationNormal = Duration(milliseconds: 300);
|
||||
static const Curve curveDefault = Curves.fastOutSlowIn; // Apple-like snappy curve
|
||||
static const Curve curveDefault =
|
||||
Curves.fastOutSlowIn; // Apple-like snappy curve
|
||||
|
||||
// ============ DARK THEME (TV Main) ============
|
||||
static ThemeData get darkTheme {
|
||||
final baseTheme = ThemeData.dark(useMaterial3: true);
|
||||
|
||||
|
||||
return baseTheme.copyWith(
|
||||
colorScheme: AppColors.darkColorScheme,
|
||||
scaffoldBackgroundColor: AppColors.background,
|
||||
|
||||
// Typography: San Francisco style (using Inter as proxy)
|
||||
|
||||
// Typography: "Cinematic Modern" (Outfit for Headings, Inter for UI)
|
||||
textTheme: TextTheme(
|
||||
displayLarge: GoogleFonts.inter(fontSize: 56, fontWeight: FontWeight.w700, letterSpacing: -1.0, color: AppColors.textPrimary),
|
||||
displayMedium: GoogleFonts.inter(fontSize: 48, fontWeight: FontWeight.w700, letterSpacing: -0.5, color: AppColors.textPrimary),
|
||||
displaySmall: GoogleFonts.inter(fontSize: 32, fontWeight: FontWeight.w600, color: AppColors.textPrimary),
|
||||
headlineMedium: GoogleFonts.inter(fontSize: 24, fontWeight: FontWeight.w600, color: AppColors.textPrimary),
|
||||
titleLarge: GoogleFonts.inter(fontSize: 20, fontWeight: FontWeight.w600, color: AppColors.textPrimary),
|
||||
titleMedium: GoogleFonts.inter(fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.textPrimary),
|
||||
bodyLarge: GoogleFonts.inter(fontSize: 16, fontWeight: FontWeight.w400, color: AppColors.textSecondary),
|
||||
bodyMedium: GoogleFonts.inter(fontSize: 14, fontWeight: FontWeight.w400, color: AppColors.textSecondary),
|
||||
labelLarge: GoogleFonts.inter(fontSize: 14, fontWeight: FontWeight.w600, color: AppColors.textPrimary),
|
||||
displayLarge: GoogleFonts.outfit(
|
||||
fontSize: 56,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: -1.0,
|
||||
color: AppColors.textPrimary),
|
||||
displayMedium: GoogleFonts.outfit(
|
||||
fontSize: 48,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: -0.5,
|
||||
color: AppColors.textPrimary),
|
||||
displaySmall: GoogleFonts.outfit(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary),
|
||||
headlineMedium: GoogleFonts.outfit(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary),
|
||||
titleLarge: GoogleFonts.outfit(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary),
|
||||
titleMedium: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary),
|
||||
bodyLarge: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.textSecondary),
|
||||
bodyMedium: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.textSecondary),
|
||||
labelLarge: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary),
|
||||
),
|
||||
|
||||
// AppBar: Transparent / Glass
|
||||
@@ -57,18 +87,19 @@ class AppTheme {
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
scrolledUnderElevation: 0,
|
||||
titleTextStyle: GoogleFonts.inter(
|
||||
fontSize: 17,
|
||||
titleTextStyle: GoogleFonts.outfit(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Inputs: Dark, minimal, no borders unless focused
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: AppColors.surface,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: spacing24, vertical: spacing16),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: spacing24, vertical: spacing16),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(radiusMd),
|
||||
borderSide: BorderSide.none,
|
||||
@@ -83,7 +114,7 @@ class AppTheme {
|
||||
),
|
||||
hintStyle: GoogleFonts.inter(color: AppColors.textTertiary),
|
||||
),
|
||||
|
||||
|
||||
// Buttons: White pill or minimal text
|
||||
filledButtonTheme: FilledButtonThemeData(
|
||||
style: FilledButton.styleFrom(
|
||||
@@ -91,17 +122,21 @@ class AppTheme {
|
||||
foregroundColor: Colors.black, // Black text
|
||||
elevation: 0,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(radiusMd)),
|
||||
textStyle: GoogleFonts.inter(fontWeight: FontWeight.w600, fontSize: 16),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(radiusMd)),
|
||||
textStyle:
|
||||
GoogleFonts.inter(fontWeight: FontWeight.w600, fontSize: 16),
|
||||
).copyWith(
|
||||
overlayColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.hovered)) return Colors.black.withOpacity(0.1);
|
||||
if (states.contains(WidgetState.pressed)) return Colors.black.withOpacity(0.2);
|
||||
if (states.contains(WidgetState.hovered))
|
||||
return Colors.black.withOpacity(0.1);
|
||||
if (states.contains(WidgetState.pressed))
|
||||
return Colors.black.withOpacity(0.2);
|
||||
return null;
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Cards: Transparent by default (content defines look)
|
||||
// cardTheme: const CardTheme(
|
||||
// color: AppColors.surface,
|
||||
@@ -124,8 +159,9 @@ class AppTheme {
|
||||
static const double radiusFull = 999.0;
|
||||
|
||||
// Light theme stub
|
||||
static ThemeData get lightTheme => ThemeData.light(useMaterial3: true).copyWith(
|
||||
colorScheme: AppColors.lightColorScheme,
|
||||
textTheme: GoogleFonts.interTextTheme(ThemeData.light().textTheme),
|
||||
);
|
||||
static ThemeData get lightTheme =>
|
||||
ThemeData.light(useMaterial3: true).copyWith(
|
||||
colorScheme: AppColors.lightColorScheme,
|
||||
textTheme: GoogleFonts.interTextTheme(ThemeData.light().textTheme),
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user