From cfe54321a78dcfd0cc13dfd3a87b764cea6c0154 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Sun, 24 Sep 2023 16:50:25 +0200 Subject: [PATCH] add button for clearing next up --- lib/components/PlayerScreen/queue_list.dart | 80 ++++++++++++++++++--- lib/services/queue_service.dart | 14 ++++ 2 files changed, 86 insertions(+), 8 deletions(-) diff --git a/lib/components/PlayerScreen/queue_list.dart b/lib/components/PlayerScreen/queue_list.dart index c21a7f9d3..c66e0c59d 100644 --- a/lib/components/PlayerScreen/queue_list.dart +++ b/lib/components/PlayerScreen/queue_list.dart @@ -125,7 +125,7 @@ class _QueueListState extends State { ), SliverPersistentHeader( - delegate: SectionHeaderDelegate( + delegate: QueueSectionHeader( title: const Text("Queue"), nextUpHeaderKey: widget.nextUpHeaderKey, )), @@ -215,9 +215,8 @@ class _QueueListState extends State { padding: const EdgeInsets.only(top: 20.0, bottom: 0.0), sliver: SliverPersistentHeader( pinned: false, //TODO use https://stackoverflow.com/a/69372976 to only ever have one of the headers pinned - delegate: SectionHeaderDelegate( - title: Text(AppLocalizations.of(context)!.nextUp), - height: 30.0, + delegate: NextUpSectionHeader( + controls: true, nextUpHeaderKey: widget.nextUpHeaderKey, ), // _source != null ? "Playing from ${_source?.name}" : "Queue", ), @@ -232,7 +231,7 @@ class _QueueListState extends State { padding: const EdgeInsets.only(top: 20.0, bottom: 0.0), sliver: SliverPersistentHeader( pinned: true, - delegate: SectionHeaderDelegate( + delegate: QueueSectionHeader( title: Row( children: [ Text("${AppLocalizations.of(context)!.playingFrom} "), @@ -1109,13 +1108,13 @@ class PlaybackBehaviorInfo { PlaybackBehaviorInfo(this.order, this.loop); } -class SectionHeaderDelegate extends SliverPersistentHeaderDelegate { +class QueueSectionHeader extends SliverPersistentHeaderDelegate { final Widget title; final bool controls; final double height; final GlobalKey nextUpHeaderKey; - SectionHeaderDelegate({ + QueueSectionHeader({ required this.title, required this.nextUpHeaderKey, this.controls = false, @@ -1132,7 +1131,7 @@ class SectionHeaderDelegate extends SliverPersistentHeaderDelegate { _queueService.getLoopModeStream(), (a, b) => PlaybackBehaviorInfo(a, b)), builder: (context, snapshot) { - PlaybackBehaviorInfo? info = snapshot.data as PlaybackBehaviorInfo?; + PlaybackBehaviorInfo? info = snapshot.data; return Container( // color: Colors.black.withOpacity(0.5), @@ -1212,6 +1211,71 @@ class SectionHeaderDelegate extends SliverPersistentHeaderDelegate { bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => false; } +class NextUpSectionHeader extends SliverPersistentHeaderDelegate { + final bool controls; + final double height; + final GlobalKey nextUpHeaderKey; + + NextUpSectionHeader({ + required this.nextUpHeaderKey, + this.controls = false, + this.height = 30.0, + }); + + @override + Widget build(context, double shrinkOffset, bool overlapsContent) { + final _queueService = GetIt.instance(); + + return Container( + // color: Colors.black.withOpacity(0.5), + padding: const EdgeInsets.symmetric(horizontal: 14.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Flex( + direction: Axis.horizontal, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(AppLocalizations.of(context)!.nextUp), + ])), + if (controls) + GestureDetector( + onTap: () { + _queueService.clearNextUp(); + Vibrate.feedback(FeedbackType.success); + }, + child: const Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only(top: 4.0), + child: Text("Clear Next Up"), + ), + Icon( + TablerIcons.x, + color: Colors.white, + size: 32.0, + ), + ], + ), + ), + ], + ), + ); + } + + @override + double get maxExtent => height; + + @override + double get minExtent => height; + + @override + bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => false; +} + /// If offline, check if an album is downloaded. Always returns true if online. /// Returns false if albumId is null. bool _isAlbumDownloadedIfOffline(String? albumId) { diff --git a/lib/services/queue_service.dart b/lib/services/queue_service.dart index b4d4722d1..4782cb8f0 100644 --- a/lib/services/queue_service.dart +++ b/lib/services/queue_service.dart @@ -363,6 +363,20 @@ class QueueService { } + Future clearNextUp() async { + + // _queueFromConcatenatingAudioSource(); // update internal queues + + // remove all items from Next Up + if (_queueNextUp.isNotEmpty) { + await _queueAudioSource.removeRange(_queueAudioSourceIndex+1, _queueAudioSourceIndex+1+_queueNextUp.length); + _queueNextUp.clear(); + } + + _queueFromConcatenatingAudioSource(); // update internal queues + + } + QueueInfo getQueue() { return QueueInfo(