mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-05-20 23:24:52 +02:00
feat: add totalTracks to Track model and refine EP/single classification (#202)
This commit is contained in:
+13
-1
@@ -21,6 +21,7 @@ class Track {
|
||||
final ServiceAvailability? availability;
|
||||
final String? source;
|
||||
final String? albumType;
|
||||
final int? totalTracks;
|
||||
final String? itemType;
|
||||
|
||||
const Track({
|
||||
@@ -41,10 +42,21 @@ class Track {
|
||||
this.availability,
|
||||
this.source,
|
||||
this.albumType,
|
||||
this.totalTracks,
|
||||
this.itemType,
|
||||
});
|
||||
|
||||
bool get isSingle => albumType == 'single' || albumType == 'ep';
|
||||
bool get isSingle {
|
||||
switch (albumType?.toLowerCase()) {
|
||||
case 'single':
|
||||
return true;
|
||||
case 'ep':
|
||||
final count = totalTracks;
|
||||
return count == null || count <= 1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool get isAlbumItem => itemType == 'album';
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ Track _$TrackFromJson(Map<String, dynamic> json) => Track(
|
||||
),
|
||||
source: json['source'] as String?,
|
||||
albumType: json['albumType'] as String?,
|
||||
totalTracks: (json['totalTracks'] as num?)?.toInt(),
|
||||
itemType: json['itemType'] as String?,
|
||||
);
|
||||
|
||||
@@ -49,6 +50,7 @@ Map<String, dynamic> _$TrackToJson(Track instance) => <String, dynamic>{
|
||||
'availability': instance.availability,
|
||||
'source': instance.source,
|
||||
'albumType': instance.albumType,
|
||||
'totalTracks': instance.totalTracks,
|
||||
'itemType': instance.itemType,
|
||||
};
|
||||
|
||||
|
||||
@@ -2362,6 +2362,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||
deezerId: baseTrack.deezerId,
|
||||
availability: baseTrack.availability,
|
||||
albumType: baseTrack.albumType,
|
||||
totalTracks: baseTrack.totalTracks,
|
||||
source: baseTrack.source,
|
||||
);
|
||||
}
|
||||
@@ -3274,6 +3275,8 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||
albumType:
|
||||
(data['album_type'] as String?) ??
|
||||
trackToDownload.albumType,
|
||||
totalTracks:
|
||||
data['total_tracks'] as int? ?? trackToDownload.totalTracks,
|
||||
source: trackToDownload.source,
|
||||
);
|
||||
_log.d(
|
||||
@@ -3488,6 +3491,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||
deezerId: deezerTrackId,
|
||||
availability: trackToDownload.availability,
|
||||
albumType: trackToDownload.albumType,
|
||||
totalTracks: trackToDownload.totalTracks,
|
||||
source: trackToDownload.source,
|
||||
);
|
||||
_log.d(
|
||||
|
||||
@@ -816,6 +816,7 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
discNumber: track.discNumber,
|
||||
releaseDate: track.releaseDate,
|
||||
albumType: track.albumType,
|
||||
totalTracks: track.totalTracks,
|
||||
source: track.source,
|
||||
availability: ServiceAvailability(
|
||||
tidal: availability['tidal'] as bool? ?? false,
|
||||
@@ -897,6 +898,8 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
trackNumber: data['track_number'] as int?,
|
||||
discNumber: data['disc_number'] as int?,
|
||||
releaseDate: data['release_date'] as String?,
|
||||
albumType: data['album_type'] as String?,
|
||||
totalTracks: data['total_tracks'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -919,6 +922,7 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||
trackNumber: data['track_number'] as int?,
|
||||
discNumber: data['disc_number'] as int?,
|
||||
releaseDate: data['release_date']?.toString(),
|
||||
totalTracks: data['total_tracks'] as int?,
|
||||
source:
|
||||
source ??
|
||||
data['source']?.toString() ??
|
||||
|
||||
@@ -224,6 +224,8 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||
trackNumber: data['track_number'] as int?,
|
||||
discNumber: data['disc_number'] as int?,
|
||||
releaseDate: data['release_date'] as String?,
|
||||
albumType: data['album_type'] as String?,
|
||||
totalTracks: data['total_tracks'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
Track _parseTrack(Map<String, dynamic> data) {
|
||||
Track _parseTrack(Map<String, dynamic> data, {ArtistAlbum? album}) {
|
||||
int durationMs = 0;
|
||||
final durationValue = data['duration_ms'];
|
||||
if (durationValue is int) {
|
||||
@@ -307,18 +307,22 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||
id: (data['spotify_id'] ?? data['id'] ?? '').toString(),
|
||||
name: (data['name'] ?? '').toString(),
|
||||
artistName: (data['artists'] ?? data['artist'] ?? '').toString(),
|
||||
albumName: (data['album_name'] ?? data['album'] ?? '').toString(),
|
||||
albumArtist: data['album_artist']?.toString(),
|
||||
albumName: (data['album_name'] ?? data['album'] ?? album?.name ?? '')
|
||||
.toString(),
|
||||
albumArtist: data['album_artist']?.toString() ?? widget.artistName,
|
||||
artistId:
|
||||
(data['artist_id'] ?? data['artistId'])?.toString() ??
|
||||
widget.artistId,
|
||||
albumId: data['album_id']?.toString(),
|
||||
coverUrl: (data['cover_url'] ?? data['images'])?.toString(),
|
||||
albumId: data['album_id']?.toString() ?? album?.id,
|
||||
coverUrl: (data['cover_url'] ?? data['images'] ?? album?.coverUrl)
|
||||
?.toString(),
|
||||
isrc: data['isrc']?.toString(),
|
||||
duration: (durationMs / 1000).round(),
|
||||
trackNumber: data['track_number'] as int?,
|
||||
discNumber: data['disc_number'] as int?,
|
||||
releaseDate: data['release_date']?.toString(),
|
||||
albumType: data['album_type']?.toString() ?? album?.albumType,
|
||||
totalTracks: data['total_tracks'] as int? ?? album?.totalTracks,
|
||||
source: data['provider_id']?.toString(),
|
||||
);
|
||||
}
|
||||
@@ -669,7 +673,9 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||
List<ArtistAlbum> albums,
|
||||
) {
|
||||
final albumsOnly = albums.where((a) => a.albumType == 'album').toList();
|
||||
final singles = albums.where((a) => a.albumType == 'single').toList();
|
||||
final singles = albums
|
||||
.where((a) => a.albumType == 'single' || a.albumType == 'ep')
|
||||
.toList();
|
||||
|
||||
final totalTracks = albums.fold<int>(0, (sum, a) => sum + a.totalTracks);
|
||||
final albumTracks = albumsOnly.fold<int>(
|
||||
@@ -940,7 +946,7 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||
if (result != null && result['tracks'] != null) {
|
||||
final tracksList = result['tracks'] as List<dynamic>;
|
||||
return tracksList
|
||||
.map((t) => _parseTrack(t as Map<String, dynamic>))
|
||||
.map((t) => _parseTrack(t as Map<String, dynamic>, album: album))
|
||||
.toList();
|
||||
}
|
||||
} else if (album.id.startsWith('deezer:')) {
|
||||
@@ -961,7 +967,7 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||
if (result != null && result['tracks'] != null) {
|
||||
final tracksList = result['tracks'] as List<dynamic>;
|
||||
return tracksList
|
||||
.map((t) => _parseTrack(t as Map<String, dynamic>))
|
||||
.map((t) => _parseTrack(t as Map<String, dynamic>, album: album))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -970,7 +976,7 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||
if (metadata['tracks'] != null) {
|
||||
final tracksList = metadata['tracks'] as List<dynamic>;
|
||||
return tracksList
|
||||
.map((t) => _parseTrack(t as Map<String, dynamic>))
|
||||
.map((t) => _parseTrack(t as Map<String, dynamic>, album: album))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -1004,6 +1010,7 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||
discNumber: data['disk_number'] as int? ?? data['disc_number'] as int?,
|
||||
releaseDate: album.releaseDate,
|
||||
albumType: album.albumType,
|
||||
totalTracks: album.totalTracks,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user