mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
ad74578ef6528a9884eabf42aba7b1e8032dc3b4
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8004ec559c |
fix(analysis): persist library backfill scan phase across coordinator ticks (#882)
* fix(analysis): persist backfill scan phase and cursor across coordinator ticks Keep HashBpmGaps progress when the candidate SQL page is empty only because id > cursor; store scan phase in the native worker so each tick does not restart from Candidates and rescan the first ~10k ready tracks. * docs: CHANGELOG and credits for PR #882 backfill scan phase fix * fix(analysis): move backfill tests below production code for clippy Clippy items_after_test_module requires all non-test items before mod tests. |
||
|
|
b24a7fc5cb |
fix(analysis): native library backfill coordinator for advanced strategy (#881)
* feat(analysis): native library backfill coordinator for advanced strategy Move advanced analytics scheduling from the webview loop into a Rust background worker (configure + spawn_blocking batch/enqueue), matching cover backfill. Scan hash+BPM gap tracks instead of the full library; suppress low-priority analysis UI events; limit loudness refresh IPC to the playback window. * fix(analysis): flat backfill configure IPC and restore probe track-perf Use flattened Tauri args like cover backfill so release/prod invoke works; keep emitting analysis:track-perf for library low-priority work so Performance Probe tpm/last-track stats update while waveform/enrichment UI events stay suppressed. * chore(analysis): fix clippy and drop duplicate TS backfill policy Allow too_many_arguments on library_analysis_backfill_configure for CI; remove unused frontend batch API and TS watermark helpers now owned in Rust; clarify analysis_emits_ui_events comment for low-priority track-perf. * docs: CHANGELOG and credits for PR #881 native analysis backfill |
||
|
|
df3533bb5a |
fix(cover): Windows thumbnails, tier fallback, PNG decode, coverArt id (#878)
* fix(cover): tier fallback for sparse surfaces and Windows asset URLs Sparse UI (player bar, queue) now reads disk covers via the same tier ladder as dense grids, so a warm 800.webp satisfies a 128px request. Reject non-asset convertFileSrc results on Windows, widen Tauri asset scope, and seed ladder keys on cover:tier-ready. applyDiskPath uses seedGridDiskSrcCache only to avoid notify/subscriber infinite loops. * fix(artist): top-track thumb uses album coverArt already warm in grid Song coverArt ids often differ from album cover ids (e.g. Octastorium in the grid vs empty track thumb). Prefer the album row's coverArt on artist pages and ensure high priority for 32px dense cells. * fix(cover): albumId for playback/queue; no broken img until disk URL ready Prefer albumId over track-id coverArt (Navidrome). Wire queue to CoverArtImage with playback scope. CoverArtImage renders a placeholder div until asset src exists to avoid the browser broken-image icon. * fix(test): add song id to resolveArtistPageSongCoverArtId fixture Pick<SubsonicSong, …> requires id; fixes tsc in CI/build. * fix(cover): resolve albumId for Now Playing and artist top tracks Prefer albumId when album.coverArt echoes track id; use sparse surface on artist suggestion thumbs; apply resolveSubsonicSongCoverArtId across playback surfaces (Now Playing, fullscreen, mobile, mini). * fix(cover): decode PNG from Subsonic before WebP tier encode Enable `png` in the image crate — some servers return PNG cover art; failed decode left `.fetch-failed` and empty thumbs for those albums. * refactor(cover): consolidate cover id resolution and align tests Move resolveSubsonicSongCoverArtId helpers to src/cover/resolveCoverArtId.ts with resolvePlaybackTrackCoverArtId for player surfaces; co-locate tests; fix FullscreenPlayer expectations for albumId-first resolution. * docs: CHANGELOG and credits for PR #878 * fix(cover): keep per-track coverArt when distinct from song id Address PR #878 review (b): albumId only when coverArt is missing or echoes track id; pin case with unit test; comment isRawFsPath symmetry. * chore(cover): address PR #878 review nits (scope, tests, rename) Narrow asset scope to cover-cache dirs only; add diskSrcCache Windows-path tests; rename ArtistTopTrackCover; CHANGELOG symptom-first wording. * fix(cover): restore asset scope to app data dirs (Windows regression) $APPDATA/cover-cache/** did not match Tauri scope resolution — covers were blocked after load. Use $APPDATA/** and $APPLOCALDATA/** (no $DATA). * fix(cover): Windows asset URLs — restore DATA scope, path normalize Regression after review nits: dropped $DATA/** and strict isAssetProtocolUrl blocked valid http://asset.localhost URLs on Windows. Normalize C:/ paths before convertFileSrc; CoverArtImage/Hero hide broken img on load error. * fix(cover): disk peek fallbacks when cache folder id differs Small surfaces resolve albumId while cover-cache often stores WebP under track id or album.coverArt from the grid. Peek batch now tries legacy ids; playback scope resolves server index key by URL key, not UUID-only lookup. * fix(cover): Navidrome al-* vs mf-* disk id mismatch UI used mf-* coverArtId while library backfill only cached al-* folders. Prefer album id for display/peek when coverArt is mf-*; backfill now queues both distinct album_id and cover_art_id values. * fix(cover): mf→al disk peek when mf folder missing in cache Navidrome Subsonic often returns mf-* coverArtId while backfill only creates al-* folders. Peek mf first, then al-* from hints; load albumId from library when Subsonic omits it; ensure fallback uses al-* id. * feat(cover): CoverArtRef, segment disk layout, library-index backfill Normalize cover caching around stable entity ids from the local library and Navidrome fetch ids. Disk paths live in psysonic_core::cover_cache_layout (album/<entityId>/); UI uses CoverArtRef with cacheEntityId + fetchCoverArtId. - Remove SQLite/mf peek helpers (diskPeekIds, peekCoverOnDisk, mergeDiskIdHints) - Backfill reads album/artist rows from library SQLite (bare Navidrome ids ok) - Use stored cover_art_id for HTTP; per-disc dirs only when discs differ - Migrate call sites to albumCoverRef / albumCoverRefForPlayback * feat(cover): central CoverEntry resolver (artist, album, track) Add resolveEntry.ts and Rust CoverEntry helpers as the single source of truth for cache_entity_id vs fetch_cover_art_id. ref.ts delegates to them; resolveCoverArtId becomes a thin compatibility shim. * feat(cover): resolve cover entries from local library index Add library_resolve_cover_entry IPC and cover_resolve.rs so album, artist, and track covers use SQLite cover_art_id + disc detection. TypeScript helpers in resolveEntryLibrary.ts prefer the index over live API fields when rows exist. * feat(cover): library-first hooks for grids and playback UI Add useAlbumCoverRef, useArtistCoverRef, useTrackCoverRef, and usePlaybackTrackCoverRef — sync fallback then SQLite index upgrade. Wire album/artist cards, album header, song card, and all player surfaces to resolve covers from the local library when indexed. * feat(cover): complete library-first migration across all UI surfaces Add Album/Artist/TrackCoverArtImage, useLibraryCoverPrefetch, and batch resolve helpers. Migrate grids, search, home, playback sidecars, warm peek, playlists, and share flows to hooks that upgrade from SQLite. Backfill normalizes album rows through cover_resolve; document paths in COVER_PATHS.md. Radio remains a deliberate non-library exception. * fix(cover): stop render loop from unstable serverScope in library hooks Default param `{ kind: 'active' }` created a new object every render, so every grid cell re-ran library_resolve IPC and setState in a loop. Use COVER_SCOPE_ACTIVE singleton, coverScopeKey deps, and guarded sync updates. * chore(cover): remove COVER_PATHS.md from app tree (lives in workdocs) Audit doc is team spec — see workdocs 2026-05-cover-art-pipeline/cover-paths-audit.md. * fix(cover): unstick library backfill after route changes (PR #870 regression) useCoverNavigationPriority cleanup called beginNavigation instead of end, leaking navigationHoldDepth so ui_priority_hold never released and backfill never downloaded. Also skip disk check after cover_resolve normalization. * fix(cover): segment progress, cap backfill CPU, include artists in catalog Progress and disk size now scan album/ and artist/ segments (canonical 800.webp). Prune legacy flat server/al-* dirs on startup and backfill pass. Backfill: max 2 concurrent ensures; JPEG decode and WebP encode run on the blocking pool behind a shared 2-permit semaphore so Tokio workers stay cool. Artists were missing because the catalog only read the empty artist table; add distinct artist_id from track and album rows. Paginate with a composite (kind, id) cursor so album and artist rows are not skipped. * fix(cover): drop legacy prune; backfill per-disc and artist catalog Remove prune_legacy_* and cover_cache_catalog_entry — layout is only cover_dir (album|artist segments); stale flat dirs clear on LAYOUT_STAMP change. Backfill: artists from track/album artist_id; expand albums to per-CD mf-* slots when discs differ; fix resolve_album_cover_entry when album row is missing. * fix(cover): reduce library IPC storms and fix multi-disc player art Skip per-row library_resolve on live search and artist album grids; warm grids from API coverArt after mount instead of blocking layout. Dedupe and cap concurrent library_resolve calls. Restore per-disc cache keys in the player and queue when track mf-* art differs from the album bucket. * fix(cover): skip library resolve on advanced and full search rows Use API coverArt for album/artist rails and lazy viewport artwork so result pages do not fire hundreds of library_resolve IPC calls at once. * fix(cover): default libraryResolve off for browse grids and rails Skip per-card library_resolve on album/artist/song browse UI by default; keep it on album/artist headers, playback queue rows, and orbit approval. * fix(cover): split UI/backfill CPU pools and restore mainstage hero carousel Library backfill no longer shares the 2-permit JPEG/WebP semaphore with visible cover ensures. Hero initializes albums from props, re-binds scroll visibility after mount, updates backdrop on slide change, and uses library resolve for correct cover art on the banner. * fix(analysis): resume full-library scan after candidates phase Reset the SQL cursor when entering full-library mode so tracks with partial analysis are not skipped. Tighten TS backfill completion and CPU queue watermarking; align cover-cache key tests with album-scoped storage keys. * fix(library): remove useless map_err in cover_resolve (clippy) CI treats clippy::useless-conversion as error on rusqlite optional() chains. * fix(cover): satisfy clippy on cover_cache_ensure IPC args Pass CoverCacheEnsureArgs as a single Tauri parameter instead of nine positional fields; align frontend invoke payload with { args }. |
||
|
|
11974e1438 |
feat(analysis): ship index-key rebuild, strategy controls, and playback/queue pipeline updates (#864)
* feat(analysis): align index settings and per-server strategies Rebuild the local index UX to live under Servers with per-server analytics strategies, and scope analysis queue hints/pruning by playback server so priorities stay isolated across profiles. * feat(analysis): add progress tracking and server analysis deletion functionality Introduce new interfaces for tracking library analysis progress and reporting on server analysis deletions. Implement functions to retrieve analysis progress for a server and to delete all analysis data for a specified server, enhancing the analytics strategy section with real-time progress updates and management capabilities. Update relevant components and localization files to support these features. * feat(server): implement server index key migration and enhance server ID resolution Add functionality to migrate server index keys from legacy IDs to new URL-based keys, improving server ID resolution across the application. Introduce new types and commands for handling server key migrations in both analysis and library contexts. Update relevant functions to utilize the new server ID resolution logic, ensuring consistency and accuracy in server-related operations. * refactor(library): simplify server ID handling in sync progress and idle subscriptions Refactor the library sync progress and idle subscription functions to directly use the payload's server ID without additional mapping. Update related components to resolve server IDs using a new utility function, ensuring consistent server ID resolution across the application. This change enhances code clarity and maintains functionality. * refactor(analytics): rename advanced strategy to aggressive and update descriptions Refactor the AnalyticsStrategySection component to rename the 'advanced' strategy to 'aggressive' for clarity. Update related localization strings to reflect this change, enhancing the user experience by providing clearer descriptions of the analytics strategies. Additionally, remove unused strategy description functions to streamline the code. * fix(audio): update server ID handling in audio progress functions Refactor the audio progress handling to utilize the new `getPlaybackIndexKey` function for server ID resolution. This change ensures that the correct analysis server ID is used when processing audio progress, enhancing the accuracy of playback operations. Additionally, a minor update was made to the analysis cache to include a checkpoint after seeding from bytes. Update the library path in live search to reflect the new database structure. * refactor(analysis): update server ID handling and drop legacy keys Refactor server ID handling across analysis components to utilize scheme-less keys (host + optional path) instead of legacy scheme-based keys. Introduce SQL migrations to drop legacy analysis rows and library entries keyed by scheme URLs. Update relevant functions and tests to ensure consistent server ID resolution and remove references to the legacy '' scope, enhancing clarity and maintainability. * refactor(migration): switch to strategy C dual-db flow Replace destructive server-key migration paths with a blocking inspect/run pipeline that imports into v2 sqlite files, verifies data, then switches active databases with backup safety. Add frontend migration orchestration and post-switch key rewrites while preserving existing user settings behavior. * fix(migration): harden runtime db switch and startup gate Switch database promotion through live runtime store/cache connection swaps so migration cannot leave writers on old sqlite inodes, and tighten startup gating to block initialization until migration completes. Also fix empty-bucket warning detection and set the done flag only after a post-run inspect confirms no pending legacy rows. * feat(migration): enhance migration reporting with skipped server rows tracking Add new fields to migration interfaces and reports to track skipped rows for removed servers. Update relevant components to display warnings and log messages when such rows are encountered during migration processes, improving visibility and user awareness of migration status. * fix(migration): avoid startup blocking modal on no-op runs Keep migration gate completed by default after successful runs and perform done-flag inspections without forcing a blocking phase, so normal app startup no longer flashes migration preparation when no migration is needed. * fix(migration): enforce startup precheck and purge unknown rows Prevent stale done-flag bypass by starting migration state in idle and gating completion on orchestrator precheck, and delete unknown removed-server rows from v2 databases before switch so skipped rows are not carried into the new active DB. * fix(migration): block UI during done-flag precheck Set inspecting phase before the first migration inspection and treat idle as blocking in the migration gate, so startup precheck cannot render the app before migration status is confirmed. * fix(migration): hide precheck modal when no migration is needed Keep startup precheck in a non-blocking idle phase and show the migration modal only after inspect confirms real migration work, removing the recurring half-second migration flash for already-migrated users. * fix(migration): cleanup legacy db files after path migration Always remove legacy analysis and library sqlite files (including wal/shm sidecars) when the new database paths are active, so old-path artifacts from previous builds do not linger after migration. * docs(changelog): add PR #864 release notes and contributor credit Document the full index-key rebuild scope for 1.47.0 and add the corresponding settings credit entry for PR #864. * test(analysis): raise hot-path coverage for analysis cache Add focused unit tests for analysis cache compute/store hot paths and edge branches so coverage regressions are caught before CI. Make AppHandle entrypoints runtime-generic and enable tauri test utilities in dev dependencies to cover no-cache and registered-cache execute paths. * fix(migration): make rebind pass resilient to foreign key ordering Run library and analysis server_id rebind operations inside a foreign-key-disabled transaction and validate with PRAGMA foreign_key_check after commit, so migrations from older databases do not fail on transient FK ordering during bulk updates. * feat(backup): add dual-database backup flow and blocking UX Extend backup/export and restore flows to handle library databases with unified archive detection and asynchronous backend execution. Improve backup UI with a global blocking modal and clearer localized copy so long operations do not look like app hangs. * docs(changelog): add PR #864 backup notes and contributor credit Update 1.47.0 release notes with backup/restore UX and archive-flow entries for PR #864, and add the matching settings credits contribution line for cucadmuh. * docs(changelog): sort 1.47.0 entries from old to new Reorder Added, Changed, and Fixed subsections in the 1.47.0 changelog so entries follow chronological PR order inside each block. * fix(playback): align offline/hot cache lookup with indexKey scope Use a canonical playback cache key based on indexKey with legacy UUID fallback so migrated offline and hot-cache entries are still resolved on normal play, resume, queue-undo, and prefetch paths. Refresh PR #864 changelog/credits text to reflect the full migration and backup scope. |