import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/views/widgets/didvan/app_bar.dart'; import 'package:flutter/material.dart'; class DidvanScaffold extends StatefulWidget { final List? slivers; final List? children; final AppBarData? appBarData; final EdgeInsets padding; final Color? backgroundColor; final bool reverse; final ScrollPhysics? physics; final ScrollController? scrollController; final bool showSliversFirst; final bool hidePlayer; final Widget? floatingActionButton; const DidvanScaffold({ Key? key, this.slivers, required this.appBarData, this.children, this.physics, this.padding = const EdgeInsets.symmetric(horizontal: 16), this.backgroundColor, this.reverse = false, this.scrollController, this.showSliversFirst = false, this.hidePlayer = false, this.floatingActionButton, }) : super(key: key); @override State createState() => _DidvanScaffoldState(); } class _DidvanScaffoldState extends State { late final ScrollController _scrollController; @override void initState() { _scrollController = widget.scrollController ?? ScrollController(); super.initState(); } @override void dispose() { // if(!widget.hidePlayer){ // if(MediaService.currentPodcast != null){ // MediaService.audioPlayer.dispose(); // } // } super.dispose(); } @override Widget build(BuildContext context) { final double statusBarHeight = MediaQuery.of(context).padding.top; final double systemNavigationBarHeight = MediaQuery.of(context).padding.bottom; return Scaffold( backgroundColor: widget.backgroundColor, floatingActionButton: widget.floatingActionButton, body: Padding( padding: widget.appBarData == null ? EdgeInsets.zero : EdgeInsets.only(top: statusBarHeight), child: SizedBox( height: MediaQuery.of(context).size.height - statusBarHeight - systemNavigationBarHeight, child: Stack( children: [ CustomScrollView( physics: widget.physics, controller: _scrollController, reverse: widget.reverse, slivers: [ if (!widget.reverse && widget.appBarData != null) SliverAppBar( toolbarHeight: (widget.appBarData!.isSmall ? 56 : 72) - statusBarHeight, automaticallyImplyLeading: false, pinned: true, backgroundColor: widget.backgroundColor ?? Theme.of(context).colorScheme.surface, elevation: widget.appBarData?.hasElevation == false ? 0 : null, flexibleSpace: DidvanAppBar( appBarData: widget.appBarData!, backgroundColor: widget.backgroundColor ?? Theme.of(context).colorScheme.surface, ), ), if (widget.children != null && !widget.showSliversFirst) SliverPadding( padding: widget.padding.copyWith(bottom: 16), sliver: SliverList( delegate: SliverChildBuilderDelegate( (context, index) => widget.children![index], childCount: widget.children!.length, ), ), ), if (widget.slivers != null) for (var i = 0; i < widget.slivers!.length; i++) SliverPadding( padding: widget.padding.copyWith(bottom: 0), sliver: widget.slivers![i], ), if (widget.children != null && widget.showSliversFirst) SliverPadding( padding: widget.padding, sliver: SliverList( delegate: SliverChildBuilderDelegate( (context, index) => widget.children![index], childCount: widget.children!.length, ), ), ), if (widget.reverse) SliverToBoxAdapter( child: SizedBox( height: kToolbarHeight + MediaQuery.of(context).padding.top + 12, ), ), if (!widget.hidePlayer) const SliverPadding(padding: EdgeInsets.only(bottom: 90)) ], ), if (widget.reverse && widget.appBarData != null) _AppBar( appBarData: widget.appBarData!, scrollController: _scrollController, ), ], ), ), ), ); } } class _AppBar extends StatefulWidget { final AppBarData appBarData; final ScrollController scrollController; const _AppBar({ Key? key, required this.appBarData, required this.scrollController, }) : super(key: key); @override __AppBarState createState() => __AppBarState(); } class __AppBarState extends State<_AppBar> { bool _isScrolled = false; @override void initState() { widget.scrollController.addListener(() { final position = widget.scrollController.position.pixels; if (position > 10 && _isScrolled == false) { setState(() { _isScrolled = true; }); } if (position < 10 && _isScrolled == true) { setState(() { _isScrolled = false; }); } }); super.initState(); } @override Widget build(BuildContext context) { return DidvanAppBar( backgroundColor: Theme.of(context).colorScheme.surface, appBarData: widget.appBarData, hasBorder: _isScrolled, ); } } // class _PlayerNavBar extends StatelessWidget { // const _PlayerNavBar({Key? key}) : super(key: key); // // bool _enablePlayerController(StudioDetailsState state) => // MediaService.currentPodcast != null || // (MediaService.audioPlayerTag?.contains('podcast') ?? false); // // // @override // Widget build(BuildContext context) { // return StreamBuilder( // stream: MediaService.audioPlayer.isPlaying, // builder: (context, snapshot) => GestureDetector( // onTap: () => MediaService.currentPodcast == null || // MediaService.currentPodcast?.description == 'radar' // ? Navigator.of(context).pushNamed( // Routes.radarDetails, // arguments: { // 'onMarkChanged': (id, value) {}, // 'onCommentsChanged': (id, value) {}, // 'id': MediaService.currentPodcast?.id, // 'args': const RadarRequestArgs(page: 0), // 'hasUnmarkConfirmation': false, // }, // ) // : _showPlayerBottomSheet(context), // child: Consumer( // builder: (context, state, child) => AnimatedContainer( // padding: const EdgeInsets.only(top: 12), // duration: DesignConfig.lowAnimationDuration, // height: _enablePlayerController(state) ? 60 : 0, // margin: const EdgeInsets.symmetric(horizontal: 20), // decoration: BoxDecoration( // color: DesignConfig.isDark // ? Theme.of(context).colorScheme.focused // : Theme.of(context).colorScheme.navigation, // borderRadius: BorderRadius.circular(200), // ), // alignment: Alignment.topCenter, // child: Builder(builder: (context) { // if (!_enablePlayerController(state)) return const SizedBox(); // if (state.appState == AppState.failed) { // Future.delayed(const Duration(seconds: 2), () { // MediaService.resetAudioPlayer(); // }); // return DidvanText( // 'اتصال اینترنت برقرار نمی‌باشد', // color: DesignConfig.isDark // ? Theme.of(context).colorScheme.title // : Theme.of(context).colorScheme.secondCTA, // ); // } // if (MediaService.currentPodcast == null) { // return SizedBox( // height: 32, // child: Center( // child: SpinKitThreeBounce( // size: 18, // color: DesignConfig.isDark // ? Theme.of(context).colorScheme.title // : Theme.of(context).colorScheme.secondCTA, // ), // ), // ); // } // return SizedBox( // height: 56, // child: Row( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Padding( // padding: const EdgeInsets.only( // right: 12, // left: 8, // ), // child: DidvanIconButton( // icon: DidvanIcons.close_regular, // color: DesignConfig.isDark // ? null // : Theme.of(context).colorScheme.secondCTA, // gestureSize: 32, // 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, // maxLines: 1, // overflow: TextOverflow.ellipsis, // color: DesignConfig.isDark // ? null // : Theme.of(context).colorScheme.secondCTA, // ), // AudioSlider( // disableThumb: true, // tag: MediaService.audioPlayerTag!, // ), // ], // ), // ), // StreamBuilder( // stream: MediaService.audioPlayer.onReadyToPlay, // builder: (context, snapshot) { // if (snapshot.data == null || // state.appState == AppState.busy && // MediaService.currentPodcast?.description != // 'radar') { // return Padding( // padding: const EdgeInsets.only( // top: 4, // left: 16, // right: 16, // ), // child: SizedBox( // height: 18, // width: 18, // child: CircularProgressIndicator( // strokeWidth: 2, // color: DesignConfig.isDark // ? Theme.of(context).colorScheme.title // : Theme.of(context).colorScheme.secondCTA, // ), // ), // ); // } // return const SizedBox(); // }, // ), // if (state.appState != AppState.busy && // snapshot.data != null || // MediaService.currentPodcast?.description == 'radar') // Padding( // padding: const EdgeInsets.only( // left: 12, // right: 12, // ), // child: DidvanIconButton( // gestureSize: 32, // color: DesignConfig.isDark // ? null // : Theme.of(context).colorScheme.secondCTA, // icon: snapshot.data! // ? DidvanIcons.pause_solid // : DidvanIcons.play_solid, // onPressed: () { // if (state.args?.type == 'video') { // state.getStudioDetails( // MediaService.currentPodcast!.id, // args: state.podcastArgs, // fetchOnly: true, // ); // } // MediaService.handleAudioPlayback( // audioSource: MediaService.currentPodcast!.link, // id: MediaService.currentPodcast!.id, // isVoiceMessage: false, // ); // }, // ), // ), // ], // ), // ); // }), // ), // ), // ), // ); // } // // void _showPlayerBottomSheet(BuildContext context) { // final sheetKey = GlobalKey(); // bool isExpanded = false; // final detailsState = context.read(); // if (detailsState.args?.type == 'video') { // detailsState.getStudioDetails( // MediaService.currentPodcast!.id, // args: detailsState.podcastArgs, // fetchOnly: true, // ); // } // final state = context.read(); // showModalBottomSheet( // constraints: BoxConstraints( // maxWidth: ActionSheetUtils.mediaQueryData.size.width, // ), // backgroundColor: Colors.transparent, // context: context, // isScrollControlled: true, // builder: (context) => ChangeNotifierProvider.value( // value: state, // child: Consumer( // builder: (context, state, child) => MediaQuery( // data: ActionSheetUtils.mediaQueryData, // 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_up_regular, // onPressed: () { // if (!isExpanded) { // sheetKey.currentState?.expand(); // isExpanded = true; // } else { // isExpanded = false; // sheetKey.currentState?.contract(); // } // }, // ), // const SizedBox(height: 16), // ], // ), // ), // ], // ), // ), // expandableContent: state.appState == AppState.busy // ? Container( // height: MediaQuery.of(context).size.height / 2, // alignment: Alignment.center, // child: SpinKitSpinningLines( // color: Theme.of(context).colorScheme.primary, // ), // ) // : StudioDetailsWidget( // onMarkChanged: (id, value) => context // .read() // .changeMark(id, value, true), // ), // ), // ), // ), // ), // ); // } // }