Adds PhotoAlbum, CreatorHome, AboutCreator.

This commit is contained in:
2025-04-23 17:45:09 -04:00
parent 247b2b023c
commit 6d3525c2ee
42 changed files with 3176 additions and 818 deletions

View File

@@ -0,0 +1,121 @@
using FastEndpoints;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Hutopy.Web.Features.Contents.Data;
using Hutopy.Web.Common.Security;
using Hutopy.Web.Common.BlobStorage;
namespace Hutopy.Web.Features.Contents.Handlers;
[PublicAPI]
public record AddPhotoToAlbumRequest(
Guid AlbumId,
Guid PhotoId,
IFormFile File,
string? Caption = null);
[PublicAPI]
public record AddPhotoToAlbumResponse(
Guid PhotoId,
string PhotoUrl);
[PublicAPI]
public sealed class AddPhotoToAlbumRequestValidator : Validator<AddPhotoToAlbumRequest>
{
public AddPhotoToAlbumRequestValidator()
{
RuleFor(x => x.AlbumId)
.NotNull()
.NotEmpty();
RuleFor(x => x.PhotoId)
.NotNull()
.NotEmpty();
RuleFor(x => x.File)
.NotNull()
.NotEmpty()
.Must(file => file.ContentType.StartsWith("image/"))
.WithMessage("File must be an image");
RuleFor(x => x.Caption)
.MaximumLength(255);
}
}
[PublicAPI]
public class AddPhotoToAlbumHandler(
ContentDbContext context,
AzureBlobStorage blobStorage)
: Endpoint<AddPhotoToAlbumRequest, AddPhotoToAlbumResponse>
{
public override void Configure()
{
Post("/api/albums/{AlbumId}/photos");
Options(o => o.WithTags("Albums"));
AllowFileUploads();
}
public override async Task HandleAsync(
AddPhotoToAlbumRequest request,
CancellationToken ct)
{
var userId = User.GetUserId();
var album = await context
.Albums
.SingleOrDefaultAsync(
a => a.Id == request.AlbumId && a.CreatedBy == userId,
cancellationToken: ct);
if (album is null)
{
await SendNotFoundAsync(ct);
return;
}
// Check if a photo with the same ID already exists
var existingPhoto = await context
.AlbumPhotos
.AnyAsync(p => p.Id == request.PhotoId, ct);
if (existingPhoto)
{
await SendErrorsAsync(409, ct);
return;
}
// Get the next order number
var nextOrder = await context
.AlbumPhotos
.Where(p => p.AlbumId == request.AlbumId)
.MaxAsync(p => (int?)p.Order, ct) ?? 0;
// Upload the photo to blob storage
var photoUrl = await blobStorage.UploadFileAsync(
ContainerNames.Creators,
$"{SubDirectoryNames.Albums}/{request.AlbumId}/{request.PhotoId}",
request.File.OpenReadStream(),
request.File.ContentType,
ct);
// Create the album photo
var photo = new AlbumPhoto
{
Id = request.PhotoId,
CreatedBy = userId,
AlbumId = request.AlbumId,
PhotoUrl = photoUrl,
Caption = request.Caption,
Order = nextOrder + 1
};
context.AlbumPhotos.Add(photo);
await context.SaveChangesAsync(ct);
await SendOkAsync(
new AddPhotoToAlbumResponse(photo.Id, photoUrl),
ct);
}
}