diff --git a/src/lib/system/datasources/local_music_fetcher_impl.dart b/src/lib/system/datasources/local_music_fetcher_impl.dart index 29a79ae..333183a 100644 --- a/src/lib/system/datasources/local_music_fetcher_impl.dart +++ b/src/lib/system/datasources/local_music_fetcher_impl.dart @@ -66,12 +66,12 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { } } - final List songFiles = []; + final Set songFilePaths = {}; for (final libDir in libDirs) { - final List files = - await getSongFilesInDirectory(libDir.path, allowedExtensions, blockedPaths); - songFiles.addAll(files); + _log.d('Checking folder: ${libDir.path}'); + songFilePaths.addAll(await getSongFilesInDirectory(libDir.path, allowedExtensions, blockedPaths)); } + final List songFiles = songFilePaths.map((e) => File(e)).toList(); _log.d('Found ${songFiles.length} songs'); @@ -89,7 +89,7 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { final existingSongFiles = songFiles.where((element) => !songFilesToCheck.contains(element)).toList(); final structs = await mapSongsAlreadyScanned(existingSongFiles, albumsInDb, artistsInDb); - var songs = structs['songs'] as List; + final songs = structs['songs'] as List; final albums = structs['albums'] as List; final artists = structs['artists'] as Set; @@ -97,6 +97,7 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { final albumArtMap = structs['albumArtMap'] as Map; final songsToCheck = await getMetadataForFiles(songFilesToCheck); + _log.d('Songs to check: ${songsToCheck.length}'); for (final (songFile, songData) in songsToCheck) { _log.i('Scanning Song ${songFile.path}'); @@ -105,7 +106,7 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { final lastModified = songFile.lastModifiedSync(); final albumArtist = songData.albumArtist ?? songData.artist; - final albumString = '${songData.album}___${albumArtist}___${songData.year}'; + final albumString = '${songData.album}___${albumArtist}__${songData.year}'; if (albumIdMap.containsKey(albumString)) { final albumId = albumIdMap[albumString]!; @@ -179,6 +180,8 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { )); } + _log.d('Songs in list: ${songs.length}'); + final albumAccentTasks = albums .where((element) => element.color == null && element.albumArtPath != null) .map((e) => AccentGenerator(e.id, File(e.albumArtPath!))); @@ -196,6 +199,8 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { _fileNumSubject.add(executions.length); scanCount = 0; + final albumColorMap = {}; + for (final execution in executions) { _progressSubject.add(++scanCount); final (albumId, color) = await execution; @@ -204,17 +209,21 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { continue; } - final i = albums.indexWhere((element) => element.id == albumId); - albums[i] = albums[i].copyWith(color: color); - - songs = songs.map((song) { - if (song.albumId == albumId) return song.copyWith(color: color); - return song; - }).toList(); + albumColorMap[albumId] = color; } asyncExecutor.close(); + for (int i = 0; i < albums.length; i++) { + final Color? color = albumColorMap[albums[i].id]; + if (color != null) albums[i] = albums[i].copyWith(color: color); + } + + for (int i = 0; i < songs.length; i++) { + final Color? color = albumColorMap[songs[i].albumId]; + if (color != null) songs[i] = songs[i].copyWith(color: color); + } + return { 'SONGS': songs, 'ALBUMS': albums, @@ -222,7 +231,7 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { }; } - Future> getSongFilesInDirectory( + Future> getSongFilesInDirectory( String path, Set allowedExtensions, Set blockedPaths) async { return Directory(path) .list(recursive: true, followLinks: false) @@ -236,8 +245,8 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { return false; } }) - .asyncMap((item) => File(item.path)) - .toList(); + .asyncMap((item) => item.path) + .toSet(); } // Returns a list of all new song files and files that have changed since they where last imported @@ -277,7 +286,10 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher { // Maps all the songs that where scanned previously, and their Albums and Artists to the new data structures Future> mapSongsAlreadyScanned( - List songFiles, List albumsInDb, List artistsInDb) async { + List songFiles, + List albumsInDb, + List artistsInDb, + ) async { final List songs = []; final List albums = []; final Set artists = {};