// ignore_for_file: use_build_context_synchronously, deprecated_member_use import 'package:chewie/chewie.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/services/media/media.dart'; import 'package:didvan/views/comments/comments.dart'; import 'package:didvan/views/comments/comments_state.dart'; import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart'; import 'package:didvan/views/podcasts/studio_details/widgets/studio_details_widget.dart'; import 'package:didvan/views/widgets/bookmark_button.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/overview/multitype.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:didvan/views/widgets/tag_item.dart'; import 'package:didvan/views/widgets/video/primary_controls.dart'; import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:video_player/video_player.dart'; class VideoDetailsPage extends StatefulWidget { final Map pageData; const VideoDetailsPage({Key? key, required this.pageData}) : super(key: key); @override State createState() => _VideoDetailsPageState(); } class _VideoDetailsPageState extends State { int _currentlyPlayingId = 0; VideoPlayerController? _videoPlayerController; ChewieController? _chewieController; bool _isDescriptionExpanded = false; @override void initState() { super.initState(); final state = context.read(); state.args = widget.pageData['args']; Future.delayed( Duration.zero, () => state.getStudioDetails(widget.pageData['id']).then((_) { if (mounted) { _initializePlayer(state.studio); Future.delayed(const Duration(milliseconds: 500), () { if (mounted) { state.getRelatedContents(); } }); } }), ); } Future _initializePlayer(StudioDetailsData studio) async { if (studio.type == 'video') { _videoPlayerController?.dispose(); _chewieController?.dispose(); debugPrint("Playing video from URL: ${studio.link}"); _videoPlayerController = VideoPlayerController.network(studio.link); try { await _videoPlayerController!.initialize(); if (mounted) { setState(() { _chewieController = ChewieController( videoPlayerController: _videoPlayerController!, customControls: const PrimaryControls(), autoPlay: true, looping: true, aspectRatio: 16 / 9, materialProgressColors: ChewieProgressColors( playedColor: Theme.of(context).colorScheme.title, handleColor: Theme.of(context).colorScheme.title, ), ); _currentlyPlayingId = studio.id; }); } } catch (e) { debugPrint("Error initializing video player: $e"); } } } @override Widget build(BuildContext context) { return Consumer( builder: (context, state, child) { if (state.isStudioLoaded && _currentlyPlayingId != state.studio.id) { Future.microtask(() => _initializePlayer(state.studio)); } return StateHandler( state: state, onRetry: () { try { state.getStudioDetails(state.studio.id); } catch (e) { state.getStudioDetails(widget.pageData['id']); } }, builder: (context, state) { if (!state.isStudioLoaded) { return Scaffold( body: Center( child: Image.asset( Assets.loadingAnimation, width: 100, height: 100, ), ), ); } return WillPopScope( onWillPop: () async { if (MediaService.currentPodcast != null) { state.studio = MediaService.currentPodcast!; } state.handleTracking(id: state.studio.id); return true; }, child: Scaffold( backgroundColor: Theme.of(context).colorScheme.surface, appBar: PreferredSize( preferredSize: const Size.fromHeight(90.0), child: AppBar( backgroundColor: Colors.white, elevation: 0, automaticallyImplyLeading: false, flexibleSpace: SafeArea( child: Container( padding: const EdgeInsets.symmetric( horizontal: 16.0, vertical: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Center( child: SvgPicture.asset( 'lib/assets/images/logos/logo-horizontal-light.svg', height: 55, ), ), IconButton( icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', color: const Color.fromARGB(255, 102, 102, 102), height: 24, ), onPressed: () { Navigator.pop(context); }, ), ], ), ), ), )), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AspectRatio( aspectRatio: 16 / 9, child: Stack( children: [ (_chewieController != null && _chewieController!.videoPlayerController .value.isInitialized) ? Chewie(controller: _chewieController!) : Center( child: Image.asset( Assets.loadingAnimation, width: 100, height: 100, ), ), Positioned( top: 1, left: 1, child: BookmarkButton( value: state.studio.marked, onMarkChanged: (value) { if (widget.pageData['onMarkChanged'] != null) { widget.pageData['onMarkChanged']( state.studio.id, value); } }, gestureSize: 35, type: 'video', itemId: state.studio.id, ), ), ], ), ), _buildDescriptionSection(state), _buildRelatedContentSection(state), _buildCommentsSection(state), ], ), ), ), ); }, ); }, ); } Widget _buildDescriptionSection(StudioDetailsState state) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text( state.studio.title, style: const TextStyle( fontSize: 17, fontWeight: FontWeight.bold, color: Color.fromARGB(255, 0, 53, 70)), ), ), AnimatedSize( duration: const Duration(milliseconds: 300), child: ConstrainedBox( constraints: BoxConstraints( maxHeight: _isDescriptionExpanded ? double.infinity : 100.0, ), child: Html( key: ValueKey(state.studio.id), data: state.studio.description, onAnchorTap: (href, _, __) => launchUrlString(href!), style: { '*': Style( direction: TextDirection.rtl, textAlign: TextAlign.right, lineHeight: LineHeight.percent(135), margin: const Margins(), padding: HtmlPaddings.zero, color: const Color.fromARGB(255, 102, 102, 102), fontWeight: FontWeight.normal, ), }, ), ), ), InkWell( onTap: () { setState(() { _isDescriptionExpanded = !_isDescriptionExpanded; }); }, child: Padding( padding: const EdgeInsets.only(top: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( _isDescriptionExpanded ? 'lib/assets/icons/arrow-up2.svg' : 'lib/assets/icons/arrow-down.svg', color: Theme.of(context).primaryColor, height: 20, ), const SizedBox(width: 4), Text( _isDescriptionExpanded ? 'کمتر' : 'بیشتر', style: TextStyle( color: Theme.of(context).primaryColor, fontWeight: FontWeight.normal, ), ), ], ), ), ), if (state.studio.tags.isNotEmpty) const SizedBox(height: 16), if (state.studio.tags.isNotEmpty) Wrap( spacing: 8, runSpacing: 8, children: [ for (var i = 0; i < state.studio.tags.length; i++) TagItem( tag: state.studio.tags[i], onMarkChanged: (id, value) { if (widget.pageData['onMarkChanged'] != null) { widget.pageData['onMarkChanged'](id, value); } }, type: 'video', ), ], ), ], ), ), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const SizedBox(), if (state.nextStudio != null && state.alongSideState == AppState.idle) StudioPreview( isNext: true, studio: state.nextStudio!, ), if (state.alongSideState == AppState.busy) StudioPreview.placeHolder, if (state.prevStudio != null && state.alongSideState == AppState.idle) StudioPreview( isNext: false, studio: state.prevStudio!, ), if (state.alongSideState == AppState.busy) StudioPreview.placeHolder, const SizedBox(), ], ), ], ); } Widget _buildCommentsSection(StudioDetailsState state) { return Container( width: double.infinity, margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: const BoxDecoration( color: Color(0xFF059669), borderRadius: BorderRadius.only( topLeft: Radius.circular(12), topRight: Radius.circular(12), ), ), child: const DidvanText( 'نظرات', style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), SizedBox( height: 400, child: ChangeNotifierProvider( create: (context) => CommentsState(), child: Comments( pageData: { 'id': state.studio.id, 'type': 'studio', 'title': state.studio.title, 'onCommentsChanged': state.onCommentsChanged, 'isPage': false, }, ), ), ), ], ), ); } Widget _buildRelatedContentSection(StudioDetailsState state) { debugPrint("تعداد مطالب مرتبط: ${state.studio.relatedContents.length}"); debugPrint( "آیا لیست مطالب مرتبط خالی است؟ ${state.studio.relatedContentsIsEmpty}"); debugPrint("تعداد tags: ${state.studio.tags.length}"); return Container( width: double.infinity, margin: const EdgeInsets.all(8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Padding( padding: EdgeInsets.all(8.0), child: Text( "مطالب مرتبط:", style: TextStyle( fontSize: 16, color: Color.fromARGB(255, 0, 53, 70), fontWeight: FontWeight.bold), ), ), Padding( padding: const EdgeInsets.all(8), child: Builder( builder: (context) { debugPrint("Building related content section:"); debugPrint( " - relatedContents.length: ${state.studio.relatedContents.length}"); debugPrint( " - relatedContentsIsEmpty: ${state.studio.relatedContentsIsEmpty}"); debugPrint(" - tags.length: ${state.studio.tags.length}"); if (state.studio.relatedContents.isNotEmpty) { debugPrint( " - Showing ${state.studio.relatedContents.length} related items"); return Column( children: [ ...state.studio.relatedContents .map((item) => Padding( padding: const EdgeInsets.only(bottom: 8), child: MultitypeOverview( item: item, onMarkChanged: (id, value) { if (widget.pageData['onMarkChanged'] != null) { widget.pageData['onMarkChanged']( id, value); } }, ), )) .toList(), ], ); } else if (state.studio.relatedContentsIsEmpty) { debugPrint(" - Showing empty message"); return const Padding( padding: EdgeInsets.all(32.0), child: Center( child: DidvanText( 'مطالب مرتبطی یافت نشد', style: TextStyle( color: Colors.grey, fontSize: 16, ), ), ), ); } else { debugPrint(" - Showing placeholders (loading state)"); return Column( children: [ const Padding( padding: EdgeInsets.all(8.0), child: Text( 'در حال بارگذاری مطالب مرتبط...', style: TextStyle( fontSize: 12, color: Colors.grey, ), ), ), ...List.generate( 3, (index) => Padding( padding: const EdgeInsets.only(bottom: 8), child: MultitypeOverview.placeholder, )), ], ); } }, ), ), ], ), ); } @override void dispose() { _videoPlayerController?.dispose(); _chewieController?.dispose(); super.dispose(); } }