import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/services/media/media.dart'; import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart'; import 'package:didvan/views/home/studio/studio_details/widgets/studio_details_widget.dart'; import 'package:didvan/views/home/studio/studio_state.dart'; import 'package:didvan/views/home/widgets/audio/audio_player_widget.dart'; import 'package:didvan/views/home/widgets/audio/audio_slider.dart'; import 'package:didvan/views/widgets/didvan/icon_button.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class DidvanBNB extends StatelessWidget { final int currentTabIndex; final void Function(int index) onTabChanged; const DidvanBNB( {Key? key, required this.currentTabIndex, required this.onTabChanged}) : super(key: key); bool get _enablePlayerController => MediaService.currentPodcast != null || MediaService.audioPlayer.playing; @override Widget build(BuildContext context) { return StreamBuilder( stream: MediaService.audioPlayer.playingStream, builder: (context, snapshot) { return Stack( children: [ GestureDetector( onTap: () => _showPlayerBottomSheet(context), child: AnimatedContainer( padding: const EdgeInsets.only(top: 12), duration: DesignConfig.lowAnimationDuration, height: _enablePlayerController ? 120 : 72, decoration: BoxDecoration( color: DesignConfig.isDark ? Theme.of(context).colorScheme.focused : Theme.of(context).colorScheme.navigation, borderRadius: const BorderRadius.vertical( top: Radius.circular(16), ), ), child: !_enablePlayerController ? const SizedBox() : SizedBox( height: 48, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only( right: 12, left: 16, ), child: DidvanIconButton( icon: DidvanIcons.close_regular, color: DesignConfig.isDark ? null : Theme.of(context).colorScheme.secondCTA, gestureSize: 28, onPressed: MediaService.resetAudioPlayer, ), ), SkeletonImage( imageUrl: MediaService.currentPodcast!.image, width: 32, height: 32, ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DidvanText( MediaService.currentPodcast!.title, color: DesignConfig.isDark ? null : Theme.of(context) .colorScheme .secondCTA, ), AudioSlider( disableThumb: true, tag: MediaService.audioPlayerTag!, ), ], ), ), Padding( padding: const EdgeInsets.only( left: 12, right: 16, ), child: DidvanIconButton( gestureSize: 28, color: DesignConfig.isDark ? null : Theme.of(context).colorScheme.secondCTA, icon: snapshot.data! ? DidvanIcons.pause_solid : DidvanIcons.play_solid, onPressed: () { MediaService.handleAudioPlayback( audioSource: MediaService.audioPlayerTag, ); }, ), ), ], ), ), ), ), Positioned( bottom: 0, left: 0, right: 0, child: Container( height: 72, decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.vertical(top: Radius.circular(16)), boxShadow: DesignConfig.defaultShadow, ), padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ _NavBarItem( isSelected: currentTabIndex == 0, title: 'اخبار', selectedIcon: DidvanIcons.news_solid, unselectedIcon: DidvanIcons.news_light, onTap: () => onTabChanged(0), ), _NavBarItem( isSelected: currentTabIndex == 1, title: 'آمار', selectedIcon: DidvanIcons.chart_solid, unselectedIcon: DidvanIcons.chart_light, onTap: () => onTabChanged(1), ), _NavBarItem( isSelected: currentTabIndex == 2, title: 'رادار', selectedIcon: DidvanIcons.radar_solid, unselectedIcon: DidvanIcons.radar_light, onTap: () => onTabChanged(2), ), _NavBarItem( isSelected: currentTabIndex == 3, title: 'استودیو', selectedIcon: DidvanIcons.play_circle_solid, unselectedIcon: DidvanIcons.play_circle_light, onTap: () => onTabChanged(3), ), _NavBarItem( isSelected: currentTabIndex == 4, title: 'تنظیمات', selectedIcon: DidvanIcons.setting_solid, unselectedIcon: DidvanIcons.setting_light, onTap: () => onTabChanged(4), ), ], ), ), ), ], ); }); } void _showPlayerBottomSheet(BuildContext context) { final sheetKey = GlobalKey(); bool isExpanded = false; final detailsState = context.read(); final state = context.read(); showModalBottomSheet( backgroundColor: Colors.transparent, context: context, isScrollControlled: true, builder: (context) => ChangeNotifierProvider.value( value: state, child: Consumer( builder: (context, state, child) => ExpandableBottomSheet( key: sheetKey, background: Align( alignment: Alignment.bottomCenter, child: Container( height: MediaQuery.of(context).size.height * 0.7, color: Theme.of(context).colorScheme.surface, ), ), persistentHeader: GestureDetector( onVerticalDragUpdate: (details) { if (details.delta.dy > 10) { Navigator.of(context).pop(); } }, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ AudioPlayerWidget( podcast: MediaService.currentPodcast!, ), Container( width: MediaQuery.of(context).size.width, color: Theme.of(context).colorScheme.surface, child: Column( children: [ DidvanIconButton( size: 32, icon: DidvanIcons.angle_down_regular, onPressed: () { if (!isExpanded) { sheetKey.currentState?.expand(); isExpanded = true; return; } isExpanded = false; sheetKey.currentState?.contract(); }, ), const SizedBox(height: 16), ], ), ), ], ), ), expandableContent: state.appState == AppState.busy ? const SizedBox() : StudioDetailsWidget( studio: detailsState.studio, onCommentsTabSelected: () { Future.delayed( const Duration(milliseconds: 100), sheetKey.currentState?.expand, ); }, ), ), ), ), ); } } class _NavBarItem extends StatelessWidget { final VoidCallback onTap; final bool isSelected; final String title; final IconData selectedIcon; final IconData unselectedIcon; const _NavBarItem({ Key? key, required this.isSelected, required this.title, required this.selectedIcon, required this.unselectedIcon, required this.onTap, }) : super(key: key); @override Widget build(BuildContext context) { return Expanded( child: Tooltip( message: title, decoration: BoxDecoration( color: Theme.of(context).colorScheme.title, borderRadius: DesignConfig.highBorderRadius, boxShadow: DesignConfig.defaultShadow, ), child: GestureDetector( onTap: onTap, child: Container( color: Colors.transparent, child: Column( children: [ const SizedBox( height: 4, ), AnimatedContainer( padding: const EdgeInsets.all(4), duration: DesignConfig.lowAnimationDuration, decoration: BoxDecoration( shape: BoxShape.circle, color: isSelected ? Theme.of(context).colorScheme.focused : Theme.of(context).colorScheme.surface, ), child: Icon( isSelected ? selectedIcon : unselectedIcon, size: 32, color: DesignConfig.isDark ? Theme.of(context).colorScheme.text : Theme.of(context).colorScheme.title, ), ), DidvanText( title, style: Theme.of(context).textTheme.caption, color: Theme.of(context).colorScheme.title, ), const Spacer(), ], ), ), ), ), ); } }