mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-19 09:27:14 +02:00
release: v3.1.0 - fix Separate Singles, extension metadata, YTMusic parsing
Fixes: - Fix Separate Singles not working (#54) - albumType not extracted from Deezer API - Fix extension artist/album metadata missing provider IDs and cover URLs - Fix YTMusic extension not extracting album name and duration from search - Fix extension collection screens setState after dispose - Fix search source chips referencing removed badge props Changes: - Deezer convertTrack now includes album_type from record_type - Track creation preserves albumType and source throughout download flow - Go exports include provider_id in album/artist responses - Version bump to 3.1.0+59
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/// App version and info constants
|
||||
/// Update version here only - all other files will reference this
|
||||
class AppInfo {
|
||||
static const String version = '3.0.1';
|
||||
static const String buildNumber = '58';
|
||||
static const String version = '3.1.0';
|
||||
static const String buildNumber = '59';
|
||||
static const String fullVersion = '$version+$buildNumber';
|
||||
|
||||
|
||||
|
||||
@@ -1461,6 +1461,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||
final data = trackData;
|
||||
_log.d('Track data keys: ${data.keys.toList()}');
|
||||
_log.d('ISRC from API: ${data['isrc']}');
|
||||
_log.d('album_type from API: ${data['album_type']}');
|
||||
trackToDownload = Track(
|
||||
id: (data['spotify_id'] as String?) ?? trackToDownload.id,
|
||||
name: (data['name'] as String?) ?? trackToDownload.name,
|
||||
@@ -1482,9 +1483,12 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||
releaseDate: data['release_date'] as String?,
|
||||
deezerId: rawId,
|
||||
availability: trackToDownload.availability,
|
||||
// Preserve albumType from API response or original track
|
||||
albumType: (data['album_type'] as String?) ?? trackToDownload.albumType,
|
||||
source: trackToDownload.source,
|
||||
);
|
||||
_log.d(
|
||||
'Metadata enriched: Track ${trackToDownload.trackNumber}, Disc ${trackToDownload.discNumber}, ISRC ${trackToDownload.isrc}',
|
||||
'Metadata enriched: Track ${trackToDownload.trackNumber}, Disc ${trackToDownload.discNumber}, ISRC ${trackToDownload.isrc}, AlbumType ${trackToDownload.albumType}',
|
||||
);
|
||||
} else {
|
||||
_log.w('Unexpected track data type: ${trackData.runtimeType}');
|
||||
@@ -1720,6 +1724,8 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||
releaseDate: backendYear ?? trackToDownload.releaseDate,
|
||||
deezerId: trackToDownload.deezerId,
|
||||
availability: trackToDownload.availability,
|
||||
albumType: trackToDownload.albumType,
|
||||
source: trackToDownload.source,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -455,6 +455,8 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
trackNumber: track.trackNumber,
|
||||
discNumber: track.discNumber,
|
||||
releaseDate: track.releaseDate,
|
||||
albumType: track.albumType,
|
||||
source: track.source,
|
||||
availability: ServiceAvailability(
|
||||
tidal: availability['tidal'] as bool? ?? false,
|
||||
qobuz: availability['qobuz'] as bool? ?? false,
|
||||
@@ -552,9 +554,10 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
name: data['name'] as String? ?? '',
|
||||
releaseDate: data['release_date'] as String? ?? '',
|
||||
totalTracks: data['total_tracks'] as int? ?? 0,
|
||||
coverUrl: data['images'] as String?,
|
||||
coverUrl: (data['cover_url'] ?? data['images'])?.toString(),
|
||||
albumType: data['album_type'] as String? ?? 'album',
|
||||
artists: data['artists'] as String? ?? '',
|
||||
providerId: data['provider_id']?.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1431,6 +1431,7 @@ class _ExtensionAlbumScreenState extends ConsumerState<ExtensionAlbumScreen> {
|
||||
widget.extensionId,
|
||||
widget.albumId,
|
||||
);
|
||||
if (!mounted) return;
|
||||
|
||||
if (result == null) {
|
||||
setState(() {
|
||||
@@ -1457,6 +1458,7 @@ class _ExtensionAlbumScreenState extends ConsumerState<ExtensionAlbumScreen> {
|
||||
_isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_error = 'Error: $e';
|
||||
_isLoading = false;
|
||||
@@ -1567,6 +1569,7 @@ class _ExtensionPlaylistScreenState extends ConsumerState<ExtensionPlaylistScree
|
||||
widget.extensionId,
|
||||
widget.playlistId,
|
||||
);
|
||||
if (!mounted) return;
|
||||
|
||||
if (result == null) {
|
||||
setState(() {
|
||||
@@ -1593,6 +1596,7 @@ class _ExtensionPlaylistScreenState extends ConsumerState<ExtensionPlaylistScree
|
||||
_isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_error = 'Error: $e';
|
||||
_isLoading = false;
|
||||
@@ -1702,6 +1706,7 @@ class _ExtensionArtistScreenState extends ConsumerState<ExtensionArtistScreen> {
|
||||
widget.extensionId,
|
||||
widget.artistId,
|
||||
);
|
||||
if (!mounted) return;
|
||||
|
||||
if (result == null) {
|
||||
setState(() {
|
||||
@@ -1728,6 +1733,7 @@ class _ExtensionArtistScreenState extends ConsumerState<ExtensionArtistScreen> {
|
||||
_isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_error = 'Error: $e';
|
||||
_isLoading = false;
|
||||
|
||||
@@ -845,8 +845,6 @@ class _MetadataSourceSelector extends ConsumerWidget {
|
||||
_SourceChip(
|
||||
icon: Icons.graphic_eq,
|
||||
label: 'Deezer',
|
||||
badge: 'Free',
|
||||
badgeColor: colorScheme.tertiary,
|
||||
// Not selected if extension is active
|
||||
isSelected: currentSource == 'deezer' && !hasExtensionSearch,
|
||||
onTap: () {
|
||||
@@ -861,8 +859,6 @@ class _MetadataSourceSelector extends ConsumerWidget {
|
||||
_SourceChip(
|
||||
icon: Icons.music_note,
|
||||
label: 'Spotify',
|
||||
badge: 'API Key',
|
||||
badgeColor: colorScheme.secondary,
|
||||
// Not selected if extension is active
|
||||
isSelected: currentSource == 'spotify' && !hasExtensionSearch,
|
||||
onTap: () {
|
||||
|
||||
Reference in New Issue
Block a user