From e5f7f5e1dfa0c62dd6f84d9fafc46d0e0d9bcd3f Mon Sep 17 00:00:00 2001 From: PetitPrinc3 Date: Fri, 20 Dec 2024 07:02:51 -0400 Subject: [PATCH] Added download indicator underneath TrackTiles. Fixed downloading of newly liked titles when favorite tracks playlist is offline. --- README.md | 2 +- lib/api/deezer.dart | 5 +++++ lib/api/download.dart | 19 +++++++++------- lib/ui/details_screens.dart | 1 - lib/ui/library.dart | 2 -- lib/ui/search.dart | 2 -- lib/ui/tiles.dart | 43 +++++++++++++++++++++++++++++++++++-- pubspec.yaml | 2 +- 8 files changed, 59 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index cd004b2..9cd5687 100644 --- a/README.md +++ b/README.md @@ -54,12 +54,12 @@ This repository originates from [ReFreezer](https://github.com/DJDoubleD/ReFreez - Player bar does not always update its color on track tile tap or various other scenarios. - Favorite tracks playlist id is not properly saved (no/minor UX consequences). - Queue screen is laggy. This seems to be because of how the images are loaded. +- Tracks removed from playlist/favorites will not disappear immediately from the detailed screen. #### :building_construction: Upcoming features - Caching information to avoid reloading every time (eg. favorites screen) - Turn the mod into a skin for the official refreezer app - Deezer "playing" animation instead of highlight -- Download progress on track tiles #### :rocket: Definitely Not Deezer Features : - Floating player bar with background color based on title artwork diff --git a/lib/api/deezer.dart b/lib/api/deezer.dart index 9859532..9588037 100644 --- a/lib/api/deezer.dart +++ b/lib/api/deezer.dart @@ -4,6 +4,7 @@ import 'dart:math'; import 'package:http/http.dart' as http; import 'package:logging/logging.dart'; +import 'package:refreezer/api/download.dart'; import '../api/definitions.dart'; import '../api/spotify.dart'; @@ -295,6 +296,10 @@ class DeezerAPI { //Add track to favorites Future addFavoriteTrack(String id) async { await callGwApi('favorite_song.add', params: {'SNG_ID': id}); + if (await downloadManager.checkOffline( + playlist: Playlist(id: favoritesPlaylistId))) { + downloadManager.updateOfflinePlaylist(Playlist(id: favoritesPlaylistId)); + } } //Add album to favorites/library diff --git a/lib/api/download.dart b/lib/api/download.dart index 46167eb..d587159 100644 --- a/lib/api/download.dart +++ b/lib/api/download.dart @@ -413,16 +413,19 @@ class DownloadManager { List out = []; for (int i = 0; i < toDowload.length; i++) { Track t = toDowload[i]; - out.add(await Download.jsonFromTrack( + String tPath = _generatePath( t, - _generatePath( + true, + playlistName: playlist.title, + playlistTrackNumber: i, + ); + if (!(await File(tPath).exists())) { + out.add(await Download.jsonFromTrack( t, - true, - playlistName: playlist.title, - playlistTrackNumber: i, - ), - private: true, - )); + tPath, + private: true, + )); + } } await platform.invokeMethod('addDownloads', out); await start(); diff --git a/lib/ui/details_screens.dart b/lib/ui/details_screens.dart index 8616cbc..891b39c 100644 --- a/lib/ui/details_screens.dart +++ b/lib/ui/details_screens.dart @@ -4,7 +4,6 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:get_it/get_it.dart'; import 'package:intl/intl.dart'; -import 'package:logging/logging.dart'; import 'package:refreezer/fonts/deezer_icons.dart'; import 'package:refreezer/main.dart'; import 'package:refreezer/settings.dart'; diff --git a/lib/ui/library.dart b/lib/ui/library.dart index 5324672..11b2bea 100644 --- a/lib/ui/library.dart +++ b/lib/ui/library.dart @@ -286,8 +286,6 @@ class _LibraryTracksState extends State { int? trackCount; Sorting _sort = Sorting(sourceType: SortSourceTypes.TRACKS); - Playlist get _playlist => Playlist(id: deezerAPI.favoritesPlaylistId); - List get _sorted { List tcopy = List.from(tracks); tcopy.sort((a, b) => a.addedDate!.compareTo(b.addedDate!)); diff --git a/lib/ui/search.dart b/lib/ui/search.dart index 9af3067..c3623eb 100644 --- a/lib/ui/search.dart +++ b/lib/ui/search.dart @@ -428,8 +428,6 @@ class _SearchScreenState extends State { }, trailing: _removeHistoryItemWidget(i), ); - default: - return Container(); } }), diff --git a/lib/ui/tiles.dart b/lib/ui/tiles.dart index e401580..354e881 100644 --- a/lib/ui/tiles.dart +++ b/lib/ui/tiles.dart @@ -31,10 +31,11 @@ class TrackTile extends StatefulWidget { class _TrackTileState extends State { StreamSubscription? _mediaItemSub; + StreamSubscription? _downloadItemSub; bool _isOffline = false; bool nowPlaying = false; bool nowDownloading = false; - double downloadProgress = 0.0; + double downloadProgress = 0; /*bool get nowPlaying { if (GetIt.I().mediaItem.value == null) return false; @@ -58,12 +59,49 @@ class _TrackTileState extends State { } }); + //Listen to download change to drop progress indicator + _downloadItemSub = downloadManager.serviceEvents.stream.listen((e) async { + List downloads = await downloadManager.getDownloads(); + + if (e['action'] == 'onProgress') { + setState(() { + for (Map su in e['data']) { + downloads + .firstWhere((d) => d.id == su['id'], orElse: () => Download()) + .updateFromJson(su); + } + }); + } + + for (int i = 0; i < downloads.length; i++) { + if (downloads[i].trackId == widget.track.id) { + if (downloads[i].state != DownloadState.DONE) { + if (mounted) { + setState(() { + nowDownloading = true; + downloadProgress = downloads[i].progress; + Logger.root.info(downloadProgress); + }); + } + } else { + if (mounted) { + setState(() { + nowDownloading = false; + _isOffline = true; + }); + } + } + } + } + }); + super.initState(); } @override void dispose() { _mediaItemSub?.cancel(); + _downloadItemSub?.cancel(); super.dispose(); } @@ -124,7 +162,8 @@ class _TrackTileState extends State { LinearProgressIndicator( value: downloadProgress, color: Colors.green.shade400, - minHeight: 1.0, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + minHeight: 1, ) ]); } diff --git a/pubspec.yaml b/pubspec.yaml index cf9ab9a..ea4edd2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.7.16+2 +version: 0.7.17+2 environment: sdk: ">=3.0.0 <4.0.0"