Show which tracks failed to match in sync completion toast
When a playlist sync has unmatched tracks sent to wishlist, the completion toast now shows the specific track names instead of just a count. Uses warning style so it stands out. The unmatched track list is included in the sync state result so it's available for both live status polling and notification history. Addresses #272 — silent sync failures where users couldn't tell which tracks out of 150+ failed to match their Plex library.
This commit is contained in:
parent
df14bbf745
commit
7d21385ce9
2 changed files with 15 additions and 2 deletions
|
|
@ -36657,12 +36657,21 @@ def _run_sync_task(playlist_id, playlist_name, tracks_json, automation_id=None,
|
|||
|
||||
# Update final state on completion
|
||||
# Convert result to JSON-serializable dict (datetime/errors can't be emitted via SocketIO)
|
||||
# Exclude match_details — large, not needed for live status, saved to DB separately
|
||||
# Exclude match_details (large) but include a summary of unmatched tracks
|
||||
result_dict = {
|
||||
k: (v.isoformat() if hasattr(v, 'isoformat') else v)
|
||||
for k, v in result.__dict__.items()
|
||||
if k != 'match_details'
|
||||
}
|
||||
# Include unmatched track names so the frontend can show which tracks failed
|
||||
match_details = getattr(result, 'match_details', None)
|
||||
if match_details:
|
||||
unmatched_summary = [
|
||||
{'name': d.get('name', ''), 'artist': d.get('artist', ''), 'image_url': d.get('image_url', '')}
|
||||
for d in match_details if d.get('status') == 'not_found'
|
||||
]
|
||||
if unmatched_summary:
|
||||
result_dict['unmatched_tracks'] = unmatched_summary
|
||||
with sync_lock:
|
||||
sync_states[playlist_id] = {
|
||||
"status": "finished",
|
||||
|
|
|
|||
|
|
@ -16296,9 +16296,13 @@ function updateCardToDefault(playlistId, finalState = null) {
|
|||
|
||||
// Check if any tracks were added to wishlist
|
||||
const wishlistCount = finalState.progress?.wishlist_added_count || finalState.result?.wishlist_added_count || 0;
|
||||
const unmatchedTracks = finalState.progress?.unmatched_tracks || finalState.result?.unmatched_tracks || [];
|
||||
const playlistName = card.querySelector('.playlist-card-name').textContent;
|
||||
|
||||
if (wishlistCount > 0) {
|
||||
if (wishlistCount > 0 && unmatchedTracks.length > 0) {
|
||||
const trackList = unmatchedTracks.map(t => `${t.artist} - ${t.name}`).join(', ');
|
||||
showToast(`Sync complete for "${playlistName}". ${wishlistCount} not found in library: ${trackList}`, 'warning');
|
||||
} else if (wishlistCount > 0) {
|
||||
showToast(`Sync complete for "${playlistName}". Added ${wishlistCount} missing track${wishlistCount > 1 ? 's' : ''} to wishlist.`, 'success');
|
||||
} else {
|
||||
showToast(`Sync complete for "${playlistName}"`, 'success');
|
||||
|
|
|
|||
Loading…
Reference in a new issue