diff --git a/web_server.py b/web_server.py
index 92332780..e8497605 100644
--- a/web_server.py
+++ b/web_server.py
@@ -28875,7 +28875,7 @@ def _on_download_completed(batch_id, task_id, success=True):
'listenbrainz_', 'beatport_',
)
if playlist_id and playlist_id.startswith(_push_prefixes):
- database.update_sync_history_push_status(batch_id, 'pending')
+ get_database().update_sync_history_push_status(batch_id, 'pending')
threading.Thread(
target=_push_playlist_to_server,
args=(batch_id, batch),
@@ -31148,6 +31148,8 @@ def start_playlist_missing_downloads(playlist_id):
'active_count': 0,
'max_concurrent': _get_max_concurrent(),
'queue_index': 0,
+ 'playlist_id': playlist_id,
+ 'playlist_name': playlist_name,
# Track state management (replicating sync.py)
'permanently_failed_tracks': [],
'cancelled_tracks': set(),
@@ -32285,7 +32287,7 @@ def _check_batch_completion_v2(batch_id):
'listenbrainz_', 'beatport_',
)
if playlist_id and playlist_id.startswith(_push_prefixes):
- database.update_sync_history_push_status(batch_id, 'pending')
+ get_database().update_sync_history_push_status(batch_id, 'pending')
threading.Thread(
target=_push_playlist_to_server,
args=(batch_id, batch),
@@ -33691,6 +33693,8 @@ def start_missing_downloads():
'active_count': 0,
'max_concurrent': _get_max_concurrent(),
'queue_index': 0,
+ 'playlist_id': playlist_id,
+ 'playlist_name': 'Legacy Modal',
# Track state management (replicating sync.py)
'permanently_failed_tracks': [],
'cancelled_tracks': set(),
diff --git a/webui/static/pages-extra.js b/webui/static/pages-extra.js
index 8bea349e..66f42170 100644
--- a/webui/static/pages-extra.js
+++ b/webui/static/pages-extra.js
@@ -2881,10 +2881,24 @@ function _adlRenderBatchHistory() {
const dotTip = dotSource ? `Source: ${dotSource}` : 'Unknown source';
const histDot = ``;
- // Thumbnail with placeholder fallback
+ // Thumbnail with playlist-type icon fallback
+ let placeholderIcon = '♫';
+ const pName = (h.playlist_name || '').toLowerCase();
+ if (pName.includes('fresh tape') || pName.includes('release radar')) placeholderIcon = '🎵';
+ else if (pName.includes('archives') || pName.includes('discovery weekly')) placeholderIcon = '📚';
+ else if (pName.includes('seasonal')) placeholderIcon = '🌿';
+ else if (pName.includes('popular picks')) placeholderIcon = '🔥';
+ else if (pName.includes('hidden gems')) placeholderIcon = '💎';
+ else if (pName.includes('discovery shuffle')) placeholderIcon = '🔀';
+ else if (pName.includes('familiar fav')) placeholderIcon = '❤️';
+ else if (pName.includes('jam')) placeholderIcon = '🎸';
+ else if (pName.includes('explor')) placeholderIcon = '🔭';
+ else if (dotSource === 'mirrored' || dotSource === 'youtube') placeholderIcon = '🔗';
+ else if (dotSource === 'wishlist') placeholderIcon = '⭐';
+ else if (dotSource === 'album') placeholderIcon = '💿';
const thumb = h.thumb_url
- ? `
`
- : ``;
+ ? `
`
+ : `${placeholderIcon}`;
// Server push status indicator
let pushBadge = '';
diff --git a/webui/static/style.css b/webui/static/style.css
index 5c33bf53..6323de6f 100644
--- a/webui/static/style.css
+++ b/webui/static/style.css
@@ -57206,9 +57206,10 @@ body.reduce-effects *::after {
justify-content: center;
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.06);
+ font-size: 14px;
}
-.adl-batch-history-thumb-placeholder::after {
+.adl-batch-history-thumb-placeholder:empty::after {
content: '♫';
font-size: 12px;
color: rgba(255, 255, 255, 0.2);