mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
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:
@@ -1760,7 +1760,7 @@
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="track-item">
|
||||
<div class="track-item" data-position="${t.position}">
|
||||
<span class="track-position">${t.position + 1}</span>
|
||||
<div class="track-info">
|
||||
<h4>${escapeHtml(t.title)}${statusBadge}${mapButton}</h4>
|
||||
@@ -2021,6 +2021,7 @@
|
||||
const playlistName = document.getElementById('map-playlist-name').value;
|
||||
const spotifyId = document.getElementById('map-spotify-id').value;
|
||||
const jellyfinId = document.getElementById('map-selected-jellyfin-id').value;
|
||||
const position = parseInt(document.getElementById('map-position').textContent) - 1; // Convert back to 0-indexed
|
||||
|
||||
if (!jellyfinId) {
|
||||
showToast('Please select a track', 'error');
|
||||
@@ -2037,10 +2038,43 @@
|
||||
const data = await res.json();
|
||||
|
||||
if (res.ok) {
|
||||
showToast('Track mapped successfully! Refresh the playlist to see changes.', 'success');
|
||||
showToast('✓ Track mapped successfully', 'success');
|
||||
closeModal('manual-map-modal');
|
||||
// Refresh the tracks view
|
||||
viewTracks(playlistName);
|
||||
|
||||
// Update the track in the UI without refreshing
|
||||
if (data.track) {
|
||||
const trackItem = document.querySelector(`.track-item[data-position="${position}"]`);
|
||||
if (trackItem) {
|
||||
// Update the track info
|
||||
const titleEl = trackItem.querySelector('.track-info h4');
|
||||
const artistEl = trackItem.querySelector('.track-info .artists');
|
||||
const statusBadge = trackItem.querySelector('.status-badge');
|
||||
const mapButton = trackItem.querySelector('.map-track-btn');
|
||||
const searchLink = trackItem.querySelector('.track-meta a');
|
||||
|
||||
if (titleEl) {
|
||||
// Remove the old status badge and map button, add new content
|
||||
const titleText = data.track.title;
|
||||
const newStatusBadge = '<span class="status-badge success" style="font-size:0.75rem;padding:2px 8px;margin-left:8px;"><span class="status-dot"></span>Local</span>';
|
||||
titleEl.innerHTML = escapeHtml(titleText) + newStatusBadge;
|
||||
}
|
||||
|
||||
if (artistEl) artistEl.textContent = data.track.artist;
|
||||
|
||||
// Remove the search link since it's now local
|
||||
if (searchLink) {
|
||||
const metaEl = trackItem.querySelector('.track-meta');
|
||||
if (metaEl) {
|
||||
// Keep album and ISRC, remove search link
|
||||
const albumText = data.track.album ? escapeHtml(data.track.album) : '';
|
||||
metaEl.innerHTML = albumText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also refresh the playlist counts in the background
|
||||
fetchPlaylists();
|
||||
} else {
|
||||
showToast(data.error || 'Failed to save mapping', 'error');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user