@page "/tracks/mixes" @using DeepDrftManager.Services @using DeepDrftModels.DTOs @using DeepDrftModels.Enums @attribute [Authorize] @inject ICmsReleaseService CmsReleaseService @inject ISnackbar Snackbar @inject ILogger Logger Mixes — DeepDrft CMS Back to Release Archive Mixes @if (_loading) { } else if (_rows.Count == 0) { No mixes found. } else { Cover Mix Artist Waveform Actions @if (!string.IsNullOrEmpty(context.Release.ImagePath)) {
} else {
}
@context.Release.Title @context.Release.Artist @if (context.HasWaveform) { } else { } @if (context.IsGenerating) { Generating… } else { @(context.HasWaveform ? "Regenerate" : "Generate") }
}
@code { private List _rows = new(); private bool _loading = true; protected override async Task OnInitializedAsync() => await LoadAsync(); private async Task LoadAsync() { _loading = true; // Mixes are single-track releases; a single generous page covers the CMS catalogue. var result = await CmsReleaseService.GetPagedAsync( ReleaseMedium.Mix, page: 1, pageSize: 100, sortColumn: "Title", sortDescending: false); if (result.Success && result.Value is not null) { _rows = result.Value.Items .Select(r => new MixRow { Release = r, HasWaveform = !string.IsNullOrEmpty(r.MixMetadata?.WaveformEntryKey) }) .ToList(); } else { var error = result.Messages.FirstOrDefault()?.Message ?? "Unknown error"; Snackbar.Add($"Failed to load mixes: {error}", Severity.Error); _rows = new List(); } _loading = false; } // Relative path — resolves against the Manager's own origin, proxied by ImageProxyController. private static string ThumbUrl(string entryKey) => $"/api/image/{Uri.EscapeDataString(entryKey)}"; private async Task GenerateWaveformAsync(MixRow row) { row.IsGenerating = true; StateHasChanged(); try { var result = await CmsReleaseService.GenerateMixWaveformAsync(row.Release.Id); if (result.Success) { // Optimistic update: the trigger succeeded, so the waveform is stored. Unlike SessionBrowser's // re-fetch (which retrieves the server-generated HeroImageEntryKey), there is nothing to reflect // back here — HasWaveform is derived from WaveformEntryKey being non-null, which we know is now set. row.HasWaveform = true; Snackbar.Add($"Generated waveform for '{row.Release.Title}'.", Severity.Success); } else { var error = result.Messages.FirstOrDefault()?.Message ?? "Unknown error"; Snackbar.Add($"Waveform generation failed for '{row.Release.Title}': {error}", Severity.Error); } } catch (Exception ex) { Logger.LogError(ex, "Waveform generation failed for release {ReleaseId}", row.Release.Id); Snackbar.Add($"Waveform generation failed for '{row.Release.Title}' — please try again.", Severity.Error); } finally { row.IsGenerating = false; StateHasChanged(); } } private sealed class MixRow { public required ReleaseDto Release { get; set; } public bool HasWaveform { get; set; } public bool IsGenerating { get; set; } } }