feat: instant UI update after manual track mapping

- Backend now returns mapped track details after saving
- Frontend updates track in-place without requiring page refresh
- Track status changes from External to Local immediately
- Map button is removed after successful mapping
- Playlist counts refresh in background
- Improved UX: no more 'refresh the playlist' message

All 225 tests pass.
This commit is contained in:
2026-02-04 17:44:57 -05:00
parent 7bb7c6a40e
commit 506f39d606
2 changed files with 69 additions and 4 deletions

View File

@@ -656,6 +656,37 @@ public class AdminController : ControllerBase
_logger.LogInformation("Cleared playlist caches for {Playlist} to force rebuild", decodedName);
// Fetch the mapped Jellyfin track details to return to the UI
try
{
var trackUrl = $"{_jellyfinSettings.Url}/Items/{request.JellyfinId}?api_key={_jellyfinSettings.ApiKey}";
var response = await _jellyfinHttpClient.GetAsync(trackUrl);
if (response.IsSuccessStatusCode)
{
var trackData = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(trackData);
var track = doc.RootElement;
var mappedTrack = new
{
id = request.JellyfinId,
title = track.TryGetProperty("Name", out var nameEl) ? nameEl.GetString() : "",
artist = track.TryGetProperty("AlbumArtist", out var artistEl) ? artistEl.GetString() :
(track.TryGetProperty("Artists", out var artistsEl) && artistsEl.GetArrayLength() > 0
? artistsEl[0].GetString() : ""),
album = track.TryGetProperty("Album", out var albumEl) ? albumEl.GetString() : "",
isLocal = true
};
return Ok(new { message = "Mapping saved successfully", track = mappedTrack });
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to fetch mapped track details, but mapping was saved");
}
return Ok(new { message = "Mapping saved successfully" });
}
catch (Exception ex)