import 'package:chewie/chewie.dart'; import 'package:didvan/config/design_config.dart'; import 'package:didvan/models/didvan_plus_model.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request_helper.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/video/primary_controls.dart'; import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; class DidvanPlusVideoPlayer extends StatefulWidget { final DidvanPlusModel video; const DidvanPlusVideoPlayer({super.key, required this.video}); @override State createState() => _DidvanPlusVideoPlayerState(); } class _DidvanPlusVideoPlayerState extends State { late VideoPlayerController _videoController; ChewieController? _chewieController; bool _isInitialized = false; @override void initState() { super.initState(); _initializeVideo(); } void _initializeVideo() { debugPrint('🎥 Didvan Plus Video - Original File: ${widget.video.file}'); debugPrint('🎥 Didvan Plus Video - Original Image: ${widget.video.image}'); // بررسی اینکه آیا لینک از قبل کامل است یا نه final bool fileHasHttp = widget.video.file.startsWith('http'); final bool fileHasBaseUrl = widget.video.file.contains(RequestHelper.baseUrl); debugPrint('🎥 File has HTTP: $fileHasHttp'); debugPrint('🎥 File has BaseURL: $fileHasBaseUrl'); // برای دیدوان پلاس، لینک مستقیم از سرور استفاده می‌شود final videoUrl = widget.video.file.startsWith('http') || widget.video.file.contains(RequestHelper.baseUrl) ? widget.video.file : '${RequestHelper.baseUrl}${widget.video.file}'; debugPrint('🎥 Video URL before token: $videoUrl'); // فقط به لینک‌های baseUrl سرور accessToken اضافه می‌شود، نه لینک‌های external مثل S3 final bool needsToken = videoUrl.contains(RequestHelper.baseUrl); debugPrint('🎥 Needs access token: $needsToken'); final String fullUrl; if (needsToken) { final separator = videoUrl.contains('?') ? '&' : '?'; fullUrl = '$videoUrl${separator}accessToken=${RequestService.token}'; } else { fullUrl = videoUrl; // لینک‌های S3 نیازی به token ندارند } debugPrint('🎥 Didvan Plus Video - Final URL: $fullUrl'); // برای S3 signed URLs نباید Authorization header اضافه کنیم if (needsToken) { _videoController = VideoPlayerController.networkUrl( Uri.parse(fullUrl), httpHeaders: { 'Authorization': 'Bearer ${RequestService.token}', }, ); } else { // برای S3 بدون Authorization header _videoController = VideoPlayerController.networkUrl( Uri.parse(fullUrl), ); } _videoController.initialize().then((_) { debugPrint('✅ Video initialized successfully'); setState(() { _chewieController = ChewieController( videoPlayerController: _videoController, autoPlay: true, looping: false, allowFullScreen: true, allowMuting: true, showControls: true, customControls: const PrimaryControls(), materialProgressColors: ChewieProgressColors( playedColor: DesignConfig.isDark ? const Color.fromARGB(255, 0, 125, 166) : const Color.fromARGB(255, 0, 89, 119), handleColor: DesignConfig.isDark ? const Color.fromARGB(255, 0, 125, 166) : const Color.fromARGB(255, 0, 89, 119), backgroundColor: Colors.grey, bufferedColor: Colors.grey.shade300, ), placeholder: Container( color: Colors.black, child: Center( child: Image.network( widget.video.image.startsWith('http') || widget.video.image.contains(RequestHelper.baseUrl) ? widget.video.image : '${RequestHelper.baseUrl}${widget.video.image}', fit: BoxFit.cover, ), ), ), ); _isInitialized = true; }); }).catchError((error) { debugPrint('❌ Video initialization error: $error'); }); } @override void dispose() { _videoController.dispose(); _chewieController?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: true, backgroundColor: Colors.black, body: SafeArea( child: Column( children: [ Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), color: Colors.black, child: Row( children: [ IconButton( icon: const Icon(Icons.close, color: Colors.white), onPressed: () => Navigator.of(context).pop(), ), Expanded( child: Text( widget.video.title, style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), ), Expanded( child: Center( child: _isInitialized && _chewieController != null ? Chewie(controller: _chewieController!) : Container( color: Colors.black, child: Stack( fit: StackFit.expand, children: [ Image.network( widget.video.image.startsWith('http') || widget.video.image.contains(RequestHelper.baseUrl) ? widget.video.image : '${RequestHelper.baseUrl}${widget.video.image}', fit: BoxFit.fitWidth, ), const Center( child: CircularProgressIndicator( color: Colors.white, ), ), ], ), ), ), ), Container( width: double.infinity, padding: const EdgeInsets.all(16), color: DesignConfig.isDark ? const Color(0xFF1E1E1E) : Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ DidvanText( widget.video.title, fontSize: 18, fontWeight: FontWeight.bold, ), const SizedBox(height: 8), DidvanText( widget.video.description, fontSize: 14, color: Colors.grey, ), ], ), ), ], ), ), ); } }