diff --git a/DeepDrftManager/Components/Pages/Tracks/TrackNew.razor b/DeepDrftManager/Components/Pages/Tracks/TrackNew.razor
index ed95ec1..e94d2b8 100644
--- a/DeepDrftManager/Components/Pages/Tracks/TrackNew.razor
+++ b/DeepDrftManager/Components/Pages/Tracks/TrackNew.razor
@@ -29,6 +29,34 @@
+
+
+
+ @if (_selectedImageFile is { } selectedImage)
+ {
+
+ Selected: @selectedImage.Name
+
+
+ }
+ else
+ {
+ No cover art — optional.
+ }
+
+
+ @if (_selectedImageFile is not null)
+ {
+ Will upload on save.
+ }
+
+
+
@if (!string.IsNullOrEmpty(_errorMessage))
@@ -67,6 +95,8 @@
private const long MaxUploadBytes = 1_073_741_824L;
private IBrowserFile? _selectedFile;
+ private IBrowserFile? _selectedImageFile;
+ private string? _imagePath;
private string _trackName = string.Empty;
private string _artist = string.Empty;
private string _album = string.Empty;
@@ -81,6 +111,18 @@
_errorMessage = null;
}
+ private void HandleImageFileSelected(InputFileChangeEventArgs e)
+ {
+ _selectedImageFile = e.File;
+ _imagePath = null;
+ }
+
+ private void ClearImage()
+ {
+ _selectedImageFile = null;
+ _imagePath = null;
+ }
+
private async Task SubmitAsync()
{
_errorMessage = null;
@@ -130,6 +172,21 @@
_isUploading = true;
try
{
+ // Upload any selected cover art first; abort the submit if it fails so we never
+ // create a track expecting an image that was never stored in the vault.
+ if (_selectedImageFile is { } imgFile)
+ {
+ await using var imgStream = imgFile.OpenReadStream(maxAllowedSize: 50_000_000);
+ var imgResult = await CmsTrackService.UploadImageAsync(imgStream, imgFile.Name, imgFile.ContentType);
+ if (!imgResult.Success)
+ {
+ var imgError = imgResult.Messages.FirstOrDefault()?.Message ?? "Unknown error";
+ _errorMessage = $"Image upload failed: {imgError}";
+ return;
+ }
+ _imagePath = imgResult.Value;
+ }
+
// OpenReadStream streams chunks from the browser via the SignalR circuit; the
// service wraps it in StreamContent so the whole file is never materialised in
// memory before DeepDrftAPI receives it.
@@ -149,6 +206,26 @@
if (result.Success)
{
+ // The upload endpoint does not accept an imagePath, so link the cover art with a
+ // follow-up metadata update — same two-step pattern TrackEdit uses.
+ if (_imagePath is { } imgPath && result.Value is { } created)
+ {
+ var linkResult = await CmsTrackService.UpdateAsync(
+ created.Id,
+ _trackName,
+ _artist,
+ string.IsNullOrWhiteSpace(_album) ? null : _album,
+ string.IsNullOrWhiteSpace(_genre) ? null : _genre,
+ string.IsNullOrWhiteSpace(_releaseDate) ? null : (DateOnly?)DateOnly.ParseExact(_releaseDate, "yyyy-MM-dd"),
+ imgPath);
+ if (!linkResult.Success)
+ {
+ // Track was created; image is in the vault but unlinked. Non-blocking —
+ // the user can attach it via Edit.
+ Snackbar.Add("Track uploaded, but cover art could not be linked. You can add it via Edit.", Severity.Warning);
+ }
+ }
+
Snackbar.Add($"Uploaded '{_trackName}'.", Severity.Success);
Navigation.NavigateTo("/tracks");
return;