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