From e14a317a565d6a80badbdcb458bb1255919718df Mon Sep 17 00:00:00 2001 From: Broque Thomas Date: Thu, 26 Feb 2026 17:19:34 -0800 Subject: [PATCH] Add wishlist batch remove API and UI Introduce batch removal support for wishlist tracks. Adds a new POST endpoint /api/wishlist/remove-batch that validates input, removes multiple tracks via the wishlist service, logs the result and returns a removed count. Updates the frontend (webui/static/script.js) to provide per-track and per-album checkboxes, a Select All button, a batch action bar with selection count and a Remove Selected action (with confirmation), and logic to refresh the view and wishlist count after removal. Styles (webui/static/style.css) are extended to support unified watchlist/wishlist batch bars, checkbox styling, and a Select All button. Preserves existing single-item removal behavior. --- web_server.py | 29 ++++++++ webui/static/script.js | 154 +++++++++++++++++++++++++++++++++++++++++ webui/static/style.css | 58 ++++++++++++---- 3 files changed, 229 insertions(+), 12 deletions(-) diff --git a/web_server.py b/web_server.py index baba3a60..a9ef1024 100644 --- a/web_server.py +++ b/web_server.py @@ -13054,6 +13054,35 @@ def remove_album_from_wishlist(): logger.error(f"Error removing album from wishlist: {e}") return jsonify({"success": False, "error": str(e)}), 500 +@app.route('/api/wishlist/remove-batch', methods=['POST']) +def remove_batch_from_wishlist(): + """Endpoint to remove multiple tracks from the wishlist.""" + try: + from core.wishlist_service import get_wishlist_service + + data = request.get_json() + spotify_track_ids = data.get('spotify_track_ids', []) + + if not spotify_track_ids or not isinstance(spotify_track_ids, list): + return jsonify({"success": False, "error": "Missing or invalid spotify_track_ids"}), 400 + + wishlist_service = get_wishlist_service() + removed = 0 + for track_id in spotify_track_ids: + if wishlist_service.remove_track_from_wishlist(track_id): + removed += 1 + + logger.info(f"Batch removed {removed} track(s) from wishlist") + return jsonify({ + "success": True, + "removed": removed, + "message": f"Removed {removed} track{'s' if removed != 1 else ''} from wishlist" + }) + + except Exception as e: + logger.error(f"Error batch removing from wishlist: {e}") + return jsonify({"success": False, "error": str(e)}), 500 + @app.route('/api/add-album-to-wishlist', methods=['POST']) def add_album_track_to_wishlist(): """Endpoint to add a single track from an album to the wishlist.""" diff --git a/webui/static/script.js b/webui/static/script.js index a3367176..43a36010 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -6995,6 +6995,14 @@ async function openWishlistOverviewModal() {
+ +
+
Loading tracks...
@@ -7312,6 +7320,12 @@ async function selectWishlistCategory(category) { const tracksListHTML = albumData.tracks.map(track => `
+ ${track.name}