feat: bottomsheet player controls base

This commit is contained in:
Matyáš Caras 2024-05-23 20:36:42 +02:00
parent 2937d484cd
commit 139844596a
Signed by: hernik
GPG key ID: 2A3175F98820C5C6
3 changed files with 207 additions and 35 deletions

View file

@ -4,6 +4,7 @@ import 'package:just_audio_background/just_audio_background.dart';
import 'package:just_audio_media_kit/just_audio_media_kit.dart'; import 'package:just_audio_media_kit/just_audio_media_kit.dart';
import 'package:ocarina/views/home_view.dart'; import 'package:ocarina/views/home_view.dart';
import 'package:ocarina/widgets/player.dart'; import 'package:ocarina/widgets/player.dart';
import 'package:path_provider/path_provider.dart';
import 'package:responsive_sizer/responsive_sizer.dart'; import 'package:responsive_sizer/responsive_sizer.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -17,7 +18,10 @@ void main() async {
androidNotificationOngoing: true, androidNotificationOngoing: true,
); );
await FastCachedImageConfig.init(clearCacheAfter: const Duration(days: 31)); await FastCachedImageConfig.init(
clearCacheAfter: const Duration(days: 31),
subDir: (await getApplicationCacheDirectory()).path,
);
sp = await SharedPreferences.getInstance(); sp = await SharedPreferences.getInstance();
runApp(const MyApp()); runApp(const MyApp());
} }

View file

@ -25,26 +25,29 @@ class ImageCover extends StatelessWidget {
height: _width, height: _width,
child: Hero( child: Hero(
tag: heroTag, tag: heroTag,
child: FastCachedImage( child: ClipRRect(
url: imageUrl, borderRadius: BorderRadius.circular(8),
loadingBuilder: (c, d) => Shimmer.fromColors( child: FastCachedImage(
baseColor: Colors.grey.shade300, url: imageUrl,
highlightColor: Colors.grey.shade100, loadingBuilder: (c, d) => Shimmer.fromColors(
child: Container( baseColor: Colors.grey.shade300,
color: Colors.grey, highlightColor: Colors.grey.shade100,
), child: Container(
), color: Colors.grey,
errorBuilder: (c, _, __) {
return ColoredBox(
color: Theme.of(context).colorScheme.primaryContainer,
child: Center(
child: Icon(
Icons.music_note,
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
), ),
); ),
}, errorBuilder: (c, _, __) {
return ColoredBox(
color: Theme.of(context).colorScheme.primaryContainer,
child: Center(
child: Icon(
Icons.music_note,
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
),
);
},
),
), ),
), ),
), ),

View file

@ -1,6 +1,10 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:fast_cached_network_image/fast_cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:ocarina/api/audio/audioplayer_service.dart'; import 'package:ocarina/api/audio/audioplayer_service.dart';
import 'package:ocarina/util/util.dart'; import 'package:ocarina/util/util.dart';
import 'package:responsive_sizer/responsive_sizer.dart';
import 'package:shimmer/shimmer.dart';
/// The player widget /// The player widget
/// ///
@ -22,23 +26,184 @@ class PlayerState extends State<Player> {
setState(() {}); setState(() {});
} }
var _showFullControls = false;
final _sheetController = DraggableScrollableController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DraggableScrollableSheet( return NotificationListener<DraggableScrollableNotification>(
initialChildSize: 0.1, onNotification: (n) {
snap: true, if (n.extent > 0.3) {
snapSizes: const [0.1, 1], _showFullControls = true;
minChildSize: 0.1, } else {
builder: (c, s) => SingleChildScrollView( _showFullControls = false;
controller: s, }
child: Row( setState(() {});
children: [ return false;
Text( },
AudioPlayerService().song == null child: DraggableScrollableSheet(
? "Nothing" controller: _sheetController,
: AudioPlayerService().song!.title, initialChildSize: 0.1,
), snap: true,
], snapSizes: const [0.1, 1],
minChildSize: 0.1,
builder: (c, s) => SingleChildScrollView(
controller: s,
child: Column(
children: [
AnimatedOpacity(
opacity: _showFullControls ? 0 : 1,
duration: const Duration(milliseconds: 300),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: GestureDetector(
onTap: () {
_sheetController.animateTo(
(_sheetController.size == 1) ? 0.1 : 1,
duration: const Duration(milliseconds: 300),
curve: Curves.easeIn,
);
},
child: Container(
color: Theme.of(context).colorScheme.primaryContainer,
height: 10.h,
width: 100.w,
child: Padding(
padding: const EdgeInsets.all(8),
child: Row(
children: [
SizedBox(
height: 10.h,
width: 10.h,
child: Padding(
padding: const EdgeInsets.all(8),
child: ClipRRect(
child: (AudioPlayerService().song == null)
? ColoredBox(
color: Theme.of(context)
.colorScheme
.primaryContainer,
child: Center(
child: Icon(
Icons.music_note,
color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
),
),
)
: (FastCachedImage(
url: AudioPlayerService()
.song!
.coverArtUrl,
loadingBuilder: (c, d) =>
Shimmer.fromColors(
baseColor: Colors.grey.shade300,
highlightColor:
Colors.grey.shade100,
child: Container(
color: Colors.grey,
),
),
errorBuilder: (c, _, __) {
logger
..e(_)
..e(__);
return ColoredBox(
color: Theme.of(context)
.colorScheme
.primaryContainer,
child: Center(
child: Icon(
Icons.music_note,
color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
),
),
);
},
)),
),
),
),
const SizedBox(
width: 5,
),
AutoSizeText(
AudioPlayerService().song == null
? "Nothing"
: AudioPlayerService().song!.title,
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
fontSize: 14,
decoration: TextDecoration.none,
),
),
],
),
),
),
),
),
),
SizedBox(
height: 90.h,
width: 100.w,
child: Center(
child: Column(
children: [
ClipRRect(
child: (AudioPlayerService().song == null)
? ColoredBox(
color: Theme.of(context)
.colorScheme
.primaryContainer,
child: Center(
child: Icon(
Icons.music_note,
color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
),
),
)
: (FastCachedImage(
url: AudioPlayerService().song!.coverArtUrl,
loadingBuilder: (c, d) => Shimmer.fromColors(
baseColor: Colors.grey.shade300,
highlightColor: Colors.grey.shade100,
child: Container(
color: Colors.grey,
),
),
errorBuilder: (c, _, __) {
logger
..e(_)
..e(__);
return ColoredBox(
color: Theme.of(context)
.colorScheme
.primaryContainer,
child: Center(
child: Icon(
Icons.music_note,
color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
),
),
);
},
)),
),
],
),
),
),
],
),
), ),
), ),
); );