diff --git a/lib/main.dart b/lib/main.dart index 5b4f2fa..3ba4dad 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -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:ocarina/views/home_view.dart'; import 'package:ocarina/widgets/player.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:responsive_sizer/responsive_sizer.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -17,7 +18,10 @@ void main() async { 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(); runApp(const MyApp()); } diff --git a/lib/widgets/image_cover.dart b/lib/widgets/image_cover.dart index 257f69f..87199c1 100644 --- a/lib/widgets/image_cover.dart +++ b/lib/widgets/image_cover.dart @@ -25,26 +25,29 @@ class ImageCover extends StatelessWidget { height: _width, child: Hero( tag: heroTag, - child: FastCachedImage( - url: imageUrl, - loadingBuilder: (c, d) => Shimmer.fromColors( - baseColor: Colors.grey.shade300, - 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, - ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: FastCachedImage( + url: imageUrl, + loadingBuilder: (c, d) => Shimmer.fromColors( + baseColor: Colors.grey.shade300, + 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, + ), + ), + ); + }, + ), ), ), ), diff --git a/lib/widgets/player.dart b/lib/widgets/player.dart index e2537d4..d1d28ee 100644 --- a/lib/widgets/player.dart +++ b/lib/widgets/player.dart @@ -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:ocarina/api/audio/audioplayer_service.dart'; import 'package:ocarina/util/util.dart'; +import 'package:responsive_sizer/responsive_sizer.dart'; +import 'package:shimmer/shimmer.dart'; /// The player widget /// @@ -22,23 +26,184 @@ class PlayerState extends State { setState(() {}); } + var _showFullControls = false; + final _sheetController = DraggableScrollableController(); @override Widget build(BuildContext context) { - return DraggableScrollableSheet( - initialChildSize: 0.1, - snap: true, - snapSizes: const [0.1, 1], - minChildSize: 0.1, - builder: (c, s) => SingleChildScrollView( - controller: s, - child: Row( - children: [ - Text( - AudioPlayerService().song == null - ? "Nothing" - : AudioPlayerService().song!.title, - ), - ], + return NotificationListener( + onNotification: (n) { + if (n.extent > 0.3) { + _showFullControls = true; + } else { + _showFullControls = false; + } + setState(() {}); + return false; + }, + child: DraggableScrollableSheet( + controller: _sheetController, + 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, + ), + ), + ); + }, + )), + ), + ], + ), + ), + ), + ], + ), ), ), );