Commit graph

3327 commits

Author SHA1 Message Date
BoulderBadgeDad
7b3a927e86
Merge pull request #693 from Nezreka/dev
Bump version to 2.6.1
2026-05-24 15:47:10 -07:00
Broque Thomas
93743119d9 Bump version to 2.6.1
Update the SoulSync base version, Docker release workflow default, and What's New notes so the next release surfaces as 2.6.1.
2026-05-24 15:44:58 -07:00
BoulderBadgeDad
63260a48c0
Merge pull request #692 from Nezreka/dev
Dev
2026-05-24 15:36:09 -07:00
Broque Thomas
28922ad2c1 Cap persistent download history response
Stop appending persistent download history once the unified downloads payload reaches the requested limit. This keeps the Downloads tab history tail bounded even if the history provider returns more rows than requested, while preserving existing live-task total behavior.
2026-05-24 14:57:32 -07:00
Broque Thomas
28641403d9 Fix Zustand shallow import
Use Zustand's public shallow selector export so the import page resolves correctly under the installed Zustand 5 package. This fixes the Vite boot overlay without changing import workflow behavior.
2026-05-24 14:47:29 -07:00
BoulderBadgeDad
29ba4e0049
Merge pull request #689 from kettui/refactor/more-native-links
Replace programmatic navigation with anchor links on issues & stats pages
2026-05-24 14:41:25 -07:00
BoulderBadgeDad
a1222d5a8f
Merge pull request #686 from kettui/feat/react-migration-import
feat(webui): migrate import page to React
2026-05-24 14:16:05 -07:00
Broque Thomas
0bea332aed Preserve album bundle track numbers
Keep album-bundle staging from replacing known per-track album numbers with the filename parser's default when staged files do not expose a real track number. Carry staging tag numbers through the cache, fall back to task metadata for private release staging, and cap hybrid album batches to one worker when Soulseek is first in the source order.
2026-05-24 13:59:44 -07:00
Antti Kettunen
caa6534ee8
feat(import): show MusicBrainz variants
- pass release metadata through album search normalization
- surface release format, country, label, and disambiguation in React import cards
- add coverage for search normalization and import route rendering
2026-05-24 21:29:22 +03:00
Antti Kettunen
400d0dd48a
docs(import): align migration docs
- describe the implemented nested /import route structure
- document the route-local workflow store and stable draft state
- update testing, risk, and cleanup notes to match the current code
2026-05-24 21:17:22 +03:00
Antti Kettunen
e2a760bd68
fix(webui): keep import pages cache-aware
- keep the /import loader from turning transient staging fetch failures into route errors
- keep cached auto-import status and results visible during refetch failures
- show inline notices only when there is no stale data to fall back to
- add regression coverage for staging, status, and results failure paths
2026-05-24 21:17:22 +03:00
Antti Kettunen
a65fbfd532
refactor(webui): move badge into primitives
- move the shared badge primitive and styling out of the form component module
- keep primary-button badge styling working via a data-slot hook instead of a form-local class
- update the import pages and primitive tests to consume the new home for Badge
2026-05-24 21:17:22 +03:00
Antti Kettunen
9da8251e43
feat(webui): clarify import source metadata
- thread primary_source through album and track search payloads while keeping per-result source on the returned rows
- reuse the shared Notice primitive for fallback and error messaging in the import pages
- update the import route tests and shell route smoke coverage for the new behavior
2026-05-24 21:17:22 +03:00
Antti Kettunen
2a7c03f398
refactor(webui): merge primitives into one module
- fold Show and Notice into a single primitives module with one shared stylesheet
- keep the primitives barrel export intact while shrinking the folder footprint
- consolidate the primitive tests into one combined suite
2026-05-24 21:17:22 +03:00
Antti Kettunen
01a0333d7a
style(import): add separate styles for mobile 2026-05-24 21:17:21 +03:00
Antti Kettunen
7bd6e0ba09
feat(form): add ghost option variant
- Keep option buttons transparent by default and subtle on hover
- Use the ghost style for inactive auto-import filters so the active one stands out
- Keep OptionButton aligned with the existing button variant API
2026-05-24 21:17:21 +03:00
Antti Kettunen
5a227e3ace
test(import): use shared shell helper 2026-05-24 21:17:21 +03:00
Antti Kettunen
b4ca5efe39
refactor(form): use nested data selectors
- keep only semantic data attributes on the form primitives
- move variant styling into nested CSS module selectors
- preserve the existing visual treatment while simplifying the component layer
2026-05-24 21:17:21 +03:00
Antti Kettunen
e65ec37c9e
test(import): use MSW route handlers
- replace direct fetch stubs with shared MSW handlers
- keep fetch spying only for request assertions
- cover the shell prefetch with an issues counts handler
2026-05-24 21:17:21 +03:00
Antti Kettunen
7a0548ac94
refactor(import): normalize controls and classes
- let the singles action buttons use the default size again
- remove redundant type="button" props from import controls
- switch import page conditional classes to clsx object notation
- drop route-test assertions that pinned compact auto-import sizes
2026-05-24 21:17:21 +03:00
Antti Kettunen
9ba54bd82d
feat(form): add compact option groups
- add a size prop to OptionButtonGroup with a denser sm layout\n- use the compact filter group on the auto-import panel\n- keep the new size variants covered in form and route tests
2026-05-24 21:17:21 +03:00
Antti Kettunen
fccc03efef
feat(import): badge auto-import status 2026-05-24 21:17:21 +03:00
Antti Kettunen
934a612df3
feat(form): add select size variants 2026-05-24 21:17:21 +03:00
Antti Kettunen
56f642aadd
test(import): remove stale frontend pytest
- delete the source-text guard for the old album lookup cache pattern\n- keep the import-page source-routing contract covered by Vitest route tests\n- avoid duplicating frontend behavior checks across pytest and the webui test suite
2026-05-24 21:17:21 +03:00
Antti Kettunen
0721a859a9
fix(import): keep count badge visible
- add a contrast override for badges inside primary buttons
- keep the singles process action aligned with the select/deselect row
- update import route tests for the new button label shape
2026-05-24 21:17:21 +03:00
Antti Kettunen
9f2c5c685b
refactor(import): simplify API failure handling
- rely on ky for transport errors across import/staging calls
- keep explicit soft-failure checks for auto-import approval endpoints
- add regression test for approval/rejection soft failures
2026-05-24 21:17:20 +03:00
Antti Kettunen
d32d88ea0e
refactor(webui): add shared badges to form kit
- add a reusable shared Badge primitive alongside the existing form controls\n- use it for the import auto-filter count pills and remove the route-local badge styles\n- tighten option button spacing so embedded badges read cleanly
2026-05-24 21:17:20 +03:00
Antti Kettunen
d066aba03d
refactor(webui): lean import buttons on shared styles
- move the import page over to shared button variants and option buttons
- strip route-local button chrome back to layout-only helpers
- keep the import route styling focused on layout, cards, and state indicators
2026-05-24 21:17:20 +03:00
Antti Kettunen
b78350a3e2
fix(webui): preserve import tab refresh URLs
- stop the legacy shell bootstrap from collapsing /import/auto and /import/singles back to the import root on reload\n- update the shell route smoke test to expect the canonical /import/album redirect for the bare import page
2026-05-24 21:17:20 +03:00
Antti Kettunen
ae0711f464
refactor(webui): theme shared import controls
- add a shared switch primitive for theme-aware toggle styling\n- keep import-page buttons leaning on shared variants instead of local color rules\n- simplify the singles and auto-import controls around the shared form layer
2026-05-24 21:17:20 +03:00
Antti Kettunen
af3d51c2ed
refactor(webui): theme import buttons
- add shared button variants and size controls backed by theme-aware styles
- move album import search controls onto shared button styling
- keep the import route layout-specific CSS limited to positioning
2026-05-24 21:17:20 +03:00
Antti Kettunen
0d7fb91d98
refactor(webui): share import form primitives
- add shared Base UI-backed checkbox and slider primitives under the form component layer
- move the singles import checkbox and auto-import confidence slider to the shared controls
- keep the import route tests aligned with the new accessible component roles
2026-05-24 21:17:20 +03:00
Antti Kettunen
aa86bedc6e
refactor(webui): key singles import state by file
- replace index-based singles selection and search state with stable staging file keys\n- keep refreshes from shifting selected rows or open search panels when files are inserted or reordered\n- add a regression test that proves selection stays attached to the intended file across refreshes
2026-05-24 21:17:20 +03:00
Antti Kettunen
89252cf6e4
fix(webui): refine import singles checkbox
- switch the singles selector to a real checkbox input for cleaner semantics\n- keep the mobile import page layout aligned while avoiding legacy button sizing\n- tune the checkbox tick so it stays visually centered and readable
2026-05-24 21:17:20 +03:00
Antti Kettunen
fe8ae8f290
fix(webui): restore import glyphs
- bring the React import page back in line with the legacy emoji/glyph treatment\n- restore album, singles, auto-import, and queue fallback icons\n- keep the visual refresh aligned with the old page while preserving the React port
2026-05-24 21:17:20 +03:00
Antti Kettunen
3fdc815794
fix(webui): show import refresh timestamp 2026-05-24 21:17:19 +03:00
Antti Kettunen
7853d0cfb8
chore(webui): remove legacy import feature js / css code 2026-05-24 21:17:19 +03:00
Antti Kettunen
27fbc80e7a
feat(webui): migrate import route to React
- Move import page, tabs, workflow state, and route tests into React-owned route slices
- Preserve shell gating, staging queries, album matching, singles matching, auto-import, and queue behavior
- Add migration plan snapshot so cleanup/refinement can build on a stable baseline
2026-05-24 21:11:40 +03:00
Antti Kettunen
5680e52ceb
refactor(webui): route stats interop through shell bridge
- move stats route legacy handoffs onto explicit SoulSyncWebShellBridge methods\n- stop relying on ad hoc window globals from React code for artist navigation and playback\n- update shell bridge tests and route test doubles to enforce the expanded bridge contract
2026-05-24 21:11:40 +03:00
Antti Kettunen
ff4c556257
feat(webui): migrate stats page to react
- move the stats route onto the React shell with Recharts-based visualizations
- remove the global Chart.js include and add a local stats seed script for easier testing
- keep parity coverage with route, API, and helper tests while preserving the legacy page layout
2026-05-24 21:11:40 +03:00
Broque Thomas
a3ba79a9ce Improve radio mode UI and behavior
Refactor and enhance the player radio feature: add npSetRadioMode, npQueueHasNext, and npEnsureCurrentTrackInQueue helpers to centralize radio-state changes and conditional radio fetch logic; replace direct npRadioMode toggles with npSetRadioMode in the expanded player and artist-radio flow (now awaits playLibraryTrack and triggers fetchIfNeeded). Add accessibility (aria-pressed) and label/pulse elements to the radio button, and update CSS for improved visuals and active-state animation. Also adjust toasts/messages and ensure the current library track is seeded into the queue when needed.
2026-05-24 11:02:19 -07:00
Broque Thomas
ccbe918808 Unify artist detail action buttons
Move the artist watchlist and discography actions into the main artist hero action row so they sit with Artist Radio and Enhance Quality. Apply a shared compact pill treatment for the hero actions while preserving the existing button IDs and click behavior.
2026-05-24 10:46:21 -07:00
Broque Thomas
9a0e3b4011 Persist completed downloads in downloads view
Include a capped recent tail of database-backed download history in the unified Downloads page so completed Deezer and other streaming downloads remain visible after runtime tasks are cleaned up or the container restarts. Use persistent download history for the dashboard finished count, keep live tasks authoritative for active rows, avoid showing the local clear-completed action for persisted history rows, and cover history hydration/deduping/capping in status tests.
2026-05-24 10:02:00 -07:00
Broque Thomas
4ca3f70bf3 Show MusicBrainz release variants in import
Expand matched MusicBrainz release groups into concrete releases for specific album searches so import users can choose the correct edition by track count, format, country, and disambiguation. Preserve distinct MusicBrainz release IDs instead of deduping same-title variants, carry release metadata through import matching, and surface those details on album result cards. Add coverage for variant preservation and release-group expansion.
2026-05-24 09:33:19 -07:00
Broque Thomas
7bee424686 Escape dash-leading YouTube search queries
Fix manual YouTube searches for video IDs that begin with a dash by escaping leading '-' before building yt-dlp ytsearch expressions. This preserves normal search terms and already escaped user input while preventing yt-dlp from treating the ID as search syntax.

Add regression coverage for both YouTube download search and video search paths. Fixes #684.
2026-05-24 08:54:47 -07:00
Antti Kettunen
c9ac9aeb1a
refactor(issues): use Link to open/close issues 2026-05-24 18:16:18 +03:00
Antti Kettunen
81bdf4355f
refactor(webui): link stats artist chips
- replace manual artist-detail navigation with declarative anchors
- reuse the shared artist-detail helper for bubble and ranked views
- keep the no-id bubble fallback non-interactive
2026-05-24 17:05:58 +03:00
BoulderBadgeDad
0af66b1bb4
Merge pull request #685 from Nezreka/dev
Dev
2026-05-24 01:54:42 -07:00
Broque Thomas
f68afe80c8 Update #524 lookup pattern test for consolidated renderer (#681)
The #681 commit (eba7f61e) collapsed the inline duplicate card-renderer
inside importPageSearchAlbum into a single _renderSuggestionCard call.
The structural test for the issue #524 lookup-cache pattern was still
counting inline cache writes and expecting >=2, which started failing
in CI now that the search-results renderer routes through the shared
helper.

Rewritten to assert the actual invariant of the consolidated design:

* _renderSuggestionCard contains exactly one _albumLookup write
* No other inline write exists (a second write means a caller is
  re-implementing the renderer instead of calling the helper — the
  exact duplication the #524 fix consolidated away)

Same regression guard, matches the new architecture.
2026-05-24 01:46:36 -07:00
Broque Thomas
3ee77e3f44 Release 2.6.0
MINOR bump: Qobuz playlist sync is the headline feature (#677), plus
the Import album search fallback-source surfacing fix (#681).

* web_server.py — _SOULSYNC_BASE_VERSION → 2.6.0
* webui/static/helper.js — split the 2.5.9 'Unreleased — dev cycle'
  entries into a new 2.6.0 block with a real release-date marker;
  bumped the _getLatestWhatsNewVersion fallback default; rolled the
  '2.5.9 Release Stability Pass' modal section down to a generic
  'Earlier in v2.5' aggregator now that 2.6.0 is the current release
* .github/workflows/docker-publish.yml — bumped manual version_tag
  default to 2.6.0 so the next workflow_dispatch defaults right
2026-05-24 01:35:15 -07:00