Fix Discover synced playlists not appearing under Server Playlists

Server Playlists was filtered to only show playlists matching mirrored_playlists entries,
but Discover syncs are stored in sync_history (not mirrored_playlists), so they were
excluded. Adds GET /api/sync/history/names returning distinct synced playlist names,
and includes those in the filter alongside mirrored playlists.
This commit is contained in:
Broque Thomas 2026-04-14 08:24:44 -07:00
parent 61c6b6f3f9
commit 86621704fe
3 changed files with 34 additions and 5 deletions

View file

@ -10289,6 +10289,17 @@ class MusicDatabase:
logger.debug(f"Error deleting sync history entry: {e}") logger.debug(f"Error deleting sync history entry: {e}")
return False return False
def get_sync_history_playlist_names(self):
"""Return distinct playlist names ever synced (for server playlist filtering)."""
try:
conn = self._get_connection()
cursor = conn.cursor()
cursor.execute("SELECT DISTINCT playlist_name FROM sync_history WHERE playlist_name != ''")
return [row[0] for row in cursor.fetchall()]
except Exception as e:
logger.error(f"Error getting sync history playlist names: {e}")
return []
def get_sync_history_stats(self): def get_sync_history_stats(self):
"""Return counts grouped by source.""" """Return counts grouped by source."""
try: try:

View file

@ -30405,6 +30405,16 @@ def delete_sync_history_entry_api(entry_id):
except Exception as e: except Exception as e:
return jsonify({"success": False, "error": str(e)}), 500 return jsonify({"success": False, "error": str(e)}), 500
@app.route('/api/sync/history/names', methods=['GET'])
def get_sync_history_playlist_names():
"""Return distinct playlist names ever synced, for server playlist cross-reference."""
try:
db = MusicDatabase()
names = db.get_sync_history_playlist_names()
return jsonify(names)
except Exception as e:
return jsonify([])
# =============================== # ===============================
# == UNIFIED MISSING TRACKS API == # == UNIFIED MISSING TRACKS API ==
# =============================== # ===============================

View file

@ -72385,31 +72385,39 @@ async function loadServerPlaylists() {
} }
try { try {
// Fetch server playlists and mirrored playlists in parallel // Fetch server playlists, mirrored playlists, and sync history names in parallel
const [serverRes, mirroredRes] = await Promise.all([ const [serverRes, mirroredRes, historyNamesRes] = await Promise.all([
fetch('/api/server/playlists'), fetch('/api/server/playlists'),
fetch('/api/mirrored-playlists'), fetch('/api/mirrored-playlists'),
fetch('/api/sync/history/names'),
]); ]);
const data = await serverRes.json(); const data = await serverRes.json();
let mirroredAll = []; let mirroredAll = [];
try { mirroredAll = await mirroredRes.json(); } catch (_) { } try { mirroredAll = await mirroredRes.json(); } catch (_) { }
if (!Array.isArray(mirroredAll)) mirroredAll = []; if (!Array.isArray(mirroredAll)) mirroredAll = [];
let historyNames = [];
try { historyNames = await historyNamesRes.json(); } catch (_) { }
if (!Array.isArray(historyNames)) historyNames = [];
if (!data.success || !data.playlists) { if (!data.success || !data.playlists) {
if (container) container.innerHTML = `<div class="playlist-placeholder">${data.error || 'Could not load server playlists'}</div>`; if (container) container.innerHTML = `<div class="playlist-placeholder">${data.error || 'Could not load server playlists'}</div>`;
return; return;
} }
// Only show server playlists that have a matching mirrored playlist // Only show server playlists that have a matching mirrored playlist or sync history entry
const mirroredNames = new Set(mirroredAll.map(p => p.name.trim().toLowerCase())); const mirroredNames = new Set(mirroredAll.map(p => p.name.trim().toLowerCase()));
const filtered = data.playlists.filter(pl => mirroredNames.has(pl.name.trim().toLowerCase())); const syncedNames = new Set(historyNames.map(n => n.trim().toLowerCase()));
const filtered = data.playlists.filter(pl => {
const key = pl.name.trim().toLowerCase();
return mirroredNames.has(key) || syncedNames.has(key);
});
_serverPlaylists = filtered; _serverPlaylists = filtered;
const title = document.getElementById('server-tab-title'); const title = document.getElementById('server-tab-title');
if (title) title.textContent = `Server Playlists (${data.server_type ? data.server_type.charAt(0).toUpperCase() + data.server_type.slice(1) : ''})`; if (title) title.textContent = `Server Playlists (${data.server_type ? data.server_type.charAt(0).toUpperCase() + data.server_type.slice(1) : ''})`;
if (filtered.length === 0) { if (filtered.length === 0) {
if (container) container.innerHTML = '<div class="playlist-placeholder">No synced playlists found. Only server playlists that match your mirrored playlists are shown here.</div>'; if (container) container.innerHTML = '<div class="playlist-placeholder">No synced playlists found. Only server playlists that have been synced via SoulSync are shown here.</div>';
return; return;
} }