diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml
index b6497acd..74359da5 100644
--- a/.github/workflows/docker-publish.yml
+++ b/.github/workflows/docker-publish.yml
@@ -6,7 +6,7 @@ on:
version_tag:
description: 'Version tag (e.g. 1.6, 1.7)'
required: true
- default: '2.1'
+ default: '2.2'
jobs:
build-and-push:
diff --git a/web_server.py b/web_server.py
index 6285b236..ee1502e0 100644
--- a/web_server.py
+++ b/web_server.py
@@ -32,7 +32,7 @@ from config.settings import config_manager
logger = get_logger("web_server")
# App version — single source of truth for backup metadata, version-info endpoint, etc.
-SOULSYNC_VERSION = "2.1"
+SOULSYNC_VERSION = "2.2"
# Dedicated source reuse logger — writes to logs/source_reuse.log
import logging as _logging
@@ -20014,6 +20014,20 @@ def get_version_info():
"title": "What's New in SoulSync",
"subtitle": f"Version {SOULSYNC_VERSION} — Latest Changes",
"sections": [
+ {
+ "title": "⚡ Wing It — Download or Sync Without Discovery",
+ "description": "Bypass metadata discovery and use raw track names directly",
+ "features": [
+ "• Wing It button on all discovery modals and ListenBrainz Discover page cards",
+ "• Choose Download or Sync from a compact dropdown — no extra dialogs",
+ "• Download: sends raw artist/title to the download engine with full post-processing",
+ "• Sync: creates playlist on media server by matching raw names against library",
+ "• Failed tracks are NOT added to wishlist — clean wing-it behavior",
+ "• Live sync progress displayed inline just like normal sync",
+ "• Download creates a bubble on the dashboard for progress tracking"
+ ],
+ "usage_note": "Click the ⚡ Wing It button next to Start Discovery or Download Missing in any playlist modal."
+ },
{
"title": "🔔 Redesigned Notification System",
"description": "Modern compact toasts with notification history and bell button",
diff --git a/webui/index.html b/webui/index.html
index 7d6d45a7..17916c83 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -306,7 +306,7 @@
-
+
diff --git a/webui/static/helper.js b/webui/static/helper.js
index 87d03ae2..5e9f3cd5 100644
--- a/webui/static/helper.js
+++ b/webui/static/helper.js
@@ -3401,10 +3401,13 @@ function closeHelperSearch() {
// ═══════════════════════════════════════════════════════════════════════════
const WHATS_NEW = {
- '2.1': [
+ '2.2': [
// Newest features first
+ { title: 'Wing It Mode', desc: 'Download or sync playlists without metadata discovery — uses raw track names directly. Great for obscure tracks not on Spotify/iTunes' },
{ title: 'Redesigned Notifications', desc: 'Compact pill toasts, notification bell with unread badge, history panel with last 50 notifications and Learn More links' },
{ title: 'Track Redownload & Source Info', desc: 'Fix mismatched downloads — search all metadata and download sources in columns, pick the right version, auto-replace. Source Info shows where tracks came from with blacklist option', page: 'library' },
+ { title: 'Fix Hybrid Download Mode', desc: 'Hybrid mode now tries fallback sources when primary source results all fail quality filtering (#235)' },
+ { title: 'Fix Discovery Progress Display', desc: 'Discovery modals (YouTube, Tidal, ListenBrainz, Beatport) now show live progress instead of staying on Pending' },
{ title: 'Spotify API Rate Limit Improvements', desc: 'Cached get_artist_albums, eliminated duplicate search calls, auth probe reduced 66%, enrichment workers auto-pause during downloads' },
{ title: 'Server Playlist Manager', desc: 'Compare source playlists against your media server — find missing tracks, swap wrong matches, remove extras with a dual-column editor', page: 'sync' },
{ title: 'Sync History Dashboard', desc: 'Dashboard shows recent syncs as cards — click for per-track match details with confidence scores and album art' },
@@ -3454,12 +3457,12 @@ const WHATS_NEW = {
function _getCurrentVersion() {
const btn = document.querySelector('.version-button');
- return btn ? btn.textContent.trim().replace('v', '') : '2.1';
+ return btn ? btn.textContent.trim().replace('v', '') : '2.2';
}
function _getLatestWhatsNewVersion() {
const versions = Object.keys(WHATS_NEW).sort((a, b) => parseFloat(b) - parseFloat(a));
- return versions[0] || '2.1';
+ return versions[0] || '2.2';
}
function openWhatsNew() {