feat: bottomsheet player controls base
This commit is contained in:
parent
2937d484cd
commit
139844596a
3 changed files with 207 additions and 35 deletions
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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<Player> {
|
|||
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<DraggableScrollableNotification>(
|
||||
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,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue