Enhance wishlist auto-processing detection and UI feedback
Added backend support for reporting current auto-processing state and cycle in the wishlist stats API. Updated frontend to detect and handle auto-processing start, close modals, and notify users, as well as improved countdown timer updates and conflict handling when starting manual processing.
This commit is contained in:
parent
2ede3ddee7
commit
fb56fbca5f
2 changed files with 70 additions and 21 deletions
|
|
@ -9466,17 +9466,33 @@ def get_wishlist_stats():
|
||||||
|
|
||||||
total_count = singles_count + albums_count
|
total_count = singles_count + albums_count
|
||||||
|
|
||||||
# Calculate time until next auto-processing
|
# Calculate time until next auto-processing and get processing state
|
||||||
next_run_in_seconds = 0
|
next_run_in_seconds = 0
|
||||||
|
is_processing = False
|
||||||
with wishlist_timer_lock:
|
with wishlist_timer_lock:
|
||||||
if wishlist_next_run_time > 0:
|
if wishlist_next_run_time > 0:
|
||||||
next_run_in_seconds = max(0, int(wishlist_next_run_time - time.time()))
|
next_run_in_seconds = max(0, int(wishlist_next_run_time - time.time()))
|
||||||
|
is_processing = wishlist_auto_processing
|
||||||
|
|
||||||
|
# Get current cycle (albums or singles)
|
||||||
|
from database.music_database import MusicDatabase
|
||||||
|
db = MusicDatabase()
|
||||||
|
try:
|
||||||
|
with db._get_connection() as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SELECT value FROM metadata WHERE key = 'wishlist_cycle'")
|
||||||
|
row = cursor.fetchone()
|
||||||
|
current_cycle = row['value'] if row else 'albums'
|
||||||
|
except Exception:
|
||||||
|
current_cycle = 'albums' # Safe fallback
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"singles": singles_count,
|
"singles": singles_count,
|
||||||
"albums": albums_count,
|
"albums": albums_count,
|
||||||
"total": total_count,
|
"total": total_count,
|
||||||
"next_run_in_seconds": next_run_in_seconds
|
"next_run_in_seconds": next_run_in_seconds,
|
||||||
|
"is_auto_processing": is_processing,
|
||||||
|
"current_cycle": current_cycle
|
||||||
})
|
})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -6352,34 +6352,44 @@ function startWishlistCountdownTimer(currentCycle, initialSeconds) {
|
||||||
wishlistCountdownInterval = setInterval(async () => {
|
wishlistCountdownInterval = setInterval(async () => {
|
||||||
remainingSeconds--;
|
remainingSeconds--;
|
||||||
|
|
||||||
if (remainingSeconds <= 0) {
|
// Check if auto-processing has started (every 2 seconds to avoid overwhelming backend)
|
||||||
// Timer expired, fetch fresh data
|
if (remainingSeconds % 2 === 0 || remainingSeconds <= 0) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/wishlist/stats');
|
const response = await fetch('/api/wishlist/stats');
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
remainingSeconds = data.next_run_in_seconds || 0;
|
|
||||||
|
|
||||||
// Also update cycle in case it changed
|
// AUTO-CLOSE DETECTION: If auto-processing started, close modal and notify user
|
||||||
const cycleResponse = await fetch('/api/wishlist/cycle');
|
if (data.is_auto_processing) {
|
||||||
const cycleData = await cycleResponse.json();
|
console.log('🤖 [Wishlist] Auto-processing detected, closing overview modal');
|
||||||
const newCycle = cycleData.cycle || 'albums';
|
closeWishlistOverviewModal();
|
||||||
const newCycleText = newCycle === 'albums' ? 'Albums/EPs' : 'Singles';
|
showToast('Wishlist auto-processing started. View progress in Download Manager.', 'info');
|
||||||
|
return; // Exit interval
|
||||||
|
}
|
||||||
|
|
||||||
const timerElement = document.getElementById('wishlist-next-auto-timer');
|
// Update remaining seconds if timer expired
|
||||||
if (timerElement) {
|
if (remainingSeconds <= 0) {
|
||||||
const countdownText = formatCountdownTime(remainingSeconds);
|
remainingSeconds = data.next_run_in_seconds || 0;
|
||||||
timerElement.textContent = `Next Auto: ${newCycleText}${countdownText ? ' in ' + countdownText : ''}`;
|
|
||||||
|
// Also update cycle in case it changed
|
||||||
|
const newCycle = data.current_cycle || 'albums';
|
||||||
|
const newCycleText = newCycle === 'albums' ? 'Albums/EPs' : 'Singles';
|
||||||
|
|
||||||
|
const timerElement = document.getElementById('wishlist-next-auto-timer');
|
||||||
|
if (timerElement) {
|
||||||
|
const countdownText = formatCountdownTime(remainingSeconds);
|
||||||
|
timerElement.textContent = `Next Auto: ${newCycleText}${countdownText ? ' in ' + countdownText : ''}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.debug('Error updating wishlist countdown:', error);
|
console.debug('Error updating wishlist countdown:', error);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// Update the display
|
|
||||||
const timerElement = document.getElementById('wishlist-next-auto-timer');
|
// Always update the display countdown
|
||||||
if (timerElement) {
|
const timerElement = document.getElementById('wishlist-next-auto-timer');
|
||||||
const countdownText = formatCountdownTime(remainingSeconds);
|
if (timerElement) {
|
||||||
timerElement.textContent = `Next Auto: ${nextCycleText}${countdownText ? ' in ' + countdownText : ''}`;
|
const countdownText = formatCountdownTime(remainingSeconds);
|
||||||
}
|
timerElement.textContent = `Next Auto: ${nextCycleText}${countdownText ? ' in ' + countdownText : ''}`;
|
||||||
}
|
}
|
||||||
}, 1000); // Update every second
|
}, 1000); // Update every second
|
||||||
}
|
}
|
||||||
|
|
@ -7129,6 +7139,29 @@ async function startWishlistMissingTracksProcess(playlistId) {
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (!data.success) {
|
if (!data.success) {
|
||||||
|
// Special handling for auto-processing conflict
|
||||||
|
if (response.status === 409) {
|
||||||
|
console.log('🤖 [Wishlist] Auto-processing is running, redirecting to download manager');
|
||||||
|
showToast('Wishlist auto-processing is already running. Opening Download Manager...', 'info');
|
||||||
|
|
||||||
|
// Close wishlist modal and show download manager
|
||||||
|
const wishlistModal = document.getElementById('download-modal-wishlist');
|
||||||
|
if (wishlistModal) {
|
||||||
|
wishlistModal.remove();
|
||||||
|
}
|
||||||
|
delete activeDownloadProcesses[playlistId];
|
||||||
|
|
||||||
|
// Open download manager to show active batch
|
||||||
|
setTimeout(() => {
|
||||||
|
const downloadManager = document.getElementById('download-manager-modal');
|
||||||
|
if (downloadManager) {
|
||||||
|
downloadManager.style.display = 'flex';
|
||||||
|
} else {
|
||||||
|
openDownloadManagerModal();
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Special handling for rate limit
|
// Special handling for rate limit
|
||||||
if (response.status === 429) {
|
if (response.status === 429) {
|
||||||
throw new Error(`${data.error} Try closing some other download processes first.`);
|
throw new Error(`${data.error} Try closing some other download processes first.`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue