feat: add search/album/genre filtering and /albums + /genres browse pages

This commit is contained in:
daniel-c-harvey
2026-06-10 10:54:56 -04:00
parent 1071ba7374
commit 5cae83b9ed
24 changed files with 940 additions and 15 deletions
+35 -1
View File
@@ -97,6 +97,7 @@ public class TrackManager
int pageSize,
string? sortColumn,
bool sortDescending,
TrackFilter? filter = null,
CancellationToken cancellationToken = default)
{
try
@@ -117,7 +118,14 @@ public class TrackManager
}
};
var page = await Repository.GetPagedAsync(parameters);
// An all-null filter must produce identical results to no filter, so collapse it to
// null and take the unfiltered base path (preserves backward compatibility).
var effectiveFilter = filter is null || filter.IsEmpty ? null : filter;
var page = effectiveFilter is null
? await Repository.GetPagedAsync(parameters)
: await Repository.GetPagedFilteredAsync(parameters, effectiveFilter, cancellationToken);
var dtoPage = PagedResult<TrackDto>.From(page, page.Items.Select(TrackConverter.Convert));
return ResultContainer<PagedResult<TrackDto>>.CreatePassResult(dtoPage);
}
@@ -127,6 +135,32 @@ public class TrackManager
}
}
public async Task<ResultContainer<List<AlbumSummaryDto>>> GetDistinctAlbums(CancellationToken cancellationToken = default)
{
try
{
var albums = await Repository.GetDistinctAlbumsAsync(cancellationToken);
return ResultContainer<List<AlbumSummaryDto>>.CreatePassResult(albums);
}
catch (Exception e)
{
return ResultContainer<List<AlbumSummaryDto>>.CreateFailResult(e.Message);
}
}
public async Task<ResultContainer<List<GenreSummaryDto>>> GetDistinctGenres(CancellationToken cancellationToken = default)
{
try
{
var genres = await Repository.GetDistinctGenresAsync(cancellationToken);
return ResultContainer<List<GenreSummaryDto>>.CreatePassResult(genres);
}
catch (Exception e)
{
return ResultContainer<List<GenreSummaryDto>>.CreateFailResult(e.Message);
}
}
public async Task<ResultContainer<TrackDto>> Create(TrackDto newTrack)
{
try