From 1ed66c120eea926102c2a9b2dc0bcb6473298cc6 Mon Sep 17 00:00:00 2001 From: Broque Thomas Date: Mon, 16 Feb 2026 14:42:17 -0800 Subject: [PATCH] Fix Soulseek connection status showing false positive on test The Soulseek "Test Connection" button could report success while the dashboard status remained "Disconnected" because the status endpoint only checked if slskd was configured (is_configured()), not actually reachable (check_connection()). Switched to a real connection check with TTL caching (matching the existing Spotify/media server pattern), update the status cache after successful tests, and refresh the UI immediately on success. --- web_server.py | 35 ++++++++++++++++++++++------------- webui/static/script.js | 2 ++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/web_server.py b/web_server.py index e01f5a1a..71a4799f 100644 --- a/web_server.py +++ b/web_server.py @@ -2095,19 +2095,26 @@ def get_status(): _status_cache_timestamps['media_server'] = current_time # else: use cached value - # Test Soulseek - just check if configured (instant, no network test) - # This is so fast we don't need to cache it - soulseek_start = time.time() - soulseek_status = soulseek_client.is_configured() - soulseek_response_time = (time.time() - soulseek_start) * 1000 + # Test Soulseek - with caching like other services + if current_time - _status_cache_timestamps['soulseek'] > STATUS_CACHE_TTL: + soulseek_start = time.time() + try: + async def _check_soulseek(): + return await soulseek_client.check_connection() + soulseek_status = asyncio.run(_check_soulseek()) + except Exception: + soulseek_status = False + soulseek_response_time = (time.time() - soulseek_start) * 1000 + _status_cache['soulseek'] = { + 'connected': soulseek_status, + 'response_time': round(soulseek_response_time, 1) + } + _status_cache_timestamps['soulseek'] = current_time status_data = { 'spotify': _status_cache['spotify'], 'media_server': _status_cache['media_server'], - 'soulseek': { - 'connected': soulseek_status, - 'response_time': round(soulseek_response_time, 1) - }, + 'soulseek': _status_cache['soulseek'], 'active_media_server': active_server } return jsonify(status_data) @@ -2497,8 +2504,9 @@ def test_connection_endpoint(): _status_cache_timestamps['media_server'] = current_time print(f"✅ Updated {service} status cache after successful test") elif service == 'soulseek': - # Soulseek doesn't use cache, but update anyway for consistency - print("✅ Soulseek test successful") + _status_cache['soulseek']['connected'] = True + _status_cache_timestamps['soulseek'] = current_time + print("✅ Updated Soulseek status cache after successful test") elif service == 'listenbrainz': print("✅ ListenBrainz test successful") @@ -2545,8 +2553,9 @@ def test_dashboard_connection_endpoint(): _status_cache_timestamps['media_server'] = current_time print(f"✅ Updated {service} status cache after successful dashboard test") elif service == 'soulseek': - # Soulseek doesn't use cache, but log anyway for consistency - print("✅ Soulseek dashboard test successful") + _status_cache['soulseek']['connected'] = True + _status_cache_timestamps['soulseek'] = current_time + print("✅ Updated Soulseek status cache after successful dashboard test") # Add activity for dashboard connection test (different from settings test) if success: diff --git a/webui/static/script.js b/webui/static/script.js index ddd41aee..bd8700f4 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -2290,6 +2290,8 @@ async function testDashboardConnection(service) { if (result.success) { // Use backend's message which contains dynamic source name (Spotify or Apple Music) showToast(result.message || `${service} service verified`, 'success'); + // Refresh status indicators immediately so UI reflects the new state + fetchAndUpdateServiceStatus(); } else { showToast(`${service} service check failed: ${result.error}`, 'error'); }