Make release Medium writable via upload + meta-edit; resolve detail-page track by releaseId not album title

This commit is contained in:
daniel-c-harvey
2026-06-13 11:34:45 -04:00
parent ea018beb3e
commit 8b62915083
15 changed files with 314 additions and 28 deletions
+5 -1
View File
@@ -23,7 +23,8 @@ public class TrackClient
bool sortDescending = false,
string? searchText = null,
string? album = null,
string? genre = null)
string? genre = null,
long? releaseId = null)
{
var queryArgs = new Dictionary<string, string?>(){
["page"] = pageNumber.ToString(),
@@ -45,6 +46,9 @@ public class TrackClient
if (!string.IsNullOrEmpty(genre))
queryArgs["genre"] = genre;
if (releaseId is { } id)
queryArgs["releaseId"] = id.ToString();
string query = QueryString.Create(queryArgs).ToString();
var response = await _http.GetAsync($"api/track/page{query}");
@@ -19,7 +19,8 @@ public interface ITrackDataService
bool sortDescending = false,
string? searchText = null,
string? album = null,
string? genre = null);
string? genre = null,
long? releaseId = null);
/// <summary>All releases with track counts, title-ascending.</summary>
Task<ApiResult<List<ReleaseDto>>> GetAlbums();
@@ -26,8 +26,9 @@ public class TrackClientDataService : ITrackDataService
bool sortDescending = false,
string? searchText = null,
string? album = null,
string? genre = null)
=> _trackClient.GetPage(pageNumber, pageSize, sortColumn, sortDescending, searchText, album, genre);
string? genre = null,
long? releaseId = null)
=> _trackClient.GetPage(pageNumber, pageSize, sortColumn, sortDescending, searchText, album, genre, releaseId);
public Task<ApiResult<List<ReleaseDto>>> GetAlbums()
=> _trackClient.GetAlbums();
@@ -6,7 +6,7 @@ namespace DeepDrftPublic.Client.ViewModels;
/// <summary>
/// State for a single-release detail page (Session, Mix). Loads the release and resolves its
/// playable track. The release read surface exposes no track entry directly, so the playable track
/// is resolved through the existing track gallery filtered by the release's album title — for
/// is resolved through the existing track gallery filtered by the release's id (an exact join) — for
/// Session/Mix that yields the single track. Scoped; reset every flag per <see cref="Load"/> so a
/// reused instance never bleeds across navigations (mirrors TrackDetailViewModel).
/// </summary>
@@ -53,11 +53,12 @@ public class ReleaseDetailViewModel
Release = release;
// Resolve the playable track via the album-filtered track page. Session/Mix releases
// carry a single track; take the first. A release with no streamable track simply
// Resolve the playable track via the releaseId-filtered track page — an exact join, not a
// title string (which collides across same-titled releases and breaks on rename). Session/Mix
// releases carry a single track; take the first. A release with no streamable track simply
// leaves Track null (the detail page hides the play affordance).
var trackResult = await _trackData.GetPage(
pageNumber: 1, pageSize: 1, album: release.Title);
pageNumber: 1, pageSize: 1, releaseId: release.Id);
if (trackResult is { Success: true, Value: { Items: { } items } })
Track = items.FirstOrDefault();
}