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,6 +25,8 @@ class ImageCover extends StatelessWidget {
height: _width, height: _width,
child: Hero( child: Hero(
tag: heroTag, tag: heroTag,
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: FastCachedImage( child: FastCachedImage(
url: imageUrl, url: imageUrl,
loadingBuilder: (c, d) => Shimmer.fromColors( loadingBuilder: (c, d) => Shimmer.fromColors(
@ -48,6 +50,7 @@ class ImageCover extends StatelessWidget {
), ),
), ),
), ),
),
const SizedBox( const SizedBox(
height: 5, height: 5,
), ),

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,25 +26,186 @@ 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>(
onNotification: (n) {
if (n.extent > 0.3) {
_showFullControls = true;
} else {
_showFullControls = false;
}
setState(() {});
return false;
},
child: DraggableScrollableSheet(
controller: _sheetController,
initialChildSize: 0.1, initialChildSize: 0.1,
snap: true, snap: true,
snapSizes: const [0.1, 1], snapSizes: const [0.1, 1],
minChildSize: 0.1, minChildSize: 0.1,
builder: (c, s) => SingleChildScrollView( builder: (c, s) => SingleChildScrollView(
controller: s, 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( child: Row(
children: [ children: [
Text( 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 AudioPlayerService().song == null
? "Nothing" ? "Nothing"
: AudioPlayerService().song!.title, : 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,
),
),
);
},
)),
),
],
),
),
),
],
),
),
),
); );
} }
} }