// ignore_for_file: implementation_imports, library_private_types_in_public_api import 'dart:math'; import 'package:audio_video_progress_bar/audio_video_progress_bar.dart'; import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/services/media/voice.dart'; import 'package:didvan/views/ai/widgets/message_bar_btn.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:just_audio/just_audio.dart'; class AudioWave extends StatefulWidget { final String file; final double loadingPaddingSize; final Duration? totalDuration; const AudioWave({ Key? key, required this.file, this.loadingPaddingSize = 0, this.totalDuration, }) : super(key: key); @override _AudioWaveState createState() => _AudioWaveState(); } class _AudioWaveState extends State { bool loading = false; Duration? totalDuration; final int id = DateTime.now().millisecondsSinceEpoch ~/ 1000 * Random().nextInt(1000000); @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) async { if (widget.totalDuration == null) { await VoiceService.getDuration(src: widget.file).then((duration) { setState(() { totalDuration = duration; if (kDebugMode) { print(totalDuration?.inSeconds); } }); }); } else { totalDuration = widget.totalDuration; } }); listeners(); } void listeners() async { VoiceService.audioPlayer.playerStateStream.listen((event) async { if (event.processingState == ProcessingState.completed) { await VoiceService.audioPlayer.pause(); await VoiceService.audioPlayer.seek(Duration.zero); VoiceService.resetVoicePlayer(); } }); } @override void dispose() { VoiceService.resetVoicePlayer(); super.dispose(); } @override Widget build(BuildContext context) { return SizedBox( height: 46, child: Directionality( textDirection: TextDirection.ltr, child: Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ StreamBuilder( stream: VoiceService.audioPlayer.playerStateStream, builder: (context, snapshot) { if (!snapshot.hasData) { return const SizedBox(); } if ((snapshot.data!.processingState == ProcessingState.loading || snapshot.data!.processingState == ProcessingState.buffering) && VoiceService.src == widget.file) { return MessageBarBtn( enable: true, icon: DidvanIcons.close_regular, click: () async { await VoiceService.resetVoicePlayer(); }, ); } return MessageBarBtn( enable: true, icon: VoiceService.audioPlayer.playing && VoiceService.src == widget.file ? DidvanIcons.pause_solid : DidvanIcons.play_solid, click: () async { await VoiceService.voiceHelper(src: widget.file); }, ); }), Expanded( child: StreamBuilder( stream: VoiceService.audioPlayer.positionStream, builder: (context, snapshot) { if (!snapshot.hasData) { return const SizedBox(); } if ((totalDuration == null || (totalDuration != null && (VoiceService.audioPlayer.duration != null && VoiceService .audioPlayer.duration!.inSeconds != totalDuration!.inSeconds))) && VoiceService.src == widget.file && VoiceService.audioPlayer.playing) { return Padding( padding: EdgeInsets.symmetric( vertical: widget.loadingPaddingSize), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate( 5, (index) => SpinKitWave( color: Theme.of(context) .colorScheme .primary .withValues(alpha: 0.4), size: 32, itemCount: 10, ))), ); } return Padding( padding: EdgeInsets.fromLTRB( 24, 12, 12, totalDuration != null ? 0 : 12), child: ProgressBar( thumbColor: Theme.of(context).colorScheme.title, progressBarColor: DesignConfig.isDark ? Theme.of(context).colorScheme.title : Theme.of(context).colorScheme.primary, baseBarColor: Theme.of(context).colorScheme.border, bufferedBarColor: Theme.of(context).colorScheme.splash, total: totalDuration ?? Duration.zero, progress: VoiceService.src == widget.file ? snapshot.data ?? Duration.zero : Duration.zero, thumbRadius: 6, barHeight: 3, timeLabelTextStyle: TextStyle( fontSize: totalDuration != null ? null : 0, // height: totalDuration != null ? 3 : 0, color: Theme.of(context).colorScheme.text, fontFamily: DesignConfig.fontFamily), onSeek: (value) { if (VoiceService.src == widget.file) { VoiceService.audioPlayer.seek( Duration(milliseconds: value.inMilliseconds)); } }, ), ); }, ), ) ], ), )); } Row noise({required final List values, final Color? color}) { return Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceAround, children: values .map( (e) => Container( margin: const EdgeInsets.symmetric(horizontal: 1), width: 2, height: e, decoration: BoxDecoration( borderRadius: BorderRadius.circular(1000), color: color ?? Theme.of(context).colorScheme.primary, ), ), ) .toList(), ); } }