diff --git a/src/renderer/api/jellyfin/jellyfin-controller.ts b/src/renderer/api/jellyfin/jellyfin-controller.ts index 4112fd8a3..e7cd37dd3 100644 --- a/src/renderer/api/jellyfin/jellyfin-controller.ts +++ b/src/renderer/api/jellyfin/jellyfin-controller.ts @@ -333,6 +333,7 @@ const getAlbumList = async (args: AlbumListArgs): Promise => AlbumArtistIds: query.artistIds ? formatCommaDelimitedString(query.artistIds) : undefined, + ContributingArtistIds: query.isCompilation ? query.artistIds?.[0] : undefined, IncludeItemTypes: 'MusicAlbum', Limit: query.limit, ParentId: query.musicFolderId, diff --git a/src/renderer/api/navidrome/navidrome-controller.ts b/src/renderer/api/navidrome/navidrome-controller.ts index abb23bb99..18a640718 100644 --- a/src/renderer/api/navidrome/navidrome-controller.ts +++ b/src/renderer/api/navidrome/navidrome-controller.ts @@ -233,6 +233,8 @@ const getAlbumList = async (args: AlbumListArgs): Promise => _sort: albumListSortMap.navidrome[query.sortBy], _start: query.startIndex, artist_id: query.artistIds?.[0], + compilation: query.isCompilation, + genre_id: query.genre, name: query.searchTerm, ...query._custom?.navidrome, }, diff --git a/src/renderer/api/subsonic/subsonic-controller.ts b/src/renderer/api/subsonic/subsonic-controller.ts index 298da18c7..7e21bbc1e 100644 --- a/src/renderer/api/subsonic/subsonic-controller.ts +++ b/src/renderer/api/subsonic/subsonic-controller.ts @@ -332,6 +332,45 @@ export const SubsonicController: ControllerEndpoint = { [AlbumListSort.SONG_COUNT]: undefined, }; + if (query.isCompilation) { + return { + items: [], + startIndex: 0, + totalRecordCount: 0, + }; + } + + if (query.artistIds) { + const promises = []; + + for (const artistId of query.artistIds) { + promises.push( + subsonicApiClient(apiClientProps).getArtist({ + query: { + id: artistId, + }, + }), + ); + } + + const artistResult = await Promise.all(promises); + + const albums = artistResult.flatMap((artist) => { + if (artist.status !== 200) { + fsLog.warn('Failed to get artist detail', { context: { artist } }); + return []; + } + + return artist.body['subsonic-response'].artist.album; + }); + + return { + items: albums.map((album) => subsonicNormalize.album(album, apiClientProps.server)), + startIndex: 0, + totalRecordCount: albums.length, + }; + } + const res = await subsonicApiClient(apiClientProps).getAlbumList2({ query: { fromYear: query.minYear, diff --git a/src/renderer/api/types.ts b/src/renderer/api/types.ts index 153bb928b..fc6f8dc99 100644 --- a/src/renderer/api/types.ts +++ b/src/renderer/api/types.ts @@ -377,6 +377,7 @@ export type AlbumListQuery = { }; artistIds?: string[]; genre?: string; + isCompilation?: boolean; limit?: number; maxYear?: number; minYear?: number; diff --git a/src/renderer/features/artists/components/album-artist-detail-content.tsx b/src/renderer/features/artists/components/album-artist-detail-content.tsx index 3d744aeed..54863d469 100644 --- a/src/renderer/features/artists/components/album-artist-detail-content.tsx +++ b/src/renderer/features/artists/components/album-artist-detail-content.tsx @@ -100,6 +100,7 @@ export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailConten : undefined), }, }, + artistIds: [albumArtistId], limit: 15, sortBy: AlbumListSort.RELEASE_DATE, sortOrder: SortOrder.DESC, @@ -122,6 +123,8 @@ export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailConten : undefined), }, }, + artistIds: [albumArtistId], + isCompilation: true, limit: 15, sortBy: AlbumListSort.RELEASE_DATE, sortOrder: SortOrder.DESC,