diff --git a/src/Web/Features/Contents/Handlers/CreateContent.cs b/src/Web/Features/Contents/Handlers/CreateContent.cs index 968c948..a8ca937 100644 --- a/src/Web/Features/Contents/Handlers/CreateContent.cs +++ b/src/Web/Features/Contents/Handlers/CreateContent.cs @@ -14,10 +14,9 @@ public record PostContentRequest( string Title, string Description, IFormFileCollection? Files, - string ThumbnailUrl, + IFormFile? Thumbnail, // Nouveau champ pour le thumbnail string[]? ExternalUrls); - [PublicAPI] public sealed class PostContentRequestValidator : Validator { @@ -42,8 +41,9 @@ public sealed class PostContentRequestValidator : Validator RuleForEach(r => r.ExternalUrls) .NotEmpty().WithMessage("External URL cannot be empty") .Must(url => Uri.IsWellFormedUriString(url, UriKind.Absolute)).WithMessage("External URL is not valid"); - - + + RuleFor(r => r.Thumbnail) + .Must(file => file == null || file.Length > 0).WithMessage("Thumbnail file is invalid."); } } @@ -64,24 +64,19 @@ public sealed class PostContent( CancellationToken ct) { var urls = new ConcurrentBag(); + string? thumbnailUrl = null; + // Traitement des fichiers uploadés if (req.Files is not null) { await Parallel.ForEachAsync( req.Files, ct, - async ( - file, - ict) => + async (file, ict) => { try { - var contentUrl = await SaveFileAsync( - req.CreatorId, - req.Id, - file, - ict); - + var contentUrl = await SaveFileAsync(req.CreatorId, req.Id, file, ict); urls.Add(contentUrl); } catch (Exception ex) @@ -90,15 +85,26 @@ public sealed class PostContent( } }); } - - if (req.ExternalUrls is not null) + + // Téléversement du thumbnail + if (req.Thumbnail is not null) { - foreach (var externalUrl in req.ExternalUrls) + try { - urls.Add(externalUrl); + thumbnailUrl = await SaveFileAsync( + req.CreatorId, + req.Id, + req.Thumbnail, + ct, + isThumbnail: true); // Utilisation d'un chemin spécifique pour le thumbnail + } + catch (Exception ex) + { + Logger.LogError("Error uploading thumbnail: {ErrorMessage}", ex.Message); } } - + + // Ajout à la base de données await context.Contents.AddAsync( new Content { @@ -107,13 +113,13 @@ public sealed class PostContent( Title = req.Title, Description = req.Description, Urls = urls.IsEmpty ? null : urls.ToArray(), - ThumbnailUrl = req.ThumbnailUrl, - + ThumbnailUrl = thumbnailUrl, }, ct); await context.SaveChangesAsync(ct); + // Récupérer le contenu pour le retour var content = await context .Contents .Select(c => new ContentModel @@ -141,11 +147,18 @@ public sealed class PostContent( Guid creatorId, Guid contentId, IFormFile file, - CancellationToken ct = default) + CancellationToken ct = default, + bool isThumbnail = false) // Nouveau paramètre pour indiquer si c'est un thumbnail { + // Détermine le chemin du blob + var blobName = isThumbnail + ? $"{creatorId}/{SubDirectoryNames.Contents}/{contentId}/thumbnail-{file.FileName}" // Chemin pour le thumbnail + : $"{creatorId}/{SubDirectoryNames.Contents}/{contentId}/{file.FileName}"; // Chemin pour les fichiers normaux + + // Téléverse le fichier var url = await blobStorage.UploadFileAsync( ContainerNames.Creators, - $"{creatorId}/{SubDirectoryNames.Contents}/{contentId}/{file.FileName}", + blobName, file.OpenReadStream(), file.ContentType, ct: ct);