fix #59
This commit is contained in:
parent
589cfef5ce
commit
fce520abc7
3 changed files with 70 additions and 109 deletions
|
@ -5,3 +5,4 @@
|
||||||
- Calculate album colors during library update and store them for better performance
|
- Calculate album colors during library update and store them for better performance
|
||||||
- Fix bug with smart lists in history entries
|
- Fix bug with smart lists in history entries
|
||||||
- Added logging to files
|
- Added logging to files
|
||||||
|
- Implement natural sorting for album songs (#59)
|
||||||
|
|
|
@ -31,29 +31,23 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<List<SongModel>> get songStream {
|
Stream<List<SongModel>> get songStream {
|
||||||
return (select(songs)..orderBy([(t) => OrderingTerm(expression: t.title)]))
|
return (select(songs)..orderBy([(t) => OrderingTerm(expression: t.title)])).watch().map(
|
||||||
.watch()
|
(driftSongList) =>
|
||||||
.map((driftSongList) => driftSongList
|
driftSongList.map((driftSong) => SongModel.fromDrift(driftSong)).toList());
|
||||||
.map((driftSong) => SongModel.fromDrift(driftSong))
|
|
||||||
.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<List<AlbumModel>> get albumStream {
|
Stream<List<AlbumModel>> get albumStream {
|
||||||
return (select(albums)..orderBy([(t) => OrderingTerm(expression: t.title)]))
|
return (select(albums)..orderBy([(t) => OrderingTerm(expression: t.title)])).watch().map(
|
||||||
.watch()
|
(driftAlbumList) =>
|
||||||
.map((driftAlbumList) => driftAlbumList
|
driftAlbumList.map((driftAlbum) => AlbumModel.fromDrift(driftAlbum)).toList());
|
||||||
.map((driftAlbum) => AlbumModel.fromDrift(driftAlbum))
|
|
||||||
.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<List<ArtistModel>> get artistStream {
|
Stream<List<ArtistModel>> get artistStream {
|
||||||
return (select(artists)..orderBy([(t) => OrderingTerm(expression: t.name)]))
|
return (select(artists)..orderBy([(t) => OrderingTerm(expression: t.name)])).watch().map(
|
||||||
.watch()
|
(driftArtistList) =>
|
||||||
.map((driftArtistList) => driftArtistList
|
driftArtistList.map((driftArtist) => ArtistModel.fromDrift(driftArtist)).toList());
|
||||||
.map((driftArtist) => ArtistModel.fromDrift(driftArtist))
|
|
||||||
.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -62,28 +56,22 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
..where((tbl) => tbl.albumId.equals(album.id))
|
..where((tbl) => tbl.albumId.equals(album.id))
|
||||||
..orderBy([
|
..orderBy([
|
||||||
(t) => OrderingTerm(expression: t.discNumber),
|
(t) => OrderingTerm(expression: t.discNumber),
|
||||||
(t) => OrderingTerm(expression: t.trackNumber)
|
(t) => OrderingTerm(expression: t.trackNumber),
|
||||||
]))
|
|
||||||
.watch()
|
|
||||||
.distinct(const ListEquality().equals)
|
|
||||||
.map((driftSongList) => driftSongList
|
|
||||||
.map((driftSong) => SongModel.fromDrift(driftSong))
|
|
||||||
.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<List<AlbumModel>> getArtistAlbumStream(ArtistModel artist) {
|
|
||||||
return (select(albums)
|
|
||||||
..where((tbl) => tbl.artist.equals(artist.name))
|
|
||||||
..orderBy([
|
|
||||||
(t) => OrderingTerm(expression: t.title),
|
(t) => OrderingTerm(expression: t.title),
|
||||||
]))
|
]))
|
||||||
.watch()
|
.watch()
|
||||||
.distinct(const ListEquality().equals)
|
.distinct(const ListEquality().equals)
|
||||||
|
.map((driftSongList) =>
|
||||||
|
driftSongList.map((driftSong) => SongModel.fromDrift(driftSong)).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<List<AlbumModel>> getArtistAlbumStream(ArtistModel artist) {
|
||||||
|
return (select(albums)..where((tbl) => tbl.artist.equals(artist.name)))
|
||||||
|
.watch()
|
||||||
|
.distinct(const ListEquality().equals)
|
||||||
.map((driftAlbumList) {
|
.map((driftAlbumList) {
|
||||||
return driftAlbumList
|
return driftAlbumList.map((driftAlbum) => AlbumModel.fromDrift(driftAlbum)).toList();
|
||||||
.map((driftAlbum) => AlbumModel.fromDrift(driftAlbum))
|
|
||||||
.toList();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,17 +83,14 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
.watch()
|
.watch()
|
||||||
.distinct(const ListEquality().equals)
|
.distinct(const ListEquality().equals)
|
||||||
.map(
|
.map(
|
||||||
(driftSongList) => driftSongList
|
(driftSongList) =>
|
||||||
.map((driftSong) => SongModel.fromDrift(driftSong))
|
driftSongList.map((driftSong) => SongModel.fromDrift(driftSong)).toList(),
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<SongModel?> getSongByPath(String path) async {
|
Future<SongModel?> getSongByPath(String path) async {
|
||||||
return (select(songs)..where((t) => t.path.equals(path)))
|
return (select(songs)..where((t) => t.path.equals(path))).getSingleOrNull().then(
|
||||||
.getSingleOrNull()
|
|
||||||
.then(
|
|
||||||
(driftSong) => driftSong == null ? null : SongModel.fromDrift(driftSong),
|
(driftSong) => driftSong == null ? null : SongModel.fromDrift(driftSong),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -135,12 +120,9 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
deletedSongs.addAll(await (select(songs)
|
deletedSongs.addAll(await (select(songs)..where((tbl) => tbl.present.equals(false))).get().then(
|
||||||
..where((tbl) => tbl.present.equals(false)))
|
(driftSongList) =>
|
||||||
.get()
|
driftSongList.map((driftSong) => SongModel.fromDrift(driftSong)).toList()));
|
||||||
.then((driftSongList) => driftSongList
|
|
||||||
.map((driftSong) => SongModel.fromDrift(driftSong))
|
|
||||||
.toList()));
|
|
||||||
|
|
||||||
await (delete(songs)..where((tbl) => tbl.present.equals(false))).go();
|
await (delete(songs)..where((tbl) => tbl.present.equals(false))).go();
|
||||||
|
|
||||||
|
@ -187,9 +169,8 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
(t) => OrderingTerm(expression: t.trackNumber)
|
(t) => OrderingTerm(expression: t.trackNumber)
|
||||||
]))
|
]))
|
||||||
.get()
|
.get()
|
||||||
.then((driftSongList) => driftSongList
|
.then((driftSongList) =>
|
||||||
.map((driftSong) => SongModel.fromDrift(driftSong))
|
driftSongList.map((driftSong) => SongModel.fromDrift(driftSong)).toList());
|
||||||
.toList());
|
|
||||||
|
|
||||||
SongModel? prevSong;
|
SongModel? prevSong;
|
||||||
for (final s in albumSongs) {
|
for (final s in albumSongs) {
|
||||||
|
@ -210,9 +191,8 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
(t) => OrderingTerm(expression: t.trackNumber)
|
(t) => OrderingTerm(expression: t.trackNumber)
|
||||||
]))
|
]))
|
||||||
.get()
|
.get()
|
||||||
.then((driftSongList) => driftSongList
|
.then((driftSongList) =>
|
||||||
.map((driftSong) => SongModel.fromDrift(driftSong))
|
driftSongList.map((driftSong) => SongModel.fromDrift(driftSong)).toList());
|
||||||
.toList());
|
|
||||||
|
|
||||||
bool current = false;
|
bool current = false;
|
||||||
SongModel? nextSong;
|
SongModel? nextSong;
|
||||||
|
@ -231,15 +211,13 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
@override
|
@override
|
||||||
Future<void> updateSongs(List<SongModel> songModels) async {
|
Future<void> updateSongs(List<SongModel> songModels) async {
|
||||||
await batch((batch) {
|
await batch((batch) {
|
||||||
batch.replaceAll(
|
batch.replaceAll(songs, songModels.map((e) => e.toSongsCompanion()).toList());
|
||||||
songs, songModels.map((e) => e.toSongsCompanion()).toList());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<AlbumOfDay?> getAlbumOfDay() async {
|
Future<AlbumOfDay?> getAlbumOfDay() async {
|
||||||
final value = await (select(keyValueEntries)
|
final value = await (select(keyValueEntries)..where((tbl) => tbl.key.equals(ALBUM_OF_DAY)))
|
||||||
..where((tbl) => tbl.key.equals(ALBUM_OF_DAY)))
|
|
||||||
.getSingleOrNull()
|
.getSingleOrNull()
|
||||||
.then((entry) => entry?.value);
|
.then((entry) => entry?.value);
|
||||||
|
|
||||||
|
@ -252,15 +230,13 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
final int id = dict['id'] as int;
|
final int id = dict['id'] as int;
|
||||||
final int millisecondsSinceEpoch = dict['date'] as int;
|
final int millisecondsSinceEpoch = dict['date'] as int;
|
||||||
|
|
||||||
final AlbumModel? album = await (select(albums)
|
final AlbumModel? album = await (select(albums)..where((tbl) => tbl.id.equals(id)))
|
||||||
..where((tbl) => tbl.id.equals(id)))
|
|
||||||
.getSingleOrNull()
|
.getSingleOrNull()
|
||||||
.then((value) => value == null ? null : AlbumModel.fromDrift(value));
|
.then((value) => value == null ? null : AlbumModel.fromDrift(value));
|
||||||
|
|
||||||
if (album == null) return null;
|
if (album == null) return null;
|
||||||
|
|
||||||
return AlbumOfDay(
|
return AlbumOfDay(album, DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch));
|
||||||
album, DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -275,8 +251,7 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ArtistOfDay?> getArtistOfDay() async {
|
Future<ArtistOfDay?> getArtistOfDay() async {
|
||||||
final value = await (select(keyValueEntries)
|
final value = await (select(keyValueEntries)..where((tbl) => tbl.key.equals(ARTIST_OF_DAY)))
|
||||||
..where((tbl) => tbl.key.equals(ARTIST_OF_DAY)))
|
|
||||||
.getSingleOrNull()
|
.getSingleOrNull()
|
||||||
.then((entry) => entry?.value);
|
.then((entry) => entry?.value);
|
||||||
|
|
||||||
|
@ -289,15 +264,13 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
final int id = dict['id'] as int;
|
final int id = dict['id'] as int;
|
||||||
final int millisecondsSinceEpoch = dict['date'] as int;
|
final int millisecondsSinceEpoch = dict['date'] as int;
|
||||||
|
|
||||||
final ArtistModel? artist = await (select(artists)
|
final ArtistModel? artist = await (select(artists)..where((tbl) => tbl.id.equals(id)))
|
||||||
..where((tbl) => tbl.id.equals(id)))
|
|
||||||
.getSingleOrNull()
|
.getSingleOrNull()
|
||||||
.then((value) => value == null ? null : ArtistModel.fromDrift(value));
|
.then((value) => value == null ? null : ArtistModel.fromDrift(value));
|
||||||
|
|
||||||
if (artist == null) return null;
|
if (artist == null) return null;
|
||||||
|
|
||||||
return ArtistOfDay(
|
return ArtistOfDay(artist, DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch));
|
||||||
artist, DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -313,13 +286,10 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
@override
|
@override
|
||||||
Future<List<AlbumModel>> searchAlbums(String searchText, {int? limit}) async {
|
Future<List<AlbumModel>> searchAlbums(String searchText, {int? limit}) async {
|
||||||
final List<AlbumModel> result = await (select(albums)
|
final List<AlbumModel> result = await (select(albums)
|
||||||
..where((tbl) =>
|
..where((tbl) => tbl.title.regexp(searchText, dotAll: true, caseSensitive: false)))
|
||||||
tbl.title.regexp(searchText, dotAll: true, caseSensitive: false)))
|
|
||||||
.get()
|
.get()
|
||||||
.then(
|
.then(
|
||||||
(driftList) => driftList
|
(driftList) => driftList.map((driftAlbum) => AlbumModel.fromDrift(driftAlbum)).toList(),
|
||||||
.map((driftAlbum) => AlbumModel.fromDrift(driftAlbum))
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
|
@ -330,16 +300,13 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<ArtistModel>> searchArtists(String searchText,
|
Future<List<ArtistModel>> searchArtists(String searchText, {int? limit}) async {
|
||||||
{int? limit}) async {
|
|
||||||
final List<ArtistModel> result = await (select(artists)
|
final List<ArtistModel> result = await (select(artists)
|
||||||
..where((tbl) =>
|
..where((tbl) => tbl.name.regexp(searchText, dotAll: true, caseSensitive: false)))
|
||||||
tbl.name.regexp(searchText, dotAll: true, caseSensitive: false)))
|
|
||||||
.get()
|
.get()
|
||||||
.then(
|
.then(
|
||||||
(driftList) => driftList
|
(driftList) =>
|
||||||
.map((driftArtist) => ArtistModel.fromDrift(driftArtist))
|
driftList.map((driftArtist) => ArtistModel.fromDrift(driftArtist)).toList(),
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
|
@ -352,13 +319,10 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
@override
|
@override
|
||||||
Future<List<SongModel>> searchSongs(String searchText, {int? limit}) async {
|
Future<List<SongModel>> searchSongs(String searchText, {int? limit}) async {
|
||||||
final List<SongModel> result = await (select(songs)
|
final List<SongModel> result = await (select(songs)
|
||||||
..where((tbl) =>
|
..where((tbl) => tbl.title.regexp(searchText, dotAll: true, caseSensitive: false)))
|
||||||
tbl.title.regexp(searchText, dotAll: true, caseSensitive: false)))
|
|
||||||
.get()
|
.get()
|
||||||
.then(
|
.then(
|
||||||
(driftList) => driftList
|
(driftList) => driftList.map((driftSong) => SongModel.fromDrift(driftSong)).toList(),
|
||||||
.map((driftSong) => SongModel.fromDrift(driftSong))
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
|
@ -370,10 +334,7 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<SongModel> getSongStream(String path) {
|
Stream<SongModel> getSongStream(String path) {
|
||||||
return (select(songs)..where((t) => t.path.equals(path)))
|
return (select(songs)..where((t) => t.path.equals(path))).watchSingle().distinct().map(
|
||||||
.watchSingle()
|
|
||||||
.distinct()
|
|
||||||
.map(
|
|
||||||
(driftSong) => SongModel.fromDrift(driftSong),
|
(driftSong) => SongModel.fromDrift(driftSong),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -409,8 +370,7 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
);
|
);
|
||||||
|
|
||||||
// delete songs
|
// delete songs
|
||||||
batch.deleteWhere<$SongsTable, dynamic>(
|
batch.deleteWhere<$SongsTable, dynamic>(songs, (tbl) => tbl.path.isIn(paths));
|
||||||
songs, (tbl) => tbl.path.isIn(paths));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// delete empty albums
|
// delete empty albums
|
||||||
|
@ -422,9 +382,7 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
|
|
||||||
// Delete empty albums and all their database appearances.
|
// Delete empty albums and all their database appearances.
|
||||||
Future<void> _deleteAlbumIfEmpty(int albumId) async {
|
Future<void> _deleteAlbumIfEmpty(int albumId) async {
|
||||||
final aSongs = await (select(songs)
|
final aSongs = await (select(songs)..where((tbl) => tbl.albumId.equals(albumId))).get();
|
||||||
..where((tbl) => tbl.albumId.equals(albumId)))
|
|
||||||
.get();
|
|
||||||
if (aSongs.isEmpty) {
|
if (aSongs.isEmpty) {
|
||||||
await (delete(albums)..where((tbl) => tbl.id.equals(albumId))).go();
|
await (delete(albums)..where((tbl) => tbl.id.equals(albumId))).go();
|
||||||
// delete history entries with this album
|
// delete history entries with this album
|
||||||
|
@ -438,15 +396,11 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
|
|
||||||
// Delete empty artists and all their database appearances.
|
// Delete empty artists and all their database appearances.
|
||||||
Future<void> _deleteArtistIfEmpty(String name) async {
|
Future<void> _deleteArtistIfEmpty(String name) async {
|
||||||
final aAlbums =
|
final aAlbums = await (select(albums)..where((tbl) => tbl.artist.equals(name))).get();
|
||||||
await (select(albums)..where((tbl) => tbl.artist.equals(name))).get();
|
|
||||||
if (aAlbums.isEmpty) {
|
if (aAlbums.isEmpty) {
|
||||||
final emptyArtists =
|
final emptyArtists = await (select(artists)..where((tbl) => tbl.name.equals(name))).get();
|
||||||
await (select(artists)..where((tbl) => tbl.name.equals(name))).get();
|
|
||||||
await (delete(artists)..where((tbl) => tbl.name.equals(name))).go();
|
await (delete(artists)..where((tbl) => tbl.name.equals(name))).go();
|
||||||
await (delete(smartListArtists)
|
await (delete(smartListArtists)..where((tbl) => tbl.artistName.equals(name))).go();
|
||||||
..where((tbl) => tbl.artistName.equals(name)))
|
|
||||||
.go();
|
|
||||||
|
|
||||||
for (final emptyArtist in emptyArtists) {
|
for (final emptyArtist in emptyArtists) {
|
||||||
(delete(historyEntries)
|
(delete(historyEntries)
|
||||||
|
@ -459,15 +413,13 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<Set<String>> get blockedFilesStream => select(blockedFiles)
|
Stream<Set<String>> get blockedFilesStream =>
|
||||||
.watch()
|
select(blockedFiles).watch().map((value) => value.map((e) => e.path).toSet());
|
||||||
.map((value) => value.map((e) => e.path).toSet());
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> removeBlockedFiles(List<String> paths) async {
|
Future<void> removeBlockedFiles(List<String> paths) async {
|
||||||
await batch((batch) {
|
await batch((batch) {
|
||||||
batch.deleteWhere<$BlockedFilesTable, dynamic>(
|
batch.deleteWhere<$BlockedFilesTable, dynamic>(blockedFiles, (tbl) => tbl.path.isIn(paths));
|
||||||
blockedFiles, (tbl) => tbl.path.isIn(paths));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,9 +432,7 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
|
|
||||||
// delete history entries with missing album
|
// delete history entries with missing album
|
||||||
for (final entry in albumHistoryEntries) {
|
for (final entry in albumHistoryEntries) {
|
||||||
if ((await (select(albums)
|
if ((await (select(albums)..where((tbl) => tbl.id.equals(int.parse(entry.identifier)))).get())
|
||||||
..where((tbl) => tbl.id.equals(int.parse(entry.identifier))))
|
|
||||||
.get())
|
|
||||||
.isEmpty) {
|
.isEmpty) {
|
||||||
(delete(historyEntries)
|
(delete(historyEntries)
|
||||||
..where((tbl) =>
|
..where((tbl) =>
|
||||||
|
@ -499,8 +449,7 @@ class MusicDataDao extends DatabaseAccessor<MainDatabase>
|
||||||
|
|
||||||
// delete history entries with missing album
|
// delete history entries with missing album
|
||||||
for (final entry in artistHistoryEntries) {
|
for (final entry in artistHistoryEntries) {
|
||||||
if ((await (select(artists)
|
if ((await (select(artists)..where((tbl) => tbl.id.equals(int.parse(entry.identifier))))
|
||||||
..where((tbl) => tbl.id.equals(int.parse(entry.identifier))))
|
|
||||||
.get())
|
.get())
|
||||||
.isEmpty) {
|
.isEmpty) {
|
||||||
(delete(historyEntries)
|
(delete(historyEntries)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:fimber/fimber.dart';
|
import 'package:fimber/fimber.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
import 'package:string_similarity/string_similarity.dart';
|
import 'package:string_similarity/string_similarity.dart';
|
||||||
|
@ -83,8 +84,9 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
||||||
Stream<List<String>> get songRemovalStream => _songRemovalSubject.stream;
|
Stream<List<String>> get songRemovalStream => _songRemovalSubject.stream;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<List<Song>> getAlbumSongStream(Album album) =>
|
Stream<List<Song>> getAlbumSongStream(Album album) => _musicDataSource
|
||||||
_musicDataSource.getAlbumSongStream(album as AlbumModel);
|
.getAlbumSongStream(album as AlbumModel)
|
||||||
|
.map((songs) => _sortAlbumSongs(songs));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<List<Song>> getArtistSongStream(Artist artist) =>
|
Stream<List<Song>> getArtistSongStream(Artist artist) =>
|
||||||
|
@ -248,6 +250,15 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Song> _sortAlbumSongs(List<Song> songs) {
|
||||||
|
return songs
|
||||||
|
..sort((a, b) {
|
||||||
|
if (a.discNumber != b.discNumber) return a.discNumber.compareTo(b.discNumber);
|
||||||
|
if (a.trackNumber != b.trackNumber) return a.trackNumber.compareTo(b.trackNumber);
|
||||||
|
return compareNatural(a.title, b.title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
List<Album> _sortArtistAlbums(List<Album> albums) {
|
List<Album> _sortArtistAlbums(List<Album> albums) {
|
||||||
return albums
|
return albums
|
||||||
..sort((a, b) {
|
..sort((a, b) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue