Make release Medium writable via upload + meta-edit; resolve detail-page track by releaseId not album title
This commit is contained in:
@@ -55,9 +55,10 @@
|
||||
|
||||
<MudGrid>
|
||||
<MudItem xs="12" md="5">
|
||||
@* TODO: When medium write path lands, collapse to single-track slot here for Session/Mix
|
||||
(matching BatchUpload's @if (_medium == ReleaseMedium.Cut) guard). Until then,
|
||||
BatchEdit's track list is unrestricted because _medium is read-only on the edit form. *@
|
||||
@* The medium write path persists _medium on save (9.5.B). BatchEdit still shows the full
|
||||
multi-track list for every medium; collapsing to a single-track slot for Session/Mix
|
||||
(matching BatchUpload's @if (_medium == ReleaseMedium.Cut) guard) is deferred form-shape
|
||||
work, not part of the write-path wiring. *@
|
||||
<BatchTrackList Tracks="_tracks"
|
||||
@bind-SelectedIndex="_selectedIndex"
|
||||
Disabled="_saving"
|
||||
@@ -131,9 +132,9 @@
|
||||
private ReleaseType _releaseType = ReleaseType.Single;
|
||||
private ReleaseMedium _medium = ReleaseMedium.Cut;
|
||||
|
||||
// The medium selector drives ReleaseType visibility. NOTE: the metadata update endpoint
|
||||
// (PUT api/track/meta) has no medium field, so a medium change is not persisted on save today —
|
||||
// the selector reflects/adjusts local form shape only. Persisting medium-on-edit is an API change.
|
||||
// The medium selector drives ReleaseType visibility and is persisted on save: every UpdateAsync /
|
||||
// UploadTrackAsync call below passes _medium, and PUT api/track/meta resets ReleaseType to its
|
||||
// default server-side for a non-Cut medium.
|
||||
private void OnMediumChanged(ReleaseMedium medium) => _medium = medium;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@@ -373,6 +374,7 @@
|
||||
releaseDate,
|
||||
imagePathForUpdate,
|
||||
_releaseType,
|
||||
_medium,
|
||||
trackNumber);
|
||||
|
||||
if (!updateResult.Success)
|
||||
@@ -407,7 +409,8 @@
|
||||
row.WavFile.Name,
|
||||
createdByUserId,
|
||||
_releaseType,
|
||||
trackNumber);
|
||||
trackNumber,
|
||||
_medium);
|
||||
|
||||
if (!uploadResult.Success || uploadResult.Value is null)
|
||||
{
|
||||
@@ -433,6 +436,7 @@
|
||||
releaseDate,
|
||||
linkPath,
|
||||
_releaseType,
|
||||
_medium,
|
||||
trackNumber);
|
||||
|
||||
if (!linkResult.Success)
|
||||
|
||||
@@ -320,6 +320,7 @@
|
||||
string.IsNullOrWhiteSpace(_releaseDate) ? null : (DateOnly?)DateOnly.ParseExact(_releaseDate, "yyyy-MM-dd"),
|
||||
imgPath,
|
||||
_releaseType,
|
||||
_medium,
|
||||
trackNumber);
|
||||
|
||||
if (!linkResult.Success)
|
||||
|
||||
@@ -210,6 +210,7 @@
|
||||
releaseDate,
|
||||
string.IsNullOrEmpty(_form.ImagePath) ? "" : _form.ImagePath,
|
||||
_form.ReleaseType,
|
||||
_form.Medium,
|
||||
_form.TrackNumber);
|
||||
if (updated.Success)
|
||||
{
|
||||
@@ -298,8 +299,8 @@
|
||||
public DateTime? ReleaseDate { get; set; }
|
||||
public ReleaseType ReleaseType { get; set; } = ReleaseType.Single;
|
||||
|
||||
// Drives ReleaseType visibility via MediumFields. NOTE: not persisted — PUT api/track/meta has
|
||||
// no medium field, so a medium change on edit is form-shape only until the API grows one.
|
||||
// Drives ReleaseType visibility via MediumFields and is persisted on save (PUT api/track/meta
|
||||
// carries Medium). A non-Cut medium resets ReleaseType to its default server-side.
|
||||
public ReleaseMedium Medium { get; set; } = ReleaseMedium.Cut;
|
||||
public int TrackNumber { get; set; } = 1;
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ public class CmsTrackService : ICmsTrackService
|
||||
multipart.Add(new StringContent(createdByUserId.ToString()), "createdByUserId");
|
||||
multipart.Add(new StringContent(releaseType.ToString()), "releaseType");
|
||||
multipart.Add(new StringContent(trackNumber.ToString()), "trackNumber");
|
||||
// Forward-compatible: the upload endpoint does not bind a "medium" field yet (server defaults
|
||||
// to Cut). Sent so the value round-trips once the API grows the parameter; ignored until then.
|
||||
// The upload endpoint binds "medium" to the created release's ReleaseMedium (defaulting to Cut
|
||||
// for an unrecognised value). Authoritative only when this upload creates the release.
|
||||
multipart.Add(new StringContent(medium.ToString()), "medium");
|
||||
|
||||
var client = _httpClientFactory.CreateClient(ContentCmsClientName);
|
||||
@@ -374,6 +374,7 @@ public class CmsTrackService : ICmsTrackService
|
||||
string? album, string? genre, DateOnly? releaseDate,
|
||||
string? imagePath = null,
|
||||
ReleaseType? releaseType = null,
|
||||
ReleaseMedium? medium = null,
|
||||
int? trackNumber = null,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
@@ -387,6 +388,7 @@ public class CmsTrackService : ICmsTrackService
|
||||
releaseDate,
|
||||
imagePath,
|
||||
releaseType = releaseType.HasValue ? (int?)releaseType.Value : null,
|
||||
medium = medium.HasValue ? (int?)medium.Value : null,
|
||||
trackNumber,
|
||||
};
|
||||
|
||||
|
||||
@@ -18,10 +18,9 @@ public interface ICmsTrackService
|
||||
/// orphan is handled and logged server-side; here it surfaces as a failed result.
|
||||
/// <paramref name="originalFileName"/> is the browser's filename, captured at upload time and
|
||||
/// stored as metadata; it is not user-editable afterwards.
|
||||
/// <paramref name="medium"/> sets the parent release's <see cref="ReleaseMedium"/>. NOTE: the
|
||||
/// current <c>POST api/track/upload</c> endpoint has no <c>medium</c> form field, so the value is
|
||||
/// sent forward-compatibly and ignored server-side until the API binds it (Cut is the server
|
||||
/// default). Wiring the selector through here keeps the CMS ready for that API change.
|
||||
/// <paramref name="medium"/> sets the parent release's <see cref="ReleaseMedium"/> when this upload
|
||||
/// creates the release. The medium is authoritative only on creation — adding a track to an existing
|
||||
/// release never changes its medium (that is the edit path, <see cref="UpdateAsync"/>).
|
||||
/// </summary>
|
||||
Task<ResultContainer<TrackDto>> UploadTrackAsync(
|
||||
Stream wavStream,
|
||||
@@ -80,13 +79,16 @@ public interface ICmsTrackService
|
||||
/// <summary>
|
||||
/// Update a track's metadata via <c>PUT api/track/meta/{id}</c>. EntryKey is immutable and
|
||||
/// not part of the update. <paramref name="imagePath"/> is tri-state: <c>null</c> leaves the
|
||||
/// cover art unchanged, <c>""</c> clears it, and any other value sets it.
|
||||
/// cover art unchanged, <c>""</c> clears it, and any other value sets it. <paramref name="medium"/>
|
||||
/// is null = no change; a non-null, non-Cut value resets the release's ReleaseType to its default
|
||||
/// server-side, since ReleaseType is meaningful only for Cut.
|
||||
/// </summary>
|
||||
Task<Result> UpdateAsync(
|
||||
long id, string trackName, string artist,
|
||||
string? album, string? genre, DateOnly? releaseDate,
|
||||
string? imagePath = null,
|
||||
ReleaseType? releaseType = null,
|
||||
ReleaseMedium? medium = null,
|
||||
int? trackNumber = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user