import 'package:didvan/models/didvan_voice_model.dart'; import 'package:didvan/services/network/request_helper.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:flutter/material.dart'; import 'package:just_audio/just_audio.dart'; class DidvanVoiceSection extends StatefulWidget { final DidvanVoiceModel didvanVoice; const DidvanVoiceSection({ super.key, required this.didvanVoice, }); @override State createState() => _DidvanVoiceSectionState(); } class _DidvanVoiceSectionState extends State { late AudioPlayer _audioPlayer; bool _isInitialized = false; @override void initState() { super.initState(); _initializeAudio(); } void _initializeAudio() async { _audioPlayer = AudioPlayer(); final audioUrl = '${RequestHelper.baseUrl}${widget.didvanVoice.file}?accessToken=${RequestService.token}'; debugPrint('🎙️ Didvan Voice Audio URL: $audioUrl'); try { await _audioPlayer.setUrl(audioUrl); setState(() { _isInitialized = true; }); debugPrint('✅ Audio initialized successfully'); } catch (e) { debugPrint('❌ Audio initialization error: $e'); } } @override void dispose() { _audioPlayer.dispose(); super.dispose(); } String _formatDuration(Duration? duration) { if (duration == null) return '00:00'; final minutes = duration.inMinutes; final seconds = duration.inSeconds % 60; return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}'; } @override Widget build(BuildContext context) { final imageUrl = '${RequestHelper.baseUrl}${widget.didvanVoice.image}'; return Container( margin: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color.fromRGBO(0, 69, 92, 1), borderRadius: BorderRadius.circular(12), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ ClipRRect( borderRadius: const BorderRadius.all(Radius.circular(8)), child: Image.network( imageUrl, width: 80, height: 130, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Container( width: 80, height: 130, color: Colors.grey.shade800, child: const Icon(Icons.music_note, color: Colors.white), ); }, ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DidvanText( widget.didvanVoice.title, fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, maxLines: 2, overflow: TextOverflow.ellipsis, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( onPressed: () { final newPosition = _audioPlayer.position + const Duration(seconds: 10); _audioPlayer.seek(newPosition); }, icon: const Icon(Icons.forward_10, color: Colors.white), iconSize: 28, ), StreamBuilder( stream: _audioPlayer.playerStateStream, builder: (context, snapshot) { final playerState = snapshot.data; final processingState = playerState?.processingState ?? ProcessingState.idle; final playing = playerState?.playing ?? false; if (processingState == ProcessingState.loading || processingState == ProcessingState.buffering) { return Container( margin: const EdgeInsets.symmetric(horizontal: 8), width: 48, height: 48, child: const CircularProgressIndicator( color: Colors.white, ), ); } else if (!playing) { return IconButton( onPressed: _audioPlayer.play, icon: const Icon(Icons.play_circle_filled, color: Colors.white), iconSize: 48, ); } else { return IconButton( onPressed: _audioPlayer.pause, icon: const Icon(Icons.pause_circle_filled, color: Colors.white), iconSize: 48, ); } }, ), IconButton( onPressed: () { final newPosition = _audioPlayer.position - const Duration(seconds: 10); _audioPlayer.seek(newPosition < Duration.zero ? Duration.zero : newPosition); }, icon: const Icon(Icons.replay_10, color: Colors.white), iconSize: 28, ), ], ), StreamBuilder( stream: _audioPlayer.durationStream, builder: (context, snapshot) { final duration = snapshot.data; return StreamBuilder( stream: _audioPlayer.positionStream, builder: (context, snapshot) { final position = snapshot.data ?? Duration.zero; return Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ DidvanText( _formatDuration(duration), fontSize: 12, color: Colors.white70, ), DidvanText( _formatDuration(position), fontSize: 12, color: Colors.white70, ), ], ), ); }, ); }, ), const SizedBox(height: 4), Directionality( textDirection: TextDirection.ltr, child: StreamBuilder( stream: _audioPlayer.durationStream, builder: (context, snapshot) { final duration = snapshot.data ?? Duration.zero; return StreamBuilder( stream: _audioPlayer.positionStream, builder: (context, snapshot) { var position = snapshot.data ?? Duration.zero; if (position > duration) { position = duration; } return SliderTheme( data: const SliderThemeData( thumbShape: RoundSliderThumbShape(enabledThumbRadius: 6), overlayShape: RoundSliderOverlayShape(overlayRadius: 12), trackHeight: 4, activeTrackColor: Colors.white70, inactiveTrackColor: Colors.white30, thumbColor: Colors.transparent, overlayColor: Colors.transparent, ), child: Slider( value: position.inMilliseconds.toDouble(), max: duration.inMilliseconds.toDouble(), onChanged: (value) { _audioPlayer.seek( Duration(milliseconds: value.toInt())); }, ), ); }, ); }, ), ), ], ), ), ], ), ); } }