mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-11 17:30:00 +02:00
- 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.
130 lines
3.5 KiB
Dart
130 lines
3.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../theme/app_colors.dart';
|
|
import '../theme/app_theme.dart';
|
|
|
|
/// Apple TV Modern Channel Grid
|
|
///
|
|
/// Responsive grid layout for channels with:
|
|
/// - Flexible column count based on screen size
|
|
/// - Smooth animations
|
|
/// - Focus-aware spacing
|
|
class TvChannelGrid extends StatelessWidget {
|
|
final List<Widget> children;
|
|
final EdgeInsetsGeometry padding;
|
|
final double horizontalSpacing;
|
|
final double verticalSpacing;
|
|
final ScrollController? scrollController;
|
|
final ScrollPhysics physics;
|
|
|
|
const TvChannelGrid({
|
|
super.key,
|
|
required this.children,
|
|
this.padding = const EdgeInsets.fromLTRB(32, 24, 32, 32),
|
|
this.horizontalSpacing = 20,
|
|
this.verticalSpacing = 20,
|
|
this.scrollController,
|
|
this.physics = const AlwaysScrollableScrollPhysics(),
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final screenWidth = MediaQuery.of(context).size.width;
|
|
|
|
// Responsive column count
|
|
int columnCount;
|
|
if (screenWidth > 1920) {
|
|
columnCount = 6;
|
|
} else if (screenWidth > 1600) {
|
|
columnCount = 5;
|
|
} else if (screenWidth > 1280) {
|
|
columnCount = 4;
|
|
} else if (screenWidth > 960) {
|
|
columnCount = 3;
|
|
} else {
|
|
columnCount = 2;
|
|
}
|
|
|
|
return SingleChildScrollView(
|
|
controller: scrollController,
|
|
physics: physics,
|
|
padding: padding,
|
|
child: Wrap(
|
|
spacing: horizontalSpacing,
|
|
runSpacing: verticalSpacing,
|
|
children: [
|
|
for (int i = 0; i < children.length; i++)
|
|
SizedBox(
|
|
width: (screenWidth -
|
|
(padding.horizontal) -
|
|
(horizontalSpacing * (columnCount - 1))) / columnCount,
|
|
child: children[i],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Apple TV Modern Horizontal Scrollable List
|
|
class TvHorizontalList extends StatelessWidget {
|
|
final List<Widget> children;
|
|
final String? title;
|
|
final EdgeInsetsGeometry padding;
|
|
final double itemWidth;
|
|
final double spacing;
|
|
final ScrollController? scrollController;
|
|
|
|
const TvHorizontalList({
|
|
super.key,
|
|
required this.children,
|
|
this.title,
|
|
this.padding = const EdgeInsets.symmetric(vertical: 16),
|
|
this.itemWidth = 200,
|
|
this.spacing = 16,
|
|
this.scrollController,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
// Title
|
|
if (title != null)
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppTheme.spacing32,
|
|
vertical: AppTheme.spacing16,
|
|
),
|
|
child: Text(
|
|
title!,
|
|
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
),
|
|
|
|
// Horizontal list
|
|
SizedBox(
|
|
height: 280,
|
|
child: ListView.separated(
|
|
controller: scrollController,
|
|
scrollDirection: Axis.horizontal,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: 32,
|
|
vertical: padding.vertical as double? ?? 0,
|
|
),
|
|
itemCount: children.length,
|
|
separatorBuilder: (_, __) => SizedBox(width: spacing),
|
|
itemBuilder: (context, index) => SizedBox(
|
|
width: itemWidth,
|
|
child: children[index],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|