Commit graph

418 commits

Author SHA1 Message Date
Broque Thomas
9a6ee0e229 Replace Inspiration templates with tabbed Automation Hub
Swap the flat 8-card Inspiration section for a rich 4-tab Automation Hub
(Recipes, Quick Start, Tips, Reference) with 20 categorized recipe cards,
5 step-by-step guides, 8 power-user tips, and full trigger/action/then
reference tables. Includes category + difficulty filters, chain flow
visuals, accordion expand/collapse, and responsive grid layouts.
2026-03-18 19:03:41 -07:00
Broque Thomas
b9732156cd Add per-tag granular toggle settings for all 47 embedded tags
Replace category-based tag settings (10 toggles) with per-tag controls
grouped by source service in an accordion UI. Each of the 11 service
groups (Spotify, iTunes, MusicBrainz, Deezer, AudioDB, Tidal, Qobuz,
Last.fm, Genius, General) has a master toggle that disables all child
tags, with individual toggles for fine-grained control. ISRC and
copyright fallback chains are now per-source toggleable. Genre merge
contributions from each source are independently controllable. All
tags default to enabled for backward compatibility.
2026-03-18 16:17:20 -07:00
Broque Thomas
d3bff90fd6 Add Picard-compatible MusicBrainz tags and per-category tag settings
Post-processing now writes all 18 MusicBrainz tags that Picard writes:
Release Group ID, Album Artist ID, Release Track ID, Release Type,
Status, Country, Original Date, Media, Barcode, Catalog #, ASIN,
Script, Total Discs (plus the 5 already supported). One cached API
call per album via get_release with recordings include.

New "Tags to Embed" settings section with 10 category toggles (all
enabled by default): MusicBrainz IDs, Release Info, Source IDs, ISRC,
BPM, Mood & Style, Copyright & Label, Genre Merging, URLs, Quality.
Each shows inline description of what it includes.
2026-03-18 15:49:36 -07:00
Broque Thomas
2656927f79 Beatport enrichment progress, metadata cache fixes, per-source cache clearing
- Fix enrichment progress never updating: remove `continue` that skipped
  progress_callback for successful tracks in enrich_chart_tracks
- Split chart/extract into two-step flow: extract raw tracks, then enrich
  via polling endpoint with live progress overlay updates
- Move Beatport enrichment cache to persistent metadata cache system
- Fix metadata cache detail modal for Beatport (URL entity_ids with slashes)
- Add per-source Clear dropdown (Spotify/iTunes/Deezer/Beatport) to cache browser
- Remove debug logging from enrichment progress tracking
2026-03-18 08:39:02 -07:00
Broque Thomas
dc612da9d5 Add Sync to Server button for Beatport playlists in download modal
- "Sync to Server" button appears for Beatport chart/playlist downloads
- Starts media server sync via /api/sync/start with live progress bar
- Progress area renders below all modal buttons with matched/failed counts
- Cancel button to abort sync mid-way, auto-cleanup on completion
2026-03-17 20:54:58 -07:00
Broque Thomas
27a0cf8b81 Add Sync History feature with live re-sync progress and source detection
- New sync_history DB table tracks last 100 syncs with full cached context
- Records history for all sync types: Spotify, Tidal, Deezer, YouTube,
  Beatport, ListenBrainz, Mirrored playlists, and Download Missing flows
- Sync History button on sync page with modal showing entries, source
  filter tabs, stats badges, and pagination
- Re-sync button: server syncs expand card inline with live progress bar,
  matched/failed counts, and cancel button; download syncs open download modal
- Re-syncs update the original entry (moves to top) instead of creating duplicates
- Delete button (x) on each entry with smooth remove animation
- Fix mirrored playlist source detection (youtube_mirrored_ matched youtube_)
- Fix broken server import thumbnails with URL validation
2026-03-17 20:39:41 -07:00
Broque Thomas
171a64005d Fix discovery fix modal layout shift causing accidental clicks (#186)
Pin source info and search inputs at top of modal with independent
results scrolling, increase auto-search delay to 500ms, and add
confirmation dialog before committing a track match.
2026-03-17 14:21:11 -07:00
Broque Thomas
cc62541a65 Add Select All, Fix Selected & Fix All to Library Maintenance findings 2026-03-17 09:25:21 -07:00
Broque Thomas
7fd29c4f77 Fix confirm modals hidden behind other modals and wishlist showing Unknown Album
- Bump confirm dialog z-index to 200000 (both #confirm-modal-overlay and
  .confirmation-modal-overlay) so they always appear above all other modals
- Normalize track data in _run_sync_task before storing in original_tracks_map:
  album as dict {'name': ...} and artists as [{'name': ...}] — fixes all
  source converters (Deezer, YouTube, Tidal, Spotify Public, ListenBrainz,
  Beatport) whose fallback paths stored plain strings, causing the wishlist
  UI to show "Unknown Album" for every synced track
2026-03-17 07:53:59 -07:00
Broque Thomas
4c6e2fe1ec Revamp automation page: 2-col grid, duplicate, search/filter, templates, grouping
- Switch user automations to 2-column grid layout (matches system automations)
- Add duplicate button on non-system cards with POST /api/automations/<id>/duplicate
- Add search/filter bar (text search + trigger/action dropdowns) shown at 6+ automations
- Add Inspiration section with 8 starter templates that pre-fill the builder
- Add folder-style automation grouping with group_name DB column, dropdown
  popover for assignment, collapsible group sections, and builder group input
2026-03-17 07:40:14 -07:00
Broque Thomas
53ef9fa913 Add Deezer support to watchlist config modal and linked provider section
- Query/update watchlist artists by deezer_artist_id in config endpoint
- Return deezer_artist_id in config response and recent albums response
- Add Deezer provider badge (purple) to linked provider section
- Detect Deezer vs iTunes for provider linking using fallback source setting
- Show "X fans" instead of "Pop: 0" for Deezer artist search results
- Include followers count in match/search artist response
- Add deezer_artist_id matching to library enrichment and recent releases queries
2026-03-16 19:49:54 -07:00
Broque Thomas
46d3309835 Revamp watchlist & wishlist buttons with dark glass design and animated gradient border
- Dark translucent background with backdrop blur instead of bright colored fills
- Animated flowing gradient border using CSS mask-composite technique
- Color-tinted labels and count badges (amber for watchlist, accent for wishlist)
- Shimmer sweep clipped inside button bounds
- Structured HTML: separate icon, label, badge, and shimmer elements
- Badge pulses when count > 0
- Worker orbs: 7s delay before collapsing back after mouse leaves header
2026-03-16 18:10:10 -07:00
Broque Thomas
775307c2b5 Add worker orbs animation to dashboard header
Worker buttons shrink to floating colored orbs with physics-based
movement, spark emissions from active workers, connection lines, and
center gravity. Hovering the header expands orbs back to full buttons
with staggered spring animation. Desktop only, toggleable in Settings
under UI Appearance.
2026-03-16 16:47:37 -07:00
Broque Thomas
42a4285e09 Add clear findings button to library maintenance modal
Per-job and per-status filtering — respects active toolbar filters so
users can clear e.g. only track number findings or only dismissed items.
Confirmation uses the app's styled modal instead of browser confirm().
2026-03-16 15:37:33 -07:00
Broque Thomas
f10beeea0a Add source badges (Spotify/iTunes/Deezer) to watchlist artist cards
Shows which metadata sources each artist is matched to with small
colored badges on the card. Also adds deezer_artist_id to the
watchlist API response and fixes the data-artist-id fallback chain
to include Deezer-only artists.
2026-03-16 13:37:53 -07:00
Broque Thomas
a02d14a23a Add URL history pills for YouTube, Deezer, and Spotify Link sync tabs
Saves successfully loaded playlist URLs to localStorage and displays
them as clickable pills between the input bar and playlist container.
Clicking a pill re-loads that URL; X button removes it. Max 10 per
source, most recent first. Source-colored hover accents match each
tab's brand styling.

Also fixes duplicate playlist bug — YouTube and Spotify Public now
check for already-loaded playlists before making API calls, preventing
broken duplicate cards when the same URL is entered twice.
2026-03-16 10:35:45 -07:00
Broque Thomas
837c5ff680 Add persistent library history tracking downloads and server imports
New library_history table logs every completed download and every new
track imported from Plex/Jellyfin/Navidrome. A "History" button next
to "Recent Activity" on the dashboard opens a modal with Downloads and
Server Imports tabs, album art thumbnails, quality/source badges, and
pagination.
2026-03-16 09:36:05 -07:00
Broque Thomas
483e45cbc0 Add Spotify Link tab for public playlist/album scraping without API credentials
Scrapes Spotify's embed endpoint to extract track data from any public
playlist or album URL. Full discovery flow with Deezer parity: parse →
card → discovery modal → live progress → sync → download missing.

- New scraper: core/spotify_public_scraper.py (embed endpoint parsing)
- 12 API endpoints mirroring Deezer's discovery/sync/download flow
- WebSocket live discovery updates via spotify_public_discovery_states
- Green-branded tab, cards, and input styling (#1DB954)
- Album vs playlist detection with distinct card icons (💿/🎵)
- Download persistence: card click reopens download modal after close
- Card phase reset on cancel/completion (closeDownloadMissingModal)
- Backend download linking for spotify_public_ and deezer_ prefixes
- Completion handlers (V2 + no-missing-tracks) for both platforms
- Source URLs stored on mirrored playlists for future auto-refresh
2026-03-15 21:25:05 -07:00
Broque Thomas
da2b42b59a Add Redownload button to enhanced library view & fix album download mode
- Redownload button on each album in enhanced view (admin only)
- Uses same flow as artist page: fetches API tracklist, opens Download
  Missing modal with force-download option
- Register dashboard bubbles for library redownload and issue downloads
- Add library_redownload_ prefix to album download whitelist so it uses
  1 worker with source reuse and sends full album context (release_date
  for year in folder name)
2026-03-15 19:15:46 -07:00
Broque Thomas
186671aa2e Add play button to repair findings & increase finding image sizes
- Play button on acoustid_mismatch, acoustid_no_match, track_number_mismatch, fake_lossless, dead_file, orphan_file findings
- Uses playLibraryTrack() for proper media player integration (track info, sidebar, album art)
- Data attributes for safe escaping instead of inline onclick strings
- Finding images increased from 56px to 150px with hover effects
- Improved detail panel spacing and media card layout
2026-03-15 15:46:30 -07:00
Broque Thomas
078b1130f8 Fix watchlist migration dropping profile_id & fix profile delete dialog hidden behind overlay
- Watchlist nullable migration now preserves profile_id column and composite
  UNIQUE constraints when rebuilding the table
- Profile support migration always repairs missing profile_id columns on all
  tables, even if the migration metadata key already exists (handles tables
  rebuilt by other migrations)
- Confirm dialog z-index raised to 100000 to appear above profile picker
  overlay (99999), fixing invisible delete confirmation
2026-03-15 15:21:19 -07:00
Broque Thomas
ab21855af3 Enrich repair findings with album art, artist images & live job progress
- All 9 repair jobs now emit report_progress() for real-time card updates
  (phase, log lines, per-item activity) via WebSocket repair:progress events
- Enrich finding details with album/artist thumb URLs across all repair jobs
  (dead_file, duplicate, metadata_gap, album_completeness, missing_cover_art,
  acoustid_scanner, track_number_repair, fake_lossless, orphan_file)
- Track number repair: return match_score from fuzzy matching, add suffix-based
  DB lookup for album/artist art (handles cross-environment path mismatches)
- Fix Plex/Jellyfin relative thumb URLs in findings endpoint via fix_artist_image_url
- Labeled media cards in finding detail panels (album title + artist name under images)
- Dashboard tooltip shows current job name + per-job progress instead of stale stats
2026-03-15 14:08:26 -07:00
Broque Thomas
f08550140f Add whistle logo to maintenance modal header & harden fix handlers
- Add whisoul.png to modal header with subtitle text and gradient background
- Responsive: smaller logo on mobile, hide subtitle
- Share _resolve_file_path in repair_worker for cross-environment path compat
- Use path resolution in orphan and duplicate file deletion
- Guard directory cleanup against removing the transfer folder itself
- Restore correct button label text on fix error recovery
2026-03-15 13:25:40 -07:00
Broque Thomas
0594673cad Polish finding detail renderers with richer visuals
- Cover art findings: show artwork image thumbnail preview
- Duplicate findings: KEEP/REMOVE badges highlighting best quality copy
- Incomplete album: completion progress bar with percentage
- Fake lossless: spectral analysis bar comparing detected vs expected cutoff
- Resolved findings: show descriptive action label (e.g. "Entry Removed")
- Fix operator precedence bug in fake lossless nyquist calculation
2026-03-15 13:00:44 -07:00
Broque Thomas
7a706e8c11 Add fix actions for maintenance findings (dead files, orphans, duplicates, etc.)
- New fix_finding() dispatcher in repair_worker with per-type handlers:
  dead_file (remove DB entry), orphan_file (delete from disk),
  track_number_mismatch (update DB), missing_cover_art (apply artwork URL),
  metadata_gap (apply found fields), duplicate_tracks (keep best quality)
- New POST /api/repair/findings/<id>/fix endpoint
- Frontend: contextual fix buttons per finding type, bulk "Fix Selected"
- Removed path_mismatch from fixable types (dry-run preview only)
2026-03-15 12:51:18 -07:00
Broque Thomas
61ed4086e0 Redesign maintenance findings/history tabs with dashboard & fix path resolution bugs
- Add findings dashboard with summary stats and per-job clickable filter chips
- Redesign findings cards with expandable detail panels and per-type renderers
- Redesign history tab with status dots, stat pills, and full timestamps
- Fix dead file cleaner false positives by using suffix-based path resolution
- Fix orphan file detector false positives by matching via path suffixes
- Add help text modal for each repair job card
- Enlarge maintenance modal (1100px wide, 90vh tall)
2026-03-15 12:20:02 -07:00
Broque Thomas
4635ea895b include a '?' to include more details for each job. 2026-03-15 11:19:09 -07:00
Broque Thomas
dab94ce65d update soulsync repair worker with new jobs 2026-03-15 10:18:50 -07:00
Broque Thomas
cae2bd0c62 Add granular post-processing toggles for metadata services, cover art, and lyrics 2026-03-14 22:45:50 -07:00
Broque Thomas
8f0b9518bc Add per-profile ListenBrainz support with personal settings modal 2026-03-14 20:12:19 -07:00
Broque Thomas
7db1545208 Optimize enhanced view performance with event delegation and scoped DOM queries 2026-03-14 18:00:20 -07:00
Broque Thomas
7e19e66ef3 Add quality enhance button to upgrade existing library tracks & Add iTunes fallback to Quality Enhance endpoint for full metadata source parity 2026-03-14 17:09:08 -07:00
Broque Thomas
761052145f Add select all checkbox to watchlist modal for bulk removal 2026-03-14 12:25:58 -07:00
Broque Thomas
fead6db379 Fix docs sidebar navigation scroll targeting with lazy-loaded images 2026-03-14 11:16:26 -07:00
Broque Thomas
719980cf5a Hide sync sidebar by default, only show during active sync 2026-03-14 09:56:48 -07:00
Broque Thomas
945f86c643 Library Repair Worker: multi-job background maintenance daemon with 10 jobs, findings system, and management modal 2026-03-14 09:09:18 -07:00
Broque Thomas
6de3ab7cef Add universal metadata cache for Spotify & iTunes API responses with browsable dashboard tool 2026-03-14 01:26:45 -07:00
Broque Thomas
c54e52e18d Add Spotify Library discovery section, instrumental filter, custom exclusion terms & album download modal fixes 2026-03-14 00:21:44 -07:00
Broque Thomas
a5e72cff05 Add instrumental filter & custom exclusion terms to watchlist content filters 2026-03-13 23:09:12 -07:00
Broque Thomas
32f1cc946c Improve watchlist cross-provider matching accuracy and add manual artist linking UI 2026-03-13 22:28:13 -07:00
Broque Thomas
0e89155c15 Add watchlist settings gear button to artist detail and artist card pages 2026-03-13 22:07:54 -07:00
Broque Thomas
e1a5bf678a Add library issue reporting system with actionable detail modal 2026-03-13 21:14:57 -07:00
Broque Thomas
57a8bdd107 Add album file reorganization to Enhanced Library Manager 2026-03-13 18:43:54 -07:00
Broque Thomas
d4eadef374 Add interactive REST API docs with full endpoint tester and complete metadata serialization 2026-03-13 17:45:01 -07:00
Broque Thomas
4dfefc70df Polish settings page styling — premium header, toggle switches, refined inputs 2026-03-13 16:29:02 -07:00
Broque Thomas
2c6f2adce1 Redesign watchlist modal with polished cards, gradient overlays, and rate limit modal 2026-03-13 15:55:26 -07:00
Broque Thomas
a557074d3c Add Spotify rate limit modal with live countdown and ban duration escalation 2026-03-13 15:36:24 -07:00
Broque Thomas
55186c6a51 Add Deezer playlist sync tab with discovery, fix modal, and cache persistence 2026-03-13 12:29:49 -07:00
Broque Thomas
f9d80606e3 Expand debug info with library stats, service status, config, and configurable log output 2026-03-13 08:47:04 -07:00
Broque Thomas
fc05412a13 update docs page 2026-03-13 08:35:28 -07:00
Broque Thomas
470b8dca7e fix spotify active animation color 2026-03-12 21:41:01 -07:00
Broque Thomas
7d092e8b53 css fixes 2026-03-12 17:30:14 -07:00
Broque Thomas
e8df863205 enhanced library write all modal and confirmation dialog 2026-03-12 16:57:38 -07:00
Broque Thomas
6c4de45b32 fix acoustID match issue and css changes 2026-03-12 16:43:22 -07:00
Broque Thomas
ded906bef4 Fix false positive track matching & tag writing visibility for library files 2026-03-12 16:08:44 -07:00
Broque Thomas
a3bf858558 Seamless Spotify rate limit UX — replace intrusive modal with ambient indicators 2026-03-12 12:45:59 -07:00
Broque Thomas
d401dc8af1 Two-column badge layout for artist cards with 7+ service matches 2026-03-11 23:01:47 -07:00
Broque Thomas
cc35864e7d Tidal & Qobuz Enrichment Workers - Bug Fixes & Rate Limiting 2026-03-11 21:49:31 -07:00
Broque Thomas
35d6068f99 fix worker logos 2026-03-11 21:39:25 -07:00
Broque Thomas
ac2c710a1e Tidal & Qobuz Background Enrichment Workers 2026-03-11 21:26:20 -07:00
Broque Thomas
f4d8280642 css & error notification fixes 2026-03-11 14:56:45 -07:00
Broque Thomas
0aa8950436 fix build a playlist functionality and update the ui 2026-03-11 07:52:58 -07:00
Broque Thomas
c06fd044a1 Profile Permissions & Page Access Control 2026-03-10 23:23:43 -07:00
Broque Thomas
9bee72503f Unify dashboard button styles and enhance activity log 2026-03-10 20:24:33 -07:00
Broque Thomas
f91626ef18 Per-Page Particle Animations 2026-03-10 19:46:31 -07:00
Broque Thomas
40521fa499 Sidebar audio visualizer with 5 reactive styles and settings toggle 2026-03-10 16:56:47 -07:00
Broque Thomas
a682f814f7 Sidebar SVG icons, larger page header icons, and accent-colored nav 2026-03-10 16:18:07 -07:00
Broque Thomas
6b1d069be0 Add ambient accent-colored aura animation to sidebar 2026-03-10 16:01:09 -07:00
Broque Thomas
9a1c3b4124 Fix watchlist badge positioning and mobile card sizing 2026-03-10 15:24:33 -07:00
Broque Thomas
1b0fca9009 Service Badges, Page Headers, Docs Page, and Bug Fixe 2026-03-10 14:47:11 -07:00
Broque Thomas
51b5469e85 Add page icons & gradient shimmer to all page headers 2026-03-10 13:12:50 -07:00
Broque Thomas
927fe6338e Fix Spotify badge icon & compact card badge layout for overflow 2026-03-10 12:54:18 -07:00
Broque Thomas
e8ddbe3709 Reset all Genius matches to fix blind-fallback search bug & fix css issues 2026-03-10 10:57:50 -07:00
Broque Thomas
c96159d0fc fix download modal progress bar height. fix text in wishlist/watchlist buttons appearing outside container 2026-03-10 10:51:36 -07:00
Broque Thomas
f26f6f8266 Last.fm & Genius full worker parity, clickable service badges, and playlist folder race condition fix 2026-03-10 10:35:55 -07:00
Broque Thomas
92ba36a9ba Add no-auth state to Last.fm and Genius dashboard buttons with greyed-out UI and settings guidance 2026-03-10 09:20:16 -07:00
Broque Thomas
dc7140c459 Add Last.fm and Genius to on-demand enrichment, settings reload, and enrich dropdown parity 2026-03-10 09:12:36 -07:00
Broque Thomas
f8d23ec37c Add Last.fm and Genius API clients with settings integration 2026-03-09 22:35:10 -07:00
Broque Thomas
e71ae7a5f7 Import file tab on sync page to create mirrored playlists from CSV/TXT files 2026-03-09 22:03:13 -07:00
Broque Thomas
1b42b88c31 css changes 2026-03-09 18:15:42 -07:00
Broque Thomas
b9d5d4e277 update page icons 2026-03-09 18:06:44 -07:00
Broque Thomas
b3d607752b Add version tracking to database backup manager & Fix radio mode next track closing modal and losing playback state 2026-03-09 13:10:25 -07:00
Broque Thomas
ea1441d09d "Write Tags to File" in the Enhanced Library Manager 2026-03-09 11:17:01 -07:00
Broque Thomas
5f58432ca4 Redesigned media player with expanded Now Playing modal and smart radio 2026-03-09 10:13:42 -07:00
Broque Thomas
5b79ca1e88 redesign the media player in sidebar 2026-03-09 08:02:05 -07:00
Broque Thomas
7c50f350c0 Add a library management interface to the artist detail page with inline metadata editing, per-service manual matching, bulk operations, and full track/album management. 2026-03-08 23:37:02 -07:00
Broque Thomas
41edb31e07 Replace sidebar donation dropdown with support modal 2026-03-08 17:33:20 -07:00
Broque Thomas
5daa8c0596 Add rich stats to automation run history 2026-03-08 12:20:50 -07:00
Broque Thomas
f9e8c8dadd Add themed confirm dialog modal replacing all native browser confirms 2026-03-08 11:16:11 -07:00
Broque Thomas
266d044797 Add Backup Manager dashboard tool card with list, download, restore & delete 2026-03-08 10:46:03 -07:00
Broque Thomas
e11ee8622e Fix discovery modal persistence, artist dict handling, and rate limiter scope 2026-03-07 13:05:49 -08:00
Broque Thomas
918dbad88f reorganize automations page. 2026-03-07 11:27:53 -08:00
Broque Thomas
b34e348937 keep a history of automation runs 2026-03-07 09:39:08 -08:00
Broque Thomas
b90c270d54 Add Download Now button to wishlist modal and library page download bubbles 2026-03-07 00:11:15 -08:00
Broque Thomas
5f14f027d6 glow effect on active automations 2026-03-06 21:09:24 -08:00
Broque Thomas
8b6a2c0adc allow multiple notification calls per automation as well as a new signal fire utility 2026-03-06 18:10:15 -08:00
Broque Thomas
dd5f2f07e9 detail modal for each action and trgiger 2026-03-06 16:43:24 -08:00
Broque Thomas
7647ac22ed Add Discovery Pool dashboard tool card and revamp modal with premium category-card design 2026-03-06 11:59:45 -08:00
Broque Thomas
d264ec70f3 Add sync match cache and fix discovery clear to purge cache 2026-03-06 09:41:44 -08:00
Broque Thomas
9f416475e2 Live automation progress tracking with real-time output panels 2026-03-05 20:39:26 -08:00
Broque Thomas
4bd3e776bd css changes 2026-03-05 16:57:14 -08:00
Broque Thomas
f99f873d60 Replace hardcoded wishlist/watchlist timers with system automations + add Pushbullet & Telegram notifications 2026-03-05 16:50:09 -08:00
Broque Thomas
da707dcf0a Full automation engine expansion with scheduling, triggers, actions, and UI polish 2026-03-05 15:13:32 -08:00
Broque Thomas
b30e1f60bd Add Mirrored Playlists — persistent cross-service playlist archive
Automatically mirrors every parsed playlist (Spotify, Tidal, YouTube, Beatport) to a local database so they're always accessible — even if a service subscription lapses or the browser closes.
  - New "Mirrored" tab on the Sync page with source-branded cards showing discovery/download status
  - Auto-mirrors on successful parse (upsert — re-parsing updates the existing mirror, no duplicates)
  - Click any mirrored playlist to browse its full track list, then run it through the discovery pipeline
  - Cards dynamically reflect live state: Discovering → Discovered → Downloading → Downloaded
  - Download modal rehydrates after page refresh — click a "Downloading..." card to resume viewing progress
  - All phase transitions (start, complete, cancel, error, modal close) keep card and backend state in sync
  - Profile-scoped via profile_id, consistent with other features
2026-03-04 18:27:18 -08:00
Broque Thomas
6bbd52fda7 update notification 2026-03-04 15:01:54 -08:00
Broque Thomas
114af496c7 Track version 2026-03-04 11:32:40 -08:00
Broque Thomas
4fee005dee Add multi-profile support with Netflix-style profile picker
Allow multiple users to share a single SoulSync instance with isolated personal data. Each profile gets its own watchlist, wishlist, discovery pool, similar artists, and bubble snapshots — while sharing the same music library, database, and service credentials.

  - Netflix-style profile picker on startup when multiple profiles exist
  - Optional PIN protection per profile; admin PIN required when >1 profiles
  - Admin-only profile management (create, edit, rename, delete)
  - Profile avatar images via URL with colored-initial fallback
  - Zero-downtime SQLite migration — all existing data maps to auto-created
    admin profile
  - Single-user installs see no changes — profile system is invisible until
    a second profile is created
  - WebSocket count emitters scoped to profile rooms (watchlist/wishlist)
  - Background scanners (watchlist, wishlist, discovery) iterate all profiles
2026-03-04 10:46:08 -08:00
Broque Thomas
84de4ad16b Redesign watchlist modal with enriched artist detail view 2026-03-03 20:26:21 -08:00
Broque Thomas
d06b7e5a25 Update style.css 2026-03-03 19:00:50 -08:00
Broque Thomas
0f428dc45c Add WebSocket real-time updates with automatic HTTP polling fallback
Migrates 38 HTTP polling loops to WebSocket push events across 6 phases: service status, dashboard stats, enrichment workers, tool progress, sync/discovery progress, and scan status. All original HTTP polling is preserved as automatic fallback — if WebSocket is unavailable or disconnects, the app seamlessly reverts to its previous behavior. Includes 162 tests verifying event delivery, data shape, and HTTP parity. Also fixes a copy-paste bug in Beatport sync error cleanup.
2026-03-03 18:26:29 -08:00
Broque Thomas
53d841c3dc Update style.css 2026-03-03 12:43:02 -08:00
Broque Thomas
df33adf6a7 include 'add to watchlist' button to each artist in library. 2026-03-02 10:04:10 -08:00
Broque Thomas
b558dff138 add all recommended to watchlist. 2026-03-02 09:24:37 -08:00
Broque Thomas
1f73ba4f94 view recommended artists. 2026-03-02 09:12:35 -08:00
Broque Thomas
8f2dd66aee add a 'watch all' button on hero slider to quickly add all artists in slider. 2026-03-02 08:40:22 -08:00
Broque Thomas
c279f2e4fa Design retag layout 2026-03-01 22:52:27 -08:00
Broque Thomas
3dad2eae38 watchlist redesign 2026-03-01 20:35:49 -08:00
Broque Thomas
046233817d Update style.css 2026-03-01 19:47:56 -08:00
Broque Thomas
6d3f43a385 Update style.css 2026-03-01 19:30:50 -08:00
Broque Thomas
71fe5b83eb css changes 2026-03-01 15:34:51 -08:00
Broque Thomas
4fba18b25e Feat: Custom accent colors. 2026-03-01 15:29:37 -08:00
Broque Thomas
1964659c8b css changes 2026-03-01 14:55:45 -08:00
Broque Thomas
1aa6cdc9b6 Rebuild the import feature and move it to its own page. 2026-03-01 14:18:55 -08:00
Broque Thomas
c2119d4ecf Update style.css 2026-03-01 11:16:47 -08:00
Broque Thomas
698b1fa4f3 clear current downloads 2026-02-27 11:18:13 -08:00
Broque Thomas
e14a317a56 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.
2026-02-26 17:19:34 -08:00
Broque Thomas
e3a5608c95 Add manual candidate download API and UI
Add server endpoint to trigger a manual download for a user-selected candidate from the candidates modal (/api/downloads/task/<id>/download-candidate). The endpoint validates input, resets task and batch state (status, error, used_sources, active_count, permanently_failed_tracks), reconstructs Track/TrackResult objects and dispatches a background download attempt via missing_download_executor. Update the frontend candidates modal to show a download button per candidate, wire it to POST the candidate to the new API, and add CSS for table layout and download button styling. Enables restarting failed/not_found tasks by choosing a specific source without blocking the UI.
2026-02-26 13:45:38 -08:00
Broque Thomas
2852e2b39f Add candidates review modal & API
Expose cached search results for failed downloads and add a UI to review them. Implements a new GET /api/downloads/task/<task_id>/candidates endpoint that serializes any cached_candidates and track_info for a task and returns an error message and candidate count. The download worker now collects top raw search results (all_raw_results) and stores them in download_tasks[task_id]['cached_candidates'] when no match is found so users can inspect what Soulseek returned. The batch status payload includes has_candidates to mark "not_found" tasks as reviewable. On the frontend, new script functions (_ensureCandidatesClickListener, showCandidatesModal, _renderCandidatesModal, closeCandidatesModal) fetch and render a modal table of candidates; existing status rendering is updated to attach click handlers and error tooltips. Styles for the modal and a clickable .has-candidates state are added to style.css.
2026-02-26 13:09:51 -08:00
Broque Thomas
44b5032f17 Add discography filters to artist detail page
Introduce interactive discography filters on the artist detail page. Adds filter UI markup (category, content, ownership) in index.html and styles in style.css. Implements filter state, initialization, reset and apply logic in script.js; tags release cards with data attributes (live/compilation/featured) using regex heuristics, updates visibility and per-section owned/missing counts, and re-applies filters when releases are updated. Integrates filter setup into page init and resets filters when loading artist data.
2026-02-26 10:17:53 -08:00
Broque Thomas
35a03d6839 Add global watchlist override and UI
Introduce a global watchlist override feature and UI to control release/content filters across all watchlist artists. Backend: add /api/watchlist/global-config (GET/POST) for reading/updating global settings, validation to require at least one release type when override is enabled, and _apply_watchlist_global_overrides() to apply settings to WatchlistArtist objects. Scanners (manual and automatic) now call _apply_watchlist_global_overrides() and perform additional checks (_should_include_release, _should_include_track) to skip releases/tracks according to config. Frontend: add a Global Watchlist Settings modal, controls (release types, content filters, include-all shortcut), save/validation logic, banners/notices when global override is active, and integration into the watchlist modal and per-artist config. Styles: add supporting CSS for the modal and banners. Small cleanup/whitespace adjustments included.
2026-02-24 22:09:08 -08:00
Broque Thomas
1283041836 Integrate Hydrabase P2P metadata client
Add Hydrabase support as an optional/dev metadata source and comparison tool.

- Add core/hydrabase_client.py: synchronous Hydrabase WebSocket client that normalizes results to Track/Artist/Album types and exposes raw access.
- Update config/settings.py: add hydrabase settings (url, api_key, auto_connect) and getter.
- Update web_server.py: integrate HydrabaseClient, initialize client alongside the existing HydrabaseWorker, add auto-reconnect using saved config, persist credentials on connect/disconnect, add endpoints for status and stored comparisons, background comparison runner (Hydrabase vs Spotify vs iTunes), and adapt multiple search endpoints to optionally use Hydrabase as the primary metadata source with fallbacks.
- Update web UI (webui/index.html, webui/static/script.js, webui/static/style.css): add network stats and source comparison UI, pre-fill saved credentials, show peer count, load/display comparisons, update disconnect behavior to disable dev mode, and add Hydrabase badge styling.

Behavioral notes: when dev mode + Hydrabase are active, searches can be served from Hydrabase and comparisons to Spotify/iTunes are run in background; when Hydrabase fails the code falls back to Spotify/iTunes. Saved Hydrabase credentials are persisted for auto-reconnect; disconnect disables dev mode and auto_connect.

Files touched: config/settings.py, core/hydrabase_client.py, web_server.py, webui/index.html, webui/static/script.js, webui/static/style.css.
2026-02-24 08:11:48 -08:00
Broque Thomas
317d5c1770 Add Retag tool (DB, backend, frontend)
Introduce a new Retag tool to track and re-tag previously downloaded albums/singles. Changes include:

- Database: add migration hook and create retag_groups and retag_tracks tables, indexes, and many helper methods (add/find/update/delete groups & tracks, stats, trimming).
- Backend (web_server): capture completed album/single downloads into the retag tables, implement retag execution logic (_execute_retag) to fetch album metadata, match tracks, update tags, move files, download cover art, and update DB. Add thread-safe globals, executor, and REST endpoints for stats, listing groups, group tracks, album search, execute, status, and delete.
- Frontend (webui): add Retag Tool card, modals, search UI, JS to list groups/tracks, search albums, start retag operations, poll status, and update UI; include help content. Add CSS for modals and components.

The migration is invoked during DB init to ensure existing installations create the new tables. The tool caps stored groups (default 100) and avoids duplicate track entries.
2026-02-23 20:39:04 -08:00
Broque Thomas
f1fe72ceb2 Add track selection UI and backend mapping
Add per-track selection checkboxes, select-all control and a selection count to download modals (missing/YouTube/Tidal/artist-album). Implement JS helpers (toggleAllTrackSelections, updateTrackSelectionCount) to manage checkbox state, row dimming, button disabling, and to filter/stamp selected tracks with _original_index before sending to the backend. Update start/add-to-wishlist flows to use only selectedTracks and disable controls once analysis starts. Backend _run_full_missing_tracks_process now reads _original_index to preserve original table indices in analysis results. CSS updates (mobile.css and style.css) add styling for checkbox columns, responsive hiding logic for headers/columns, selection visuals (.track-deselected), and small layout/width tweaks.
2026-02-23 15:54:58 -08:00
Broque Thomas
1ad7bda880
Merge pull request #154 from snuffomega/advanced_settings
feat(settings): lock container path fields with unlock toggle
2026-02-23 10:51:17 -08:00
Broque Thomas
666e65ed3b Add repair scanning, tracklist fallbacks, UI polling
Introduce deferred album repair scanning and robust tracklist resolution plus UI/presentation tweaks.

- core/repair_worker.py: Add lazy MusicBrainz and AudioDB client accessors, per-batch folder queues, and register_folder/process_batch to defer folder scans until a batch completes. Implement cascading tracklist resolution (_resolve_album_tracklist) using Spotify/iTunes IDs, Spotify track→album lookup, album search, MusicBrainz release lookup, and AudioDB→MusicBrainz fallback. Add helpers to read Spotify track IDs, MusicBrainz album IDs, album/artist tags from files, MB/AudioDB fetchers, placeholder-ID filtering, and rename associated .lrc files when renaming audio files. Cache/locking and background-threaded scanning included. Improves resilience to missing/placeholder IDs and avoids circular imports.

- web_server.py: Register album folders for repair in post-processing and trigger repair_worker.process_batch when batches complete (multiple completion paths) so scans run after downloads finish.

- webui/static/script.js: Reduce unnecessary background work by skipping many fetches when the tab is hidden, and refresh dashboard-specific data on visibility change to ensure UI updates after OAuth or tab switch.

- webui/static/style.css: Replace glassmorphic backdrop-filters with opaque dark gradients for sidebar and main content to improve GPU rendering and visual consistency.

Overall: Adds reliable post-download album repair scanning using multiple metadata sources and reduces unnecessary client polling and heavy CSS effects for better performance and robustness.
2026-02-23 10:18:31 -08:00
snuffomega
e7ff1b2081 feat(settings): lock container path fields with unlock toggle
Prevent accidental misconfiguration of Docker container-internal paths
(Slskd Download Dir, Matched Transfer Dir, Import Staging Dir) by making
them read-only by default.

Repurposes the non-functional Browse button into a per-field Unlock/Lock
toggle. Adds a warning blurb below the Download Settings header so users
understand these are container paths, not host paths.
2026-02-23 13:11:13 -05:00
Broque Thomas
24bfc2462d Add Spotify & iTunes workers; update repair worker
Add full-featured SpotifyWorker and iTunesWorker background workers to enrich artists, albums, and tracks with external metadata using batch cascading searches, fuzzy name matching, ID validation, and DB backfills. Update RepairWorker to re-read the transfer path from the database each scan, resolve host paths when running in Docker, and trigger immediate rescans when the transfer path changes; remove the static config_manager dependency. Also include supporting changes to the database layer and web UI/server (stats, controls, and styles) to integrate the new workers and reflect updated worker status.
2026-02-22 22:29:10 -08:00
Broque Thomas
ce474749d5 Add library repair worker and UI
Introduce a RepairWorker to scan the transfer folder and automatically detect/repair broken album track numbers (e.g. the "all tracks = 01" bug). The worker uses mutagen to read/write tags, fuzzy-matches titles against an album tracklist (Spotify/iTunes via a SpotifyClient), updates filenames and the tracks DB file_path when renamed, and caches album tracklists. It also adds DB schema support (repair_status, repair_last_checked, and an index).

Integrates the worker into the web server: initializes and starts the worker, and exposes /api/repair/status, /api/repair/pause and /api/repair/resume endpoints. Adds UI elements (button, tooltip), client-side JS to poll and control the worker, CSS for visuals/animations, and a new image asset (whisoul.png).
2026-02-21 15:00:23 -08:00
Broque Thomas
e80b4894bb Update style.css 2026-02-21 08:57:03 -08:00
Broque Thomas
d4d3f1ec3d Update style.css 2026-02-21 08:53:50 -08:00
Broque Thomas
e7dfb423dc Add Active Downloads dashboard and UI fixes
Introduce an "Active Downloads" section to the dashboard and wire up client-side plumbing to populate and update it. Adds escapeForInlineJs to safely embed values into inline JS attributes and replaces several inline onclick usages (search/genre/listenbrainz/artist buttons) to prevent quoting issues. Implements updateDashboardDownloads, createDashboardDiscoverBubble, and integrates dashboard updates into artist/search/discover flows (including register/discover download persistence and monitor hooks). Adds dashboard-specific CSS for discover/artist bubbles and minor style fixes (artist image sizing, keyframe formatting) plus a mobile CSS tweak for artist images.
2026-02-21 08:51:51 -08:00
Broque Thomas
49a6c58ea8 Add Hydrabase P2P mirror worker
Introduce a Hydrabase P2P mirror worker and integrate it into the web UI and server flows. Adds core/hydrabase_worker.py: a background thread with a capped queue (1000), enqueue API, rate limiting, basic stats (sent/dropped/errors), and logic to send JSON requests over a provided WebSocket (responses received and discarded). Integrates the worker into web_server.py (import, startup init, status/pause/resume endpoints, and enqueues queries from multiple search endpoints when dev mode is enabled). Adds UI elements, JavaScript polling/toggle logic, and CSS styling for a Hydrabase status button in webui (index.html, static/script.js, static/style.css) to display and control worker state.
2026-02-21 02:15:43 -08:00
Broque Thomas
35fd7bb294 Add Hydrabase dev UI and WebSocket support
Introduce a developer-only Hydrabase testing UI and backend WebSocket integration. Adds a simple dev-mode toggle (password 'hydratest') and new API endpoints (/api/dev-mode, /api/hydrabase/connect, /api/hydrabase/disconnect, /api/hydrabase/status, /api/hydrabase/send) that use websocket-client to connect/send raw JSON to a Hydrabase instance. Frontend changes include a Hydrabase nav/page, payload editors, response panel, dev-mode UI in Settings, associated JS handlers, CSS styling, and an icon asset. Also add websocket-client to requirements.
2026-02-21 00:32:04 -08:00
Broque Thomas
3644422ab8 Add FLAC bit depth filter to post-download quality gate 2026-02-20 15:05:45 -08:00
Broque Thomas
2c56b23c27 Progressive track list rendering for large playlists 2026-02-20 09:15:15 -08:00
Broque Thomas
ed184f9bb8 rearrange the download modal 2026-02-19 23:15:33 -08:00
Broque Thomas
c70cfd335a Fix missing formats key in error path and clean up format query 2026-02-19 10:50:53 -08:00
Broque Thomas
6c6651b879 Add format summary tags to library release cards, wishlist modal, and artist hero 2026-02-19 10:20:30 -08:00
Broque Thomas
3663a75769 Show track ownership indicators and file metadata in wishlist modal for all releases 2026-02-19 09:39:56 -08:00
Broque Thomas
2ca410fadd css fixes 2026-02-19 09:05:58 -08:00