Skip to content

Commit 739ef59

Browse files
authored
Merge pull request #125 from gmcf111/fix/recently-added-sort
fix: incorrect sorting in recently added list
2 parents 72cc90e + c59eb8f commit 739ef59

4 files changed

Lines changed: 59 additions & 3 deletions

File tree

lib/models/song.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Song {
2525
final double? replayGainTrackPeak;
2626
final double? replayGainAlbumPeak;
2727
final List<ArtistRef>? artistParticipants;
28+
final DateTime? created;
2829

2930
Song({
3031
required this.id,
@@ -51,6 +52,7 @@ class Song {
5152
this.replayGainTrackPeak,
5253
this.replayGainAlbumPeak,
5354
this.artistParticipants,
55+
this.created,
5456
});
5557

5658
factory Song.fromJson(Map<String, dynamic> json) {
@@ -81,6 +83,9 @@ class Song {
8183
replayGainTrackPeak: (replayGain?['trackPeak'] as num?)?.toDouble(),
8284
replayGainAlbumPeak: (replayGain?['albumPeak'] as num?)?.toDouble(),
8385
artistParticipants: ArtistRef.parseList(json['artists']),
86+
created: json['created'] != null
87+
? DateTime.tryParse(json['created'].toString())
88+
: null,
8489
);
8590
}
8691

@@ -111,6 +116,7 @@ class Song {
111116
},
112117
if (artistParticipants != null)
113118
'artists': artistParticipants!.map((a) => a.toJson()).toList(),
119+
'created': created?.toIso8601String(),
114120
};
115121
}
116122

@@ -146,6 +152,7 @@ class Song {
146152
double? replayGainTrackPeak,
147153
double? replayGainAlbumPeak,
148154
List<ArtistRef>? artistParticipants,
155+
DateTime? created,
149156
}) {
150157
return Song(
151158
id: id ?? this.id,
@@ -172,6 +179,7 @@ class Song {
172179
replayGainTrackPeak: replayGainTrackPeak ?? this.replayGainTrackPeak,
173180
replayGainAlbumPeak: replayGainAlbumPeak ?? this.replayGainAlbumPeak,
174181
artistParticipants: artistParticipants ?? this.artistParticipants,
182+
created: created ?? this.created,
175183
);
176184
}
177185
}

lib/providers/library_provider.dart

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,34 @@ class LibraryProvider extends ChangeNotifier {
300300
offset += pageSize;
301301
}
302302

303+
final previousAlbums = _cachedAllAlbums;
304+
final previousSongs = _cachedAllSongs;
305+
final Map<String, Song> songById = {};
306+
var failedAlbumLoads = 0;
307+
for (final album in allAlbums) {
308+
try {
309+
final albumSongs = await _subsonicService.getAlbumSongs(album.id);
310+
for (final song in albumSongs) {
311+
songById[song.id] = song;
312+
}
313+
} catch (e) {
314+
failedAlbumLoads++;
315+
debugPrint('Error loading album ${album.id}: $e');
316+
}
317+
}
318+
319+
if (failedAlbumLoads > 0) {
320+
_cachedAllAlbums = previousAlbums;
321+
_cachedAllSongs = previousSongs;
322+
debugPrint(
323+
'Background refresh incomplete: $failedAlbumLoads album(s) failed; keeping previous cache.',
324+
);
325+
notifyListeners();
326+
return;
327+
}
328+
303329
_cachedAllAlbums = allAlbums;
304-
_cachedAllSongs = [];
330+
_cachedAllSongs = songById.values.toList();
305331
_lastCacheUpdate = DateTime.now();
306332

307333
await _saveCachedData();

lib/screens/all_songs_screen.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,14 @@ class _AllSongsScreenState extends State<AllSongsScreen> {
105105
);
106106
break;
107107
case SongSortOption.recentlyAdded:
108-
109-
_sortedSongs = List.from(_songs.reversed);
108+
_sortedSongs.sort((a, b) {
109+
final aCreated = a.created;
110+
final bCreated = b.created;
111+
if (aCreated == null && bCreated == null) return 0;
112+
if (aCreated == null) return 1;
113+
if (bCreated == null) return -1;
114+
return bCreated.compareTo(aCreated);
115+
});
110116
break;
111117
}
112118
}

test/models/song_test.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ void main() {
3333
expect(song.album, isNull);
3434
expect(song.artist, isNull);
3535
expect(song.duration, isNull);
36+
expect(song.created, isNull);
37+
});
38+
39+
test('should parse created field from JSON', () {
40+
final json = {
41+
'id': '123',
42+
'title': 'Test Song',
43+
'created': '2026-03-18T13:37:27.257653751Z',
44+
};
45+
46+
final song = Song.fromJson(json);
47+
48+
expect(song.created, isNotNull);
49+
expect(song.created!.year, 2026);
50+
expect(song.created!.month, 3);
51+
expect(song.created!.day, 18);
3652
});
3753

3854
test('should convert Song to JSON', () {

0 commit comments

Comments
 (0)