import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/services/media/media.dart'; import 'package:didvan/views/home/widgets/audio/audio_slider.dart'; import 'package:didvan/views/home/widgets/bookmark_button.dart'; import 'package:didvan/views/widgets/didvan/icon_button.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/ink_wrapper.dart'; import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:flutter/material.dart'; class AudioPlayerWidget extends StatelessWidget { final StudioDetailsData podcast; const AudioPlayerWidget({Key? key, required this.podcast}) : super(key: key); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( borderRadius: const BorderRadius.vertical(top: Radius.circular(8)), color: Theme.of(context).colorScheme.surface, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( margin: const EdgeInsets.symmetric(vertical: 20), height: 3, width: 50, color: Theme.of(context).colorScheme.hint, ), Padding( padding: const EdgeInsets.symmetric(horizontal: 24), child: SkeletonImage( imageUrl: podcast.image, aspectRatio: 1 / 1, ), ), const SizedBox(height: 16), DidvanText( podcast.title, style: Theme.of(context).textTheme.bodyText1, ), const SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: AudioSlider( tag: podcast.media, showTimer: true, duration: podcast.duration, ), ), Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ DidvanIconButton( icon: DidvanIcons.sleep_timer_regular, onPressed: () {}, ), Column( children: [ DidvanIconButton( size: 32, icon: DidvanIcons.media_forward_solid, onPressed: () { MediaService.audioPlayer.seek( Duration( seconds: MediaService.audioPlayer.position.inSeconds + 30, ), ); }, ), const DidvanText('30', isEnglishFont: true), ], ), _PlayPouseAnimatedIcon( audioSource: podcast.media, ), Column( children: [ DidvanIconButton( size: 32, icon: DidvanIcons.media_backward_solid, onPressed: () { MediaService.audioPlayer.seek( Duration( seconds: MediaService.audioPlayer.position.inSeconds - 10, ), ); }, ), const DidvanText('10', isEnglishFont: true), ], ), BookmarkButton( gestureSize: 48, value: podcast.marked, onMarkChanged: (value) {}, ), ], ), ], ), ); } } class _PlayPouseAnimatedIcon extends StatefulWidget { final String audioSource; const _PlayPouseAnimatedIcon({Key? key, required this.audioSource}) : super(key: key); @override State<_PlayPouseAnimatedIcon> createState() => __PlayPouseAnimatedIconState(); } class __PlayPouseAnimatedIconState extends State<_PlayPouseAnimatedIcon> with SingleTickerProviderStateMixin { late final AnimationController _animationController; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: DesignConfig.lowAnimationDuration, ); if (MediaService.audioPlayer.playing) { _animationController.forward(); } } @override Widget build(BuildContext context) { return InkWrapper( borderRadius: BorderRadius.circular(100), onPressed: () { MediaService.handleAudioPlayback( audioSource: widget.audioSource, isVoiceMessage: false, ); if (MediaService.audioPlayer.playing) { _animationController.forward(); } else { _animationController.reverse(); } }, child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.title, shape: BoxShape.circle, ), child: AnimatedIcon( size: 40, color: Theme.of(context).colorScheme.surface, icon: AnimatedIcons.play_pause, progress: _animationController, ), ), ); } @override void dispose() { _animationController.dispose(); super.dispose(); } }