Fix Wing It sync live status and button persistence across all modals
Live status: updateYouTubeModalSyncProgress was hardcoded to youtube-* element IDs but each source uses its own prefix (listenbrainz-*, tidal-*, deezer-*, etc). Now tries all prefixes to find the correct elements. Fixes Wing It sync progress AND a pre-existing bug where normal LB/Tidal sync from the modal wouldn't show live progress. Wing It button added to sync_complete phase so it persists after sync. Fixed tracks lookup with state.playlist?.tracks fallback. Increased button size in modal to match other action buttons.
This commit is contained in:
parent
3c19cc085b
commit
a9dd93b176
2 changed files with 75 additions and 19 deletions
|
|
@ -11805,11 +11805,11 @@ function _pollWingItSyncProgress(syncPlaylistId, playlistName, cardPlaylistId) {
|
|||
setTimeout(() => clearInterval(poll), 180000);
|
||||
}
|
||||
|
||||
function _wingItFromModal(urlHash) {
|
||||
// Extract tracks from the discovery modal state
|
||||
async function _wingItFromModal(urlHash) {
|
||||
// Extract tracks from the discovery modal state — tracks can be in various locations
|
||||
const state = listenbrainzPlaylistStates[urlHash] || youtubePlaylistStates[urlHash] || {};
|
||||
const tracks = state.tracks || state.rawTracks || [];
|
||||
const name = state.playlistName || state.name || 'Playlist';
|
||||
const tracks = state.tracks || state.rawTracks || state.playlist?.tracks || [];
|
||||
const name = state.playlistName || state.name || state.playlist?.name || 'Playlist';
|
||||
const isTidal = state.is_tidal_playlist;
|
||||
const isLB = state.is_listenbrainz_playlist;
|
||||
const isBeatport = state.is_beatport_playlist;
|
||||
|
|
@ -11821,7 +11821,56 @@ function _wingItFromModal(urlHash) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Close the discovery modal first
|
||||
const choice = await _showWingItChoiceDialog(tracks.length, source);
|
||||
if (!choice) return;
|
||||
|
||||
if (choice === 'sync') {
|
||||
// Sync inline — keep modal open, show progress in modal
|
||||
showToast('Starting Wing It sync...', 'info');
|
||||
updateYouTubeModalButtons(urlHash, 'syncing');
|
||||
|
||||
try {
|
||||
// Format and send sync request
|
||||
const syncTracks = tracks.map((t, i) => {
|
||||
let artists = t.artists || [];
|
||||
if (!Array.isArray(artists)) artists = [{ name: String(artists) }];
|
||||
return {
|
||||
id: t.id || t.source_track_id || `wing_it_${i}`,
|
||||
name: t.name || t.track_name || 'Unknown',
|
||||
artists: artists.map(a => typeof a === 'string' ? { name: a } : a),
|
||||
album: typeof t.album === 'object' ? t.album : { name: t.album || t.album_name || '' },
|
||||
duration_ms: t.duration_ms || 0,
|
||||
};
|
||||
});
|
||||
|
||||
const res = await fetch('/api/wing-it/sync', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ tracks: syncTracks, playlist_name: name })
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
if (data.error) {
|
||||
showToast(`Sync failed: ${data.error}`, 'error');
|
||||
updateYouTubeModalButtons(urlHash, 'discovered');
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the same sync polling as normal sync — works for any source
|
||||
if (isLB) {
|
||||
if (state) state.syncPlaylistId = data.sync_playlist_id;
|
||||
startListenBrainzSyncPolling(urlHash, data.sync_playlist_id);
|
||||
} else {
|
||||
startYouTubeSyncPolling(urlHash, data.sync_playlist_id);
|
||||
}
|
||||
} catch (e) {
|
||||
showToast('Sync failed: ' + e.message, 'error');
|
||||
updateYouTubeModalButtons(urlHash, 'discovered');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// choice === 'download' — close modal and open download modal
|
||||
const modal = document.getElementById(`youtube-discovery-modal-${urlHash}`);
|
||||
if (modal) modal.remove();
|
||||
const overlay = document.getElementById(`youtube-discovery-overlay-${urlHash}`);
|
||||
|
|
@ -30970,6 +31019,9 @@ function getModalActionButtons(urlHash, phase, state = null) {
|
|||
syncCompleteButtons += `<button class="modal-btn modal-btn-secondary" onclick="resetYouTubePlaylist('${urlHash}')">🔄 Rediscover</button>`;
|
||||
}
|
||||
|
||||
// Wing It button
|
||||
syncCompleteButtons += ` <button class="modal-btn wing-it-btn" onclick="_wingItFromModal('${urlHash}')">⚡ Wing It</button>`;
|
||||
|
||||
return syncCompleteButtons;
|
||||
|
||||
case 'download_complete':
|
||||
|
|
@ -31617,16 +31669,20 @@ function updateYouTubeCardSyncProgress(urlHash, progress) {
|
|||
}
|
||||
|
||||
function updateYouTubeModalSyncProgress(urlHash, progress) {
|
||||
const statusDisplay = document.getElementById(`youtube-sync-status-${urlHash}`);
|
||||
// Try all source-specific element ID prefixes
|
||||
const prefixes = ['youtube', 'listenbrainz', 'tidal', 'deezer', 'spotify-public', 'beatport'];
|
||||
let statusDisplay = null;
|
||||
let prefix = 'youtube';
|
||||
for (const p of prefixes) {
|
||||
statusDisplay = document.getElementById(`${p}-sync-status-${urlHash}`);
|
||||
if (statusDisplay) { prefix = p; break; }
|
||||
}
|
||||
if (!statusDisplay || !progress) return;
|
||||
|
||||
console.log(`📊 Updating YouTube modal sync progress for ${urlHash}:`, progress);
|
||||
|
||||
// Update individual counters exactly like Spotify sync
|
||||
const totalEl = document.getElementById(`youtube-total-${urlHash}`);
|
||||
const matchedEl = document.getElementById(`youtube-matched-${urlHash}`);
|
||||
const failedEl = document.getElementById(`youtube-failed-${urlHash}`);
|
||||
const percentageEl = document.getElementById(`youtube-percentage-${urlHash}`);
|
||||
const totalEl = document.getElementById(`${prefix}-total-${urlHash}`);
|
||||
const matchedEl = document.getElementById(`${prefix}-matched-${urlHash}`);
|
||||
const failedEl = document.getElementById(`${prefix}-failed-${urlHash}`);
|
||||
const percentageEl = document.getElementById(`${prefix}-percentage-${urlHash}`);
|
||||
|
||||
const total = progress.total_tracks || 0;
|
||||
const matched = progress.matched_tracks || 0;
|
||||
|
|
|
|||
|
|
@ -5171,18 +5171,18 @@ body.helper-mode-active #dashboard-activity-feed:hover {
|
|||
|
||||
/* ── Wing It Button ── */
|
||||
.wing-it-btn {
|
||||
background: transparent !important;
|
||||
background: rgba(255, 183, 77, 0.08) !important;
|
||||
border: 1px solid rgba(255, 183, 77, 0.3) !important;
|
||||
color: #ffb74d !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
padding: 6px 14px !important;
|
||||
border-radius: 8px !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 700 !important;
|
||||
padding: 10px 20px !important;
|
||||
border-radius: 10px !important;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.wing-it-btn:hover {
|
||||
background: rgba(255, 183, 77, 0.1) !important;
|
||||
background: rgba(255, 183, 77, 0.15) !important;
|
||||
border-color: rgba(255, 183, 77, 0.5) !important;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue