-
Notifications
You must be signed in to change notification settings - Fork 136
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Redesign] Recover Now-Playing Queue on Startup (#547)
* Save queue item ids on change and attempt to reload queue on next startup. * Added saving of playback position in current track. * Initial version of queue history and restore page. * Improved queue history loading, added loading indication. * Improved loading indicater and Now Playing bar transitions. Added setting to diable queue autoload. * Improved various transitions between various screens and states. * Prevented saving of empty queues. Reversed queue restore screen. Added saving queue on startPlayback(). Added saving global queue source. Added ability to easily retry queue load if all items fail. Delayed overwriting latest until user initiates playback or modifies queue after load. * Moved to batched queries in queue item lookup. Improved song count display on queue restore screen. * Removed function getTrackFromId. Added direct dependancy on collections package. Made loadSavedQueue cleaner. * Moved theme generation logic out of UI. Increased PaletteGenerator timeout from 2 to 5 seconds. * Return blue theme on failure loading theme image. Ran code through dart format. * Use currentAlbumImageProvider for all uses of current track album image. Perform now-playing queue album precaching in currentAlbumImageProvider instead of AlbumImage. Directly handle image loading error in playerScreenThemeProvider instead of waiting for timeout. --------- Co-authored-by: Chaphasilor <[email protected]>
- Loading branch information
1 parent
6af1d72
commit 82628e7
Showing
26 changed files
with
1,437 additions
and
774 deletions.
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
lib/components/AudioServiceSettingsScreen/loadQueueOnStartup_selector.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; | ||
import 'package:hive/hive.dart'; | ||
|
||
import '../../services/finamp_settings_helper.dart'; | ||
import '../../models/finamp_models.dart'; | ||
|
||
class LoadQueueOnStartupSelector extends StatelessWidget { | ||
const LoadQueueOnStartupSelector({Key? key}) : super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return ValueListenableBuilder<Box<FinampSettings>>( | ||
valueListenable: FinampSettingsHelper.finampSettingsListener, | ||
builder: (_, box, __) { | ||
return SwitchListTile.adaptive( | ||
title: Text(AppLocalizations.of(context)!.autoloadLastQueueOnStartup), | ||
subtitle: Text( | ||
AppLocalizations.of(context)!.autoloadLastQueueOnStartupSubtitle), | ||
value: FinampSettingsHelper.finampSettings.autoloadLastQueueOnStartup, | ||
onChanged: (value) => | ||
FinampSettingsHelper.setAutoloadLastQueueOnStartup(value), | ||
); | ||
}, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import 'package:finamp/models/jellyfin_models.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:get_it/get_it.dart'; | ||
import 'package:hive/hive.dart'; | ||
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; | ||
|
||
import '../../models/finamp_models.dart'; | ||
import '../../services/downloads_helper.dart'; | ||
import '../../services/finamp_settings_helper.dart'; | ||
import '../../services/jellyfin_api_helper.dart'; | ||
import '../../services/queue_service.dart'; | ||
import '../album_image.dart'; | ||
import '../error_snackbar.dart'; | ||
|
||
class QueueRestoreTile extends StatelessWidget { | ||
const QueueRestoreTile({Key? key, required this.info}) : super(key: key); | ||
|
||
final FinampStorableQueueInfo info; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final queuesBox = Hive.box<FinampStorableQueueInfo>("Queues"); | ||
final downloadsHelper = GetIt.instance<DownloadsHelper>(); | ||
final jellyfinApiHelper = GetIt.instance<JellyfinApiHelper>(); | ||
final queueService = GetIt.instance<QueueService>(); | ||
int remainingSongs = info.songCount - info.previousTracks.length; | ||
Future<BaseItemDto?> track; | ||
if (info.currentTrack == null) { | ||
track = Future.value(null); | ||
} else if (FinampSettingsHelper.finampSettings.isOffline) { | ||
track = Future.value( | ||
downloadsHelper.getDownloadedSong(info.currentTrack!)?.song); | ||
} else { | ||
track = jellyfinApiHelper | ||
.getItemById(info.currentTrack!) | ||
.then((x) => x, onError: (_) => null); | ||
} | ||
|
||
return ListTile( | ||
title: Text(AppLocalizations.of(context)!.queueRestoreTitle( | ||
DateTime.fromMillisecondsSinceEpoch(info.creation))), | ||
leading: FutureBuilder<BaseItemDto?>( | ||
future: track, | ||
builder: (context, snapshot) => AlbumImage(item: snapshot.data)), | ||
isThreeLine: true, | ||
//dense: true, | ||
subtitle: FutureBuilder<BaseItemDto?>( | ||
future: track, | ||
initialData: null, | ||
builder: (context, snapshot) => Column( | ||
crossAxisAlignment: CrossAxisAlignment.start, | ||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
children: ((snapshot.data?.name == null) | ||
? <Text>[] | ||
: [ | ||
// exclude subtitle line 1 if song name is null | ||
Text( | ||
AppLocalizations.of(context)! | ||
.queueRestoreSubtitle1(snapshot.data!.name!), | ||
overflow: TextOverflow.ellipsis) | ||
]) + | ||
[ | ||
Text(AppLocalizations.of(context)! | ||
.queueRestoreSubtitle2(info.songCount, remainingSongs)) | ||
])), | ||
trailing: IconButton( | ||
icon: const Icon(Icons.arrow_circle_right_outlined), | ||
onPressed: () { | ||
var latest = queuesBox.get("latest"); | ||
if (latest != null && latest.songCount != 0) { | ||
queuesBox.put(latest.creation.toString(), latest); | ||
} | ||
BuildContext parentContext = Navigator.of(context).context; | ||
queueService | ||
.loadSavedQueue(info) | ||
.catchError((x) => errorSnackbar(x, parentContext)); | ||
Navigator.of(context).popUntil( | ||
(route) => route.isFirst && !route.willHandlePopInternally); | ||
}), | ||
); | ||
} | ||
} |
Oops, something went wrong.