Add track coauthors with invitations, acceptance and coauthor-aware track responses
Owners invite existing users to coauthor a track; invitees accept or reject, and either side can remove a coauthor. Only accepted coauthors appear in track responses and in the coauthor's public track list. The owner also receives the full invitation list with statuses on the user tracks response.
This commit is contained in:
@@ -15,7 +15,8 @@ namespace Musify.Application.Tracks.Responses
|
||||
long OwnerUserId,
|
||||
IReadOnlyCollection<Genre> Tags,
|
||||
bool IsExplicit,
|
||||
bool IsPublished)
|
||||
bool IsPublished,
|
||||
IReadOnlyList<TrackCoauthorReference> Coauthors)
|
||||
{
|
||||
public static TrackApplicationResponse FromEntity(Track track, int listensCount) =>
|
||||
new(
|
||||
@@ -30,6 +31,7 @@ namespace Musify.Application.Tracks.Responses
|
||||
track.OwnerUserId,
|
||||
track.Tags.Select(tag => tag.Tag).ToList(),
|
||||
track.IsExplicit,
|
||||
track.IsPublished);
|
||||
track.IsPublished,
|
||||
[]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using Musify.Domain.ValueObjects;
|
||||
|
||||
namespace Musify.Application.Tracks.Responses
|
||||
{
|
||||
public record TrackCoauthorReference(long Id, string Name);
|
||||
|
||||
public record TrackCoauthorInviteReference(long UserId, string Name, CoauthorStatus Status);
|
||||
}
|
||||
@@ -27,9 +27,15 @@ namespace Musify.Application.Tracks.Responses
|
||||
track.OwnerUserId,
|
||||
track.Tags.Select(tag => tag.Tag).ToList(),
|
||||
track.IsExplicit,
|
||||
track.IsPublished));
|
||||
track.IsPublished,
|
||||
track.Coauthors
|
||||
.Where(coauthor => coauthor.Status == CoauthorStatus.Accepted)
|
||||
.OrderBy(coauthor => coauthor.RespondedAt)
|
||||
.ThenBy(coauthor => coauthor.UserId)
|
||||
.Select(coauthor => new TrackCoauthorReference(coauthor.UserId, coauthor.User.Name))
|
||||
.ToList()));
|
||||
|
||||
public static IQueryable<UserTrackApplicationResponse> SelectUserResponse(this IQueryable<Track> query) =>
|
||||
public static IQueryable<UserTrackApplicationResponse> SelectUserResponse(this IQueryable<Track> query, bool includeInvites = false) =>
|
||||
query.Select(track => new UserTrackApplicationResponse(
|
||||
track.Id,
|
||||
track.Title,
|
||||
@@ -48,6 +54,19 @@ namespace Musify.Application.Tracks.Responses
|
||||
.OrderBy(albumTrack => albumTrack.AddedAt)
|
||||
.ThenBy(albumTrack => albumTrack.AlbumId)
|
||||
.Select(albumTrack => new TrackAlbumReference(albumTrack.AlbumId, albumTrack.Album.Title))
|
||||
.ToList()));
|
||||
.ToList(),
|
||||
track.Coauthors
|
||||
.Where(coauthor => coauthor.Status == CoauthorStatus.Accepted)
|
||||
.OrderBy(coauthor => coauthor.RespondedAt)
|
||||
.ThenBy(coauthor => coauthor.UserId)
|
||||
.Select(coauthor => new TrackCoauthorReference(coauthor.UserId, coauthor.User.Name))
|
||||
.ToList(),
|
||||
includeInvites
|
||||
? track.Coauthors
|
||||
.OrderBy(coauthor => coauthor.InvitedAt)
|
||||
.ThenBy(coauthor => coauthor.UserId)
|
||||
.Select(coauthor => new TrackCoauthorInviteReference(coauthor.UserId, coauthor.User.Name, coauthor.Status))
|
||||
.ToList()
|
||||
: new List<TrackCoauthorInviteReference>()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,5 +17,7 @@ namespace Musify.Application.Tracks.Responses
|
||||
IReadOnlyCollection<Genre> Tags,
|
||||
bool IsExplicit,
|
||||
bool IsPublished,
|
||||
IReadOnlyList<TrackAlbumReference> Albums);
|
||||
IReadOnlyList<TrackAlbumReference> Albums,
|
||||
IReadOnlyList<TrackCoauthorReference> Coauthors,
|
||||
IReadOnlyList<TrackCoauthorInviteReference> CoauthorInvites);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user