From ee5ab1a7516cf85861859af92c5d122a8bc8d92e Mon Sep 17 00:00:00 2001 From: zarzet Date: Tue, 30 Jun 2026 06:20:37 +0700 Subject: [PATCH] fix(queue): resolve local album tracks by album_key Load queue local album tracks from album_key when available and fall back to album/artist matching with empty album_artist handling. Thread album_key through grouped local album rows for more reliable navigation. --- lib/screens/queue_tab.dart | 18 ++++++++++++++---- lib/screens/queue_tab_helpers.dart | 5 ++++- lib/services/library_database.dart | 16 +++++++++++++++- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/screens/queue_tab.dart b/lib/screens/queue_tab.dart index 3d10e165..606256d8 100644 --- a/lib/screens/queue_tab.dart +++ b/lib/screens/queue_tab.dart @@ -2456,10 +2456,20 @@ class _QueueTabState extends ConsumerState { Future _navigateToLocalAlbum(_GroupedLocalAlbum album) async { var tracks = album.tracks; if (tracks.isEmpty && album.displayTrackCount > 0) { - final rows = await LibraryDatabase.instance.getQueueLocalAlbumTracks( - album.albumName, - album.artistName, - ); + var rows = album.albumKey.isNotEmpty + ? await LibraryDatabase.instance.getQueueLocalAlbumTracksByKey( + album.albumKey, + ) + : await LibraryDatabase.instance.getQueueLocalAlbumTracks( + album.albumName, + album.artistName, + ); + if (rows.isEmpty && album.albumKey.isNotEmpty) { + rows = await LibraryDatabase.instance.getQueueLocalAlbumTracks( + album.albumName, + album.artistName, + ); + } tracks = rows.map(LocalLibraryItem.fromJson).toList(growable: false); if (!mounted) return; } diff --git a/lib/screens/queue_tab_helpers.dart b/lib/screens/queue_tab_helpers.dart index a5996117..23cfc54a 100644 --- a/lib/screens/queue_tab_helpers.dart +++ b/lib/screens/queue_tab_helpers.dart @@ -209,6 +209,7 @@ class _GroupedAlbum { } class _GroupedLocalAlbum { + final String albumKey; final String albumName; final String artistName; final String? coverPath; @@ -218,6 +219,7 @@ class _GroupedLocalAlbum { final String searchKey; _GroupedLocalAlbum({ + required this.albumKey, required this.albumName, required this.artistName, this.coverPath, @@ -226,7 +228,7 @@ class _GroupedLocalAlbum { required this.latestScanned, }) : searchKey = '${albumName.toLowerCase()}|${artistName.toLowerCase()}'; - String get key => '$albumName|$artistName'; + String get key => albumKey; int get displayTrackCount => trackCount ?? tracks.length; } @@ -480,6 +482,7 @@ final _queueLibraryPageProvider = if (source == 'local') { groupedLocalAlbums.add( _GroupedLocalAlbum( + albumKey: row['album_key'] as String? ?? '', albumName: row['album_name'] as String? ?? '', artistName: row['artist_name'] as String? ?? '', coverPath: row['cover_path'] as String?, diff --git a/lib/services/library_database.dart b/lib/services/library_database.dart index 49694c93..a4136463 100644 --- a/lib/services/library_database.dart +++ b/lib/services/library_database.dart @@ -967,7 +967,7 @@ class LibraryDatabase { final rows = await db.query( 'library', where: - 'LOWER(album_name) = ? AND LOWER(COALESCE(album_artist, artist_name)) = ?', + "LOWER(album_name) = ? AND LOWER(COALESCE(NULLIF(album_artist, ''), artist_name)) = ?", whereArgs: [albumName.toLowerCase(), artistName.toLowerCase()], orderBy: 'COALESCE(disc_number, 0), COALESCE(track_number, 0), track_name', @@ -975,6 +975,20 @@ class LibraryDatabase { return rows.map(_dbRowToJson).toList(growable: false); } + Future>> getQueueLocalAlbumTracksByKey( + String albumKey, + ) async { + final db = await database; + final rows = await db.query( + 'library', + where: 'album_key = ?', + whereArgs: [albumKey], + orderBy: + 'COALESCE(disc_number, 0), COALESCE(track_number, 0), track_name', + ); + return rows.map(_dbRowToJson).toList(growable: false); + } + String _queueTrackUnionSql(QueueLibraryDbQuery request, List args) { final parts = []; if (request.source != 'local') {