diff --git a/lib/features/iptv/screens/player_screen.dart b/lib/features/iptv/screens/player_screen.dart index 1b3b6fa..2b825c3 100644 --- a/lib/features/iptv/screens/player_screen.dart +++ b/lib/features/iptv/screens/player_screen.dart @@ -421,19 +421,20 @@ class _PlayerScreenState extends ConsumerState { ), ), - // Bottom Controls - styled like EPG + // Bottom Controls - styled like Native player AnimatedPositioned( duration: const Duration(milliseconds: 200), - bottom: _showControls ? 16 : -100, - left: 24, - right: 24, + bottom: _showControls ? 24 : -100, + left: 0, + right: 0, child: Center( child: Container( padding: const EdgeInsets.symmetric( horizontal: 24, vertical: 12), decoration: BoxDecoration( - color: Colors.black.withOpacity(0.5), - borderRadius: BorderRadius.circular(12), + color: + const Color(0xFF1A1A2E).withOpacity(0.85), + borderRadius: BorderRadius.circular(24), border: Border.all( color: Colors.white.withOpacity(0.1)), ), @@ -493,9 +494,9 @@ class _PlayerScreenState extends ConsumerState { if (widget.streamType == StreamType.live) AnimatedPositioned( duration: const Duration(milliseconds: 200), - bottom: _showControls ? 100 : -140, + bottom: _showControls ? 24 : -140, left: 24, - right: 24, + right: 0, child: PointerInterceptor( child: EpgOverlay( playlist: widget.playlist, @@ -578,41 +579,13 @@ class _PlayerScreenState extends ConsumerState { ), ), - // Center Play/Pause - Center( - child: _isLoading - ? const CircularProgressIndicator( - color: AppColors.primary) - : TvFocusableCard( - onTap: _togglePlayPause, - borderRadius: 100, - scaleFactor: 1.2, - focusColor: AppColors.primary, - child: Container( - width: 80, - height: 80, - decoration: BoxDecoration( - gradient: AppColors.primaryGradient, - shape: BoxShape.circle, - boxShadow: [ - BoxShadow( - color: - AppColors.primary.withOpacity(0.5), - blurRadius: 30, - spreadRadius: 5, - ), - ], - ), - child: Icon( - _isPlaying - ? Icons.pause_rounded - : Icons.play_arrow_rounded, - color: Colors.white, - size: 40, - ), - ), - ), - ), + // Center Loading Indicator (only show when loading) + if (_isLoading) + const Center( + child: CircularProgressIndicator( + color: AppColors.primary, + ), + ), // Bottom Controls Positioned( diff --git a/lib/features/iptv/widgets/epg_overlay.dart b/lib/features/iptv/widgets/epg_overlay.dart index 2f0b15f..d84aaa8 100644 --- a/lib/features/iptv/widgets/epg_overlay.dart +++ b/lib/features/iptv/widgets/epg_overlay.dart @@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/models/playlist_config.dart'; import '../providers/xtream_provider.dart'; - /// Minimal EPG overlay - shows program title and info class EpgOverlay extends ConsumerWidget { final String streamId; @@ -17,9 +16,11 @@ class EpgOverlay extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final epgAsync = ref.watch(epgByPlaylistProvider( - EpgRequestKey(playlist: playlist, streamId: streamId), - ),); + final epgAsync = ref.watch( + epgByPlaylistProvider( + EpgRequestKey(playlist: playlist, streamId: streamId), + ), + ); return epgAsync.when( data: (epgEntries) { @@ -40,67 +41,69 @@ class EpgOverlay extends ConsumerWidget { // Enhanced info display return Align( - alignment: Alignment.bottomLeft, // Align to bottom left near controls - child: Container( - margin: const EdgeInsets.fromLTRB(24, 0, 24, 24), - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - decoration: BoxDecoration( - color: Colors.black.withOpacity(0.5), // Semi-transparent backing for readability - borderRadius: BorderRadius.circular(12), - border: Border.all(color: Colors.white.withOpacity(0.1)), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: Colors.red, - borderRadius: BorderRadius.circular(4), - ), - child: const Text( - 'LIVE', - style: TextStyle( - color: Colors.white, - fontSize: 12, // Larger - fontWeight: FontWeight.bold, - ), + alignment: Alignment.bottomLeft, // Align to bottom left near controls + child: Container( + margin: const EdgeInsets.fromLTRB(0, 0, 24, 0), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + color: const Color(0xFF1A1A2E) + .withOpacity(0.85), // Match Native player controls + borderRadius: BorderRadius.circular(24), + border: Border.all(color: Colors.white.withOpacity(0.1)), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(4), + ), + child: const Text( + 'LIVE', + style: TextStyle( + color: Colors.white, + fontSize: 12, // Larger + fontWeight: FontWeight.bold, ), ), - const SizedBox(width: 12), - ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 500), // Wider - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ + ), + const SizedBox(width: 12), + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 500), // Wider + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + currentProgram.title, + style: const TextStyle( + color: Colors.white, + fontSize: 18, // Much Larger + fontWeight: FontWeight.bold, + shadows: [Shadow(color: Colors.black, blurRadius: 4)], + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + if (currentProgram.description.isNotEmpty) Text( - currentProgram.title, + currentProgram.description, style: const TextStyle( - color: Colors.white, - fontSize: 18, // Much Larger - fontWeight: FontWeight.bold, - shadows: [Shadow(color: Colors.black, blurRadius: 4)], + color: Colors.white70, + fontSize: 13, // Larger desc ), maxLines: 1, overflow: TextOverflow.ellipsis, ), - if (currentProgram.description.isNotEmpty) - Text( - currentProgram.description, - style: const TextStyle( - color: Colors.white70, - fontSize: 13, // Larger desc - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], - ), + ], ), - ], - ), + ), + ], ), + ), ); }, loading: () => const SizedBox.shrink(),