mirror of
https://github.com/spotiflacapp/SpotiFLAC-Mobile.git
synced 2026-06-01 03:15:17 +07:00
fix: preserve flat singles output for extension releases
This commit is contained in:
parent
67833424cc
commit
eff709480d
5 changed files with 155 additions and 33 deletions
|
|
@ -2000,6 +2000,33 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||||
state = state.copyWith(outputDir: dir);
|
state = state.copyWith(outputDir: dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _shouldTreatAsSingleRelease(Track track) {
|
||||||
|
if (track.isSingle) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final normalizedAlbumType = normalizeOptionalString(
|
||||||
|
track.albumType,
|
||||||
|
)?.toLowerCase();
|
||||||
|
if (normalizedAlbumType != null && normalizedAlbumType.isNotEmpty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final totalTracks = track.totalTracks;
|
||||||
|
if (totalTracks == 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final normalizedAlbumName = normalizeOptionalString(
|
||||||
|
track.albumName,
|
||||||
|
)?.toLowerCase();
|
||||||
|
if (normalizedAlbumName == 'single' || normalizedAlbumName == 'singles') {
|
||||||
|
return totalTracks == null || totalTracks <= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> _buildOutputDir(
|
Future<String> _buildOutputDir(
|
||||||
Track track,
|
Track track,
|
||||||
String folderOrganization, {
|
String folderOrganization, {
|
||||||
|
|
@ -2036,7 +2063,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (separateSingles) {
|
if (separateSingles) {
|
||||||
final isSingle = track.isSingle;
|
final isSingle = _shouldTreatAsSingleRelease(track);
|
||||||
final artistName = _sanitizeFolderName(folderArtist);
|
final artistName = _sanitizeFolderName(folderArtist);
|
||||||
|
|
||||||
if (albumFolderStructure == 'artist_album_singles') {
|
if (albumFolderStructure == 'artist_album_singles') {
|
||||||
|
|
@ -2215,7 +2242,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (separateSingles) {
|
if (separateSingles) {
|
||||||
final isSingle = track.isSingle;
|
final isSingle = _shouldTreatAsSingleRelease(track);
|
||||||
final artistName = _sanitizeFolderName(folderArtist);
|
final artistName = _sanitizeFolderName(folderArtist);
|
||||||
|
|
||||||
if (albumFolderStructure == 'artist_album_singles') {
|
if (albumFolderStructure == 'artist_album_singles') {
|
||||||
|
|
@ -4137,7 +4164,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||||
String? safBaseName;
|
String? safBaseName;
|
||||||
String safOutputExt = _determineOutputExt(quality, item.service);
|
String safOutputExt = _determineOutputExt(quality, item.service);
|
||||||
if (isSafMode) {
|
if (isSafMode) {
|
||||||
final effectiveFormat = trackToDownload.isSingle
|
final effectiveFormat = _shouldTreatAsSingleRelease(trackToDownload)
|
||||||
? state.singleFilenameFormat
|
? state.singleFilenameFormat
|
||||||
: state.filenameFormat;
|
: state.filenameFormat;
|
||||||
final baseName = await PlatformBridge.buildFilename(effectiveFormat, {
|
final baseName = await PlatformBridge.buildFilename(effectiveFormat, {
|
||||||
|
|
@ -4552,7 +4579,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
||||||
? (trackToDownload.coverUrl ?? '')
|
? (trackToDownload.coverUrl ?? '')
|
||||||
: '',
|
: '',
|
||||||
outputDir: outputDir,
|
outputDir: outputDir,
|
||||||
filenameFormat: trackToDownload.isSingle
|
filenameFormat: _shouldTreatAsSingleRelease(trackToDownload)
|
||||||
? state.singleFilenameFormat
|
? state.singleFilenameFormat
|
||||||
: state.filenameFormat,
|
: state.filenameFormat,
|
||||||
quality: quality,
|
quality: quality,
|
||||||
|
|
|
||||||
|
|
@ -908,7 +908,7 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||||
discNumber: data['disc_number'] as int?,
|
discNumber: data['disc_number'] as int?,
|
||||||
totalDiscs: data['total_discs'] as int?,
|
totalDiscs: data['total_discs'] as int?,
|
||||||
releaseDate: data['release_date'] as String?,
|
releaseDate: data['release_date'] as String?,
|
||||||
albumType: data['album_type'] as String?,
|
albumType: normalizeOptionalString(data['album_type']?.toString()),
|
||||||
totalTracks: data['total_tracks'] as int?,
|
totalTracks: data['total_tracks'] as int?,
|
||||||
composer: data['composer']?.toString(),
|
composer: data['composer']?.toString(),
|
||||||
);
|
);
|
||||||
|
|
@ -945,7 +945,7 @@ class TrackNotifier extends Notifier<TrackState> {
|
||||||
releaseDate: data['release_date']?.toString(),
|
releaseDate: data['release_date']?.toString(),
|
||||||
totalTracks: data['total_tracks'] as int?,
|
totalTracks: data['total_tracks'] as int?,
|
||||||
source: effectiveSource,
|
source: effectiveSource,
|
||||||
albumType: data['album_type']?.toString(),
|
albumType: normalizeOptionalString(data['album_type']?.toString()),
|
||||||
composer: data['composer']?.toString(),
|
composer: data['composer']?.toString(),
|
||||||
itemType: itemType,
|
itemType: itemType,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,8 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
String? _error;
|
String? _error;
|
||||||
bool _showTitleInAppBar = false;
|
bool _showTitleInAppBar = false;
|
||||||
String? _artistId;
|
String? _artistId;
|
||||||
|
String? _albumType;
|
||||||
|
int? _albumTotalTracks;
|
||||||
final ScrollController _scrollController = ScrollController();
|
final ScrollController _scrollController = ScrollController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -112,6 +114,8 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
_tracks = _AlbumCache.get(widget.albumId);
|
_tracks = _AlbumCache.get(widget.albumId);
|
||||||
}
|
}
|
||||||
_artistId = widget.artistId;
|
_artistId = widget.artistId;
|
||||||
|
_albumType = _tracks?.firstOrNull?.albumType;
|
||||||
|
_albumTotalTracks = _tracks?.firstOrNull?.totalTracks;
|
||||||
|
|
||||||
if (_tracks == null || _tracks!.isEmpty) {
|
if (_tracks == null || _tracks!.isEmpty) {
|
||||||
_fetchTracks();
|
_fetchTracks();
|
||||||
|
|
@ -179,13 +183,22 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
deezerAlbumId,
|
deezerAlbumId,
|
||||||
);
|
);
|
||||||
final trackList = metadata['track_list'] as List<dynamic>;
|
final trackList = metadata['track_list'] as List<dynamic>;
|
||||||
final tracks = trackList
|
|
||||||
.map((t) => _parseTrack(t as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final albumInfo = metadata['album_info'] as Map<String, dynamic>?;
|
final albumInfo = metadata['album_info'] as Map<String, dynamic>?;
|
||||||
final artistId = (albumInfo?['artist_id'] ?? albumInfo?['artistId'])
|
final artistId = (albumInfo?['artist_id'] ?? albumInfo?['artistId'])
|
||||||
?.toString();
|
?.toString();
|
||||||
|
final albumType = normalizeOptionalString(
|
||||||
|
albumInfo?['album_type']?.toString(),
|
||||||
|
);
|
||||||
|
final totalTracks = albumInfo?['total_tracks'] as int?;
|
||||||
|
final tracks = trackList
|
||||||
|
.map(
|
||||||
|
(t) => _parseTrack(
|
||||||
|
t as Map<String, dynamic>,
|
||||||
|
albumTypeFallback: albumType,
|
||||||
|
totalTracksFallback: totalTracks,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
_AlbumCache.set(widget.albumId, tracks);
|
_AlbumCache.set(widget.albumId, tracks);
|
||||||
|
|
||||||
|
|
@ -193,6 +206,8 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_tracks = tracks;
|
_tracks = tracks;
|
||||||
_artistId = artistId;
|
_artistId = artistId;
|
||||||
|
_albumType = albumType;
|
||||||
|
_albumTotalTracks = totalTracks;
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -204,13 +219,22 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
qobuzAlbumId,
|
qobuzAlbumId,
|
||||||
);
|
);
|
||||||
final trackList = metadata['track_list'] as List<dynamic>;
|
final trackList = metadata['track_list'] as List<dynamic>;
|
||||||
final tracks = trackList
|
|
||||||
.map((t) => _parseTrack(t as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final albumInfo = metadata['album_info'] as Map<String, dynamic>?;
|
final albumInfo = metadata['album_info'] as Map<String, dynamic>?;
|
||||||
final artistId = (albumInfo?['artist_id'] ?? albumInfo?['artistId'])
|
final artistId = (albumInfo?['artist_id'] ?? albumInfo?['artistId'])
|
||||||
?.toString();
|
?.toString();
|
||||||
|
final albumType = normalizeOptionalString(
|
||||||
|
albumInfo?['album_type']?.toString(),
|
||||||
|
);
|
||||||
|
final totalTracks = albumInfo?['total_tracks'] as int?;
|
||||||
|
final tracks = trackList
|
||||||
|
.map(
|
||||||
|
(t) => _parseTrack(
|
||||||
|
t as Map<String, dynamic>,
|
||||||
|
albumTypeFallback: albumType,
|
||||||
|
totalTracksFallback: totalTracks,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
_AlbumCache.set(widget.albumId, tracks);
|
_AlbumCache.set(widget.albumId, tracks);
|
||||||
|
|
||||||
|
|
@ -218,6 +242,8 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_tracks = tracks;
|
_tracks = tracks;
|
||||||
_artistId = artistId;
|
_artistId = artistId;
|
||||||
|
_albumType = albumType;
|
||||||
|
_albumTotalTracks = totalTracks;
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -229,13 +255,22 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
tidalAlbumId,
|
tidalAlbumId,
|
||||||
);
|
);
|
||||||
final trackList = metadata['track_list'] as List<dynamic>;
|
final trackList = metadata['track_list'] as List<dynamic>;
|
||||||
final tracks = trackList
|
|
||||||
.map((t) => _parseTrack(t as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final albumInfo = metadata['album_info'] as Map<String, dynamic>?;
|
final albumInfo = metadata['album_info'] as Map<String, dynamic>?;
|
||||||
final artistId = (albumInfo?['artist_id'] ?? albumInfo?['artistId'])
|
final artistId = (albumInfo?['artist_id'] ?? albumInfo?['artistId'])
|
||||||
?.toString();
|
?.toString();
|
||||||
|
final albumType = normalizeOptionalString(
|
||||||
|
albumInfo?['album_type']?.toString(),
|
||||||
|
);
|
||||||
|
final totalTracks = albumInfo?['total_tracks'] as int?;
|
||||||
|
final tracks = trackList
|
||||||
|
.map(
|
||||||
|
(t) => _parseTrack(
|
||||||
|
t as Map<String, dynamic>,
|
||||||
|
albumTypeFallback: albumType,
|
||||||
|
totalTracksFallback: totalTracks,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
_AlbumCache.set(widget.albumId, tracks);
|
_AlbumCache.set(widget.albumId, tracks);
|
||||||
|
|
||||||
|
|
@ -243,6 +278,8 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_tracks = tracks;
|
_tracks = tracks;
|
||||||
_artistId = artistId;
|
_artistId = artistId;
|
||||||
|
_albumType = albumType;
|
||||||
|
_albumTotalTracks = totalTracks;
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -255,13 +292,22 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
}
|
}
|
||||||
|
|
||||||
final trackList = result['tracks'] as List<dynamic>;
|
final trackList = result['tracks'] as List<dynamic>;
|
||||||
final tracks = trackList
|
|
||||||
.map((t) => _parseTrack(t as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final albumInfo = result['album'] as Map<String, dynamic>?;
|
final albumInfo = result['album'] as Map<String, dynamic>?;
|
||||||
final artistId = (albumInfo?['artist_id'] ?? albumInfo?['artistId'])
|
final artistId = (albumInfo?['artist_id'] ?? albumInfo?['artistId'])
|
||||||
?.toString();
|
?.toString();
|
||||||
|
final albumType = normalizeOptionalString(
|
||||||
|
albumInfo?['album_type']?.toString(),
|
||||||
|
);
|
||||||
|
final totalTracks = albumInfo?['total_tracks'] as int?;
|
||||||
|
final tracks = trackList
|
||||||
|
.map(
|
||||||
|
(t) => _parseTrack(
|
||||||
|
t as Map<String, dynamic>,
|
||||||
|
albumTypeFallback: albumType,
|
||||||
|
totalTracksFallback: totalTracks,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
_AlbumCache.set(widget.albumId, tracks);
|
_AlbumCache.set(widget.albumId, tracks);
|
||||||
|
|
||||||
|
|
@ -269,6 +315,8 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_tracks = tracks;
|
_tracks = tracks;
|
||||||
_artistId = artistId;
|
_artistId = artistId;
|
||||||
|
_albumType = albumType;
|
||||||
|
_albumTotalTracks = totalTracks;
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +332,11 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Track _parseTrack(Map<String, dynamic> data) {
|
Track _parseTrack(
|
||||||
|
Map<String, dynamic> data, {
|
||||||
|
String? albumTypeFallback,
|
||||||
|
int? totalTracksFallback,
|
||||||
|
}) {
|
||||||
return Track(
|
return Track(
|
||||||
id: data['spotify_id'] as String? ?? '',
|
id: data['spotify_id'] as String? ?? '',
|
||||||
name: data['name'] as String? ?? '',
|
name: data['name'] as String? ?? '',
|
||||||
|
|
@ -301,8 +353,14 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
|
||||||
discNumber: data['disc_number'] as int?,
|
discNumber: data['disc_number'] as int?,
|
||||||
totalDiscs: data['total_discs'] as int?,
|
totalDiscs: data['total_discs'] as int?,
|
||||||
releaseDate: data['release_date'] as String?,
|
releaseDate: data['release_date'] as String?,
|
||||||
albumType: data['album_type'] as String?,
|
albumType:
|
||||||
totalTracks: data['total_tracks'] as int?,
|
normalizeOptionalString(data['album_type']?.toString()) ??
|
||||||
|
albumTypeFallback ??
|
||||||
|
_albumType,
|
||||||
|
totalTracks:
|
||||||
|
data['total_tracks'] as int? ??
|
||||||
|
totalTracksFallback ??
|
||||||
|
_albumTotalTracks,
|
||||||
composer: data['composer']?.toString(),
|
composer: data['composer']?.toString(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -412,7 +412,9 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||||
discNumber: data['disc_number'] as int?,
|
discNumber: data['disc_number'] as int?,
|
||||||
totalDiscs: data['total_discs'] as int?,
|
totalDiscs: data['total_discs'] as int?,
|
||||||
releaseDate: data['release_date']?.toString(),
|
releaseDate: data['release_date']?.toString(),
|
||||||
albumType: data['album_type']?.toString() ?? album?.albumType,
|
albumType:
|
||||||
|
normalizeOptionalString(data['album_type']?.toString()) ??
|
||||||
|
album?.albumType,
|
||||||
totalTracks: data['total_tracks'] as int? ?? album?.totalTracks,
|
totalTracks: data['total_tracks'] as int? ?? album?.totalTracks,
|
||||||
composer: data['composer']?.toString(),
|
composer: data['composer']?.toString(),
|
||||||
source: data['provider_id']?.toString() ?? widget.extensionId,
|
source: data['provider_id']?.toString() ?? widget.extensionId,
|
||||||
|
|
@ -1057,9 +1059,10 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||||
);
|
);
|
||||||
if (result != null && result['tracks'] != null) {
|
if (result != null && result['tracks'] != null) {
|
||||||
final tracksList = result['tracks'] as List<dynamic>;
|
final tracksList = result['tracks'] as List<dynamic>;
|
||||||
return tracksList
|
final parsedTracks = tracksList
|
||||||
.map((t) => _parseTrack(t as Map<String, dynamic>, album: album))
|
.map((t) => _parseTrack(t as Map<String, dynamic>, album: album))
|
||||||
.toList();
|
.toList();
|
||||||
|
return parsedTracks;
|
||||||
}
|
}
|
||||||
} else if (album.id.startsWith('deezer:')) {
|
} else if (album.id.startsWith('deezer:')) {
|
||||||
final deezerId = album.id.replaceFirst('deezer:', '');
|
final deezerId = album.id.replaceFirst('deezer:', '');
|
||||||
|
|
@ -1934,6 +1937,8 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
|
||||||
albumId: album.id,
|
albumId: album.id,
|
||||||
albumName: album.name,
|
albumName: album.name,
|
||||||
coverUrl: album.coverUrl,
|
coverUrl: album.coverUrl,
|
||||||
|
initialAlbumType: album.albumType,
|
||||||
|
initialTotalTracks: album.totalTracks,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3031,6 +3031,8 @@ class _HomeTabState extends ConsumerState<HomeTab>
|
||||||
albumId: albumItem.id,
|
albumId: albumItem.id,
|
||||||
albumName: albumItem.name,
|
albumName: albumItem.name,
|
||||||
coverUrl: albumItem.coverUrl,
|
coverUrl: albumItem.coverUrl,
|
||||||
|
initialAlbumType: albumItem.albumType,
|
||||||
|
initialTotalTracks: albumItem.totalTracks,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -4315,6 +4317,8 @@ class ExtensionAlbumScreen extends ConsumerStatefulWidget {
|
||||||
final String albumId;
|
final String albumId;
|
||||||
final String albumName;
|
final String albumName;
|
||||||
final String? coverUrl;
|
final String? coverUrl;
|
||||||
|
final String? initialAlbumType;
|
||||||
|
final int? initialTotalTracks;
|
||||||
|
|
||||||
const ExtensionAlbumScreen({
|
const ExtensionAlbumScreen({
|
||||||
super.key,
|
super.key,
|
||||||
|
|
@ -4322,6 +4326,8 @@ class ExtensionAlbumScreen extends ConsumerStatefulWidget {
|
||||||
required this.albumId,
|
required this.albumId,
|
||||||
required this.albumName,
|
required this.albumName,
|
||||||
this.coverUrl,
|
this.coverUrl,
|
||||||
|
this.initialAlbumType,
|
||||||
|
this.initialTotalTracks,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -4335,10 +4341,14 @@ class _ExtensionAlbumScreenState extends ConsumerState<ExtensionAlbumScreen> {
|
||||||
String? _error;
|
String? _error;
|
||||||
String? _artistId;
|
String? _artistId;
|
||||||
String? _artistName;
|
String? _artistName;
|
||||||
|
String? _albumType;
|
||||||
|
int? _albumTotalTracks;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_albumType = normalizeOptionalString(widget.initialAlbumType);
|
||||||
|
_albumTotalTracks = widget.initialTotalTracks;
|
||||||
_fetchTracks();
|
_fetchTracks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4372,17 +4382,28 @@ class _ExtensionAlbumScreenState extends ConsumerState<ExtensionAlbumScreen> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final tracks = trackList
|
|
||||||
.map((t) => _parseTrack(t as Map<String, dynamic>))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final artistId = (result['artist_id'] ?? result['artistId'])?.toString();
|
final artistId = (result['artist_id'] ?? result['artistId'])?.toString();
|
||||||
final artistName = result['artists'] as String?;
|
final artistName = result['artists'] as String?;
|
||||||
|
final albumType =
|
||||||
|
normalizeOptionalString(result['album_type']?.toString()) ??
|
||||||
|
_albumType;
|
||||||
|
final totalTracks = result['total_tracks'] as int? ?? _albumTotalTracks;
|
||||||
|
final tracks = trackList
|
||||||
|
.map(
|
||||||
|
(t) => _parseTrack(
|
||||||
|
t as Map<String, dynamic>,
|
||||||
|
albumTypeFallback: albumType,
|
||||||
|
totalTracksFallback: totalTracks,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_tracks = tracks;
|
_tracks = tracks;
|
||||||
_artistId = artistId;
|
_artistId = artistId;
|
||||||
_artistName = artistName;
|
_artistName = artistName;
|
||||||
|
_albumType = albumType;
|
||||||
|
_albumTotalTracks = totalTracks;
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -4394,7 +4415,11 @@ class _ExtensionAlbumScreenState extends ConsumerState<ExtensionAlbumScreen> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Track _parseTrack(Map<String, dynamic> data) {
|
Track _parseTrack(
|
||||||
|
Map<String, dynamic> data, {
|
||||||
|
String? albumTypeFallback,
|
||||||
|
int? totalTracksFallback,
|
||||||
|
}) {
|
||||||
int durationMs = 0;
|
int durationMs = 0;
|
||||||
final durationValue = data['duration_ms'];
|
final durationValue = data['duration_ms'];
|
||||||
if (durationValue is int) {
|
if (durationValue is int) {
|
||||||
|
|
@ -4422,7 +4447,14 @@ class _ExtensionAlbumScreenState extends ConsumerState<ExtensionAlbumScreen> {
|
||||||
discNumber: data['disc_number'] as int?,
|
discNumber: data['disc_number'] as int?,
|
||||||
totalDiscs: data['total_discs'] as int?,
|
totalDiscs: data['total_discs'] as int?,
|
||||||
releaseDate: data['release_date']?.toString(),
|
releaseDate: data['release_date']?.toString(),
|
||||||
totalTracks: data['total_tracks'] as int?,
|
albumType:
|
||||||
|
normalizeOptionalString(data['album_type']?.toString()) ??
|
||||||
|
albumTypeFallback ??
|
||||||
|
_albumType,
|
||||||
|
totalTracks:
|
||||||
|
data['total_tracks'] as int? ??
|
||||||
|
totalTracksFallback ??
|
||||||
|
_albumTotalTracks,
|
||||||
composer: data['composer']?.toString(),
|
composer: data['composer']?.toString(),
|
||||||
source: widget.extensionId,
|
source: widget.extensionId,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue