using System.ComponentModel; using ErsatzTV.Application.LibraryBrowse; using ErsatzTV.Core.Api.LibraryBrowse; using MediatR; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace ErsatzTV.Controllers.Api; [ApiController] public class LibraryBrowseController(IMediator mediator) : ControllerBase { private const int MaxPageSize = 100; [HttpGet("/api/v1/library/browse", Name = "BrowseLibrary")] [Tags("Libraries")] [EndpointSummary("Browse and search library items")] [EndpointGroupName("general")] [ProducesResponseType(typeof(PagedLibraryBrowseItemsResponseModel), StatusCodes.Status200OK)] public async Task Browse( [FromQuery] string query = "", [FromQuery] int? libraryId = null, [FromQuery] LibraryBrowseMediaType? mediaType = null, [FromQuery] int pageNum = 0, [FromQuery] int pageSize = 100, [FromQuery] [Description("Parent id for a drill-in listing; only used with mediaType=TelevisionSeason (that show's seasons), mediaType=Episode (that season's episodes) or mediaType=MusicVideo (that artist's music videos), ignored otherwise")] int? parentId = null, CancellationToken cancellationToken = default) { int clampedPageNum = Math.Max(0, pageNum); int clampedPageSize = Math.Clamp(pageSize, 1, MaxPageSize); return await mediator.Send( new GetLibraryBrowseItems(query, libraryId, mediaType, clampedPageNum, clampedPageSize, parentId), cancellationToken); } }