didvan-app/lib/views/home/widgets/audio/audio_player_widget.dart

175 lines
5.4 KiB
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/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();
}
}