From b011ccdd5bd9ac099aff055cd3cfa40c5c89d62e Mon Sep 17 00:00:00 2001 From: XShine555 Date: Thu, 24 Sep 2026 05:20:20 +0200 Subject: [PATCH] backend: expose track count and duration on playlist responses --- .../PlayLists/GetPlayListById.cs | 4 +++- .../PlayLists/GetPlayLists.cs | 4 +++- .../PlayLists/GetPlayListsByUserId.cs | 4 +++- .../Responses/PlayListApplicationResponse.cs | 6 ++++++ .../PlayLists/UpdatePlayList.cs | 17 ++++++++++++++++- 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/backend/Core/Musify.Application/PlayLists/GetPlayListById.cs b/backend/Core/Musify.Application/PlayLists/GetPlayListById.cs index 0fc11b7..ef55024 100644 --- a/backend/Core/Musify.Application/PlayLists/GetPlayListById.cs +++ b/backend/Core/Musify.Application/PlayLists/GetPlayListById.cs @@ -21,6 +21,8 @@ namespace Musify.Application.PlayLists .Select(p => new { PlayList = p, + TrackCount = p.PlayListTracks.Count, + DurationSeconds = p.PlayListTracks.Sum(plt => (double?)plt.Track.DurationSeconds) ?? 0, CoverTrackIds = p.PlayListTracks .OrderBy(plt => plt.Position) .Take(PlayListApplicationResponse.CoverTrackCount) @@ -36,7 +38,7 @@ namespace Musify.Application.PlayLists && entry.PlayList.UserId != request.RequestingUserId) return Error.NotFound(); - return PlayListApplicationResponse.FromEntity(entry.PlayList, entry.CoverTrackIds); + return PlayListApplicationResponse.FromEntity(entry.PlayList, entry.TrackCount, entry.DurationSeconds, entry.CoverTrackIds); } } } diff --git a/backend/Core/Musify.Application/PlayLists/GetPlayLists.cs b/backend/Core/Musify.Application/PlayLists/GetPlayLists.cs index 07d8874..50df7ce 100644 --- a/backend/Core/Musify.Application/PlayLists/GetPlayLists.cs +++ b/backend/Core/Musify.Application/PlayLists/GetPlayLists.cs @@ -25,6 +25,8 @@ namespace Musify.Application.PlayLists .Select(p => new { PlayList = p, + TrackCount = p.PlayListTracks.Count, + DurationSeconds = p.PlayListTracks.Sum(plt => (double?)plt.Track.DurationSeconds) ?? 0, CoverTrackIds = p.PlayListTracks .OrderBy(plt => plt.Position) .Take(PlayListApplicationResponse.CoverTrackCount) @@ -34,7 +36,7 @@ namespace Musify.Application.PlayLists .ToPagedListAsync(request.PageNumber, request.PageSize, totalCount, cancellationToken); var pagedPlayLists = new StaticPagedList( - pagedEntities.Select(entry => PlayListApplicationResponse.FromEntity(entry.PlayList, entry.CoverTrackIds)), + pagedEntities.Select(entry => PlayListApplicationResponse.FromEntity(entry.PlayList, entry.TrackCount, entry.DurationSeconds, entry.CoverTrackIds)), pagedEntities.PageNumber, pagedEntities.PageSize, pagedEntities.TotalItemCount); return PaginatedResponse.FromPagedList(pagedPlayLists); diff --git a/backend/Core/Musify.Application/PlayLists/GetPlayListsByUserId.cs b/backend/Core/Musify.Application/PlayLists/GetPlayListsByUserId.cs index f877f7e..92d24f7 100644 --- a/backend/Core/Musify.Application/PlayLists/GetPlayListsByUserId.cs +++ b/backend/Core/Musify.Application/PlayLists/GetPlayListsByUserId.cs @@ -46,6 +46,8 @@ namespace Musify.Application.PlayLists .Select(p => new { PlayList = p, + TrackCount = p.PlayListTracks.Count, + DurationSeconds = p.PlayListTracks.Sum(plt => (double?)plt.Track.DurationSeconds) ?? 0, CoverTrackIds = p.PlayListTracks .OrderBy(plt => plt.Position) .Take(PlayListApplicationResponse.CoverTrackCount) @@ -55,7 +57,7 @@ namespace Musify.Application.PlayLists .ToPagedListAsync(request.PageNumber, request.PageSize, totalCount, cancellationToken); var pagedPlayLists = new StaticPagedList( - pagedEntities.Select(entry => PlayListApplicationResponse.FromEntity(entry.PlayList, entry.CoverTrackIds)), + pagedEntities.Select(entry => PlayListApplicationResponse.FromEntity(entry.PlayList, entry.TrackCount, entry.DurationSeconds, entry.CoverTrackIds)), pagedEntities.PageNumber, pagedEntities.PageSize, pagedEntities.TotalItemCount); return PaginatedResponse.FromPagedList(pagedPlayLists); diff --git a/backend/Core/Musify.Application/PlayLists/Responses/PlayListApplicationResponse.cs b/backend/Core/Musify.Application/PlayLists/Responses/PlayListApplicationResponse.cs index a53c82d..1402ab7 100644 --- a/backend/Core/Musify.Application/PlayLists/Responses/PlayListApplicationResponse.cs +++ b/backend/Core/Musify.Application/PlayLists/Responses/PlayListApplicationResponse.cs @@ -14,6 +14,8 @@ namespace Musify.Application.PlayLists.Responses string? LargeImageKeyName, [property: JsonConverter(typeof(LongAsStringConverter))] long OwnerUserId, PlaylistVisibility Visibility, + int TrackCount, + double DurationSeconds, DateTime CreatedAt, DateTime UpdatedAt, IReadOnlyList CoverTrackIds) @@ -22,6 +24,8 @@ namespace Musify.Application.PlayLists.Responses public static PlayListApplicationResponse FromEntity( PlayList playList, + int trackCount = 0, + double durationSeconds = 0, IReadOnlyList? coverTrackIds = null) { return new PlayListApplicationResponse( @@ -33,6 +37,8 @@ namespace Musify.Application.PlayLists.Responses playList.Pictures?.LargeName, playList.UserId, playList.Visibility, + trackCount, + durationSeconds, playList.CreatedAt, playList.UpdatedAt, coverTrackIds ?? []); diff --git a/backend/Core/Musify.Application/PlayLists/UpdatePlayList.cs b/backend/Core/Musify.Application/PlayLists/UpdatePlayList.cs index 46cc87a..600f629 100644 --- a/backend/Core/Musify.Application/PlayLists/UpdatePlayList.cs +++ b/backend/Core/Musify.Application/PlayLists/UpdatePlayList.cs @@ -112,7 +112,22 @@ namespace Musify.Application.PlayLists .ToListAsync(cancellationToken); logger.LogInformation("Updated playlist {PlayListId}", playListEntity.Id); - return PlayListApplicationResponse.FromEntity(playListEntity, coverTrackIds); + var totals = await database.PlayListHasTracks + .AsNoTracking() + .Where(plt => plt.PlayListId == playListEntity.Id) + .GroupBy(plt => plt.PlayListId) + .Select(group => new + { + TrackCount = group.Count(), + DurationSeconds = group.Sum(plt => plt.Track.DurationSeconds) + }) + .SingleOrDefaultAsync(cancellationToken); + + return PlayListApplicationResponse.FromEntity( + playListEntity, + totals?.TrackCount ?? 0, + totals?.DurationSeconds ?? 0, + coverTrackIds); } private async Task> PublishUpdatePlayListPictureSourceEventAsync(