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: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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue