diff --git a/web_server.py b/web_server.py index f9930be3..30e584e3 100644 --- a/web_server.py +++ b/web_server.py @@ -34,7 +34,7 @@ _log_path = config_manager.get('logging.path', 'logs/app.log') logger = setup_logging(_log_level, _log_path) # App version — single source of truth for backup metadata, version-info endpoint, etc. -SOULSYNC_VERSION = "2.3" +SOULSYNC_VERSION = "2.31" # Dedicated source reuse logger — writes to logs/source_reuse.log import logging as _logging @@ -22585,7 +22585,7 @@ def get_version_info(): ], }, { - "title": "Earlier in v2.2", + "title": "Earlier in v2.3", "description": "Major features from earlier in this release cycle", "features": [ "• Centralized Downloads page with live-updating list and filter pills", diff --git a/webui/static/helper.js b/webui/static/helper.js index d996cd1f..beaab24f 100644 --- a/webui/static/helper.js +++ b/webui/static/helper.js @@ -3599,7 +3599,7 @@ function closeHelperSearch() { // ═══════════════════════════════════════════════════════════════════════════ const WHATS_NEW = { - '2.2': [ + '2.31': [ // --- April 17, 2026 --- { date: 'April 17, 2026' }, { title: 'Auto-Import', desc: 'Background staging folder watcher that automatically identifies and imports music. Three strategies: audio tags, folder name parsing, and AcoustID fingerprinting. Confidence-gated: 90%+ auto-imports, 70-90% queued for review, below 70% left for manual. Enable on the Import page Auto tab', page: 'import' }, @@ -3695,12 +3695,12 @@ const WHATS_NEW = { function _getCurrentVersion() { const btn = document.querySelector('.version-button'); - return btn ? btn.textContent.trim().replace('v', '') : '2.2'; + return btn ? btn.textContent.trim().replace('v', '') : '2.31'; } function _getLatestWhatsNewVersion() { const versions = Object.keys(WHATS_NEW).sort((a, b) => parseFloat(b) - parseFloat(a)); - return versions[0] || '2.2'; + return versions[0] || '2.31'; } function openWhatsNew() { diff --git a/webui/static/script.js b/webui/static/script.js index 6cb2ad14..a9e48260 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -396,9 +396,15 @@ function handleServiceStatusUpdate(data) { // Update downloads nav badge from status push if (data.active_downloads !== undefined) _updateDlNavBadge(data.active_downloads); - // Hide sync nav button for standalone mode (no server to sync playlists to) + // Hide sync-related UI for standalone mode (no server to sync playlists to) + const isSoulsyncStandalone = data.media_server?.type === 'soulsync'; + _isSoulsyncStandalone = isSoulsyncStandalone; const syncNav = document.querySelector('[data-page="sync"]'); - if (syncNav) syncNav.style.display = (data.media_server?.type === 'soulsync') ? 'none' : ''; + if (syncNav) syncNav.style.display = isSoulsyncStandalone ? 'none' : ''; + // Hide all sync buttons across the app + document.querySelectorAll('.sync-to-server-btn, [id$="-sync-btn"], [onclick*="startPlaylistSync"], [onclick*="syncPlaylistToServer"], [onclick*="startDecadeSync"]').forEach(btn => { + btn.style.display = isSoulsyncStandalone ? 'none' : ''; + }); // Update enrichment service cards if (data.enrichment) renderEnrichmentCards(data.enrichment); @@ -11839,7 +11845,7 @@ function showPlaylistDetailsModal(playlist) { ? '📊 View Download Results' : '📥 Download Missing Tracks'} - + `; @@ -25417,6 +25423,7 @@ function updateLibraryStatusCard(dbStats) { // Track last service status for library card let _lastServiceStatus = null; +let _isSoulsyncStandalone = false; // Global flag: true when no media server (sync buttons hidden) const _origFetchServiceStatus = typeof fetchAndUpdateServiceStatus === 'function' ? fetchAndUpdateServiceStatus : null; function _capitalize(s) { return s ? s.charAt(0).toUpperCase() + s.slice(1) : ''; } @@ -27581,7 +27588,7 @@ function showDeezerArlPlaylistDetailsModal(playlist, originalDeezerPlaylistId) { - + `; @@ -37227,7 +37234,7 @@ async function openDownloadMissingModalForArtistAlbum(virtualPlaylistId, playlis Begin Analysis ${_isBeatportPlaylistId(virtualPlaylistId) ? ` - ` : ''}