mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
cd47a4b0fae8c087f4f6f01865d05d009ec977f9
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4ac373a65b |
feat(search): scoped live search on browse pages (#938)
* feat(artists): scoped live search badge replaces page filter Move Artists browse text search into the header Live Search with a page scope badge (Users icon), field-local undo, and double-click/backspace to clear scope. Block the live-search dropdown while scoped so results only filter the Artists grid; mobile overlay follows the same rules. * fix(artists): plain grid for scoped search fixes broken card layout Route the browse grid through VirtualCardGrid, switch to non-virtual CSS grid when live search filters the catalog, reset scroll on filter changes, and skip content-visibility on plain tiles to avoid blank/black cards. * fix(search): scope badge double-Backspace and single clear control Require two Backspaces on an empty scoped field after prior text input; one Backspace still clears the badge when the field was never filled. Move live-search clear/advanced controls inside the field pill, drop the extra outer clear button, and use type=text to avoid native search clears. * fix(search): drop duplicate outer live-search clear button Keep the native in-field clear on type=search and the original pill layout; remove only the extra × control outside the search border. Reset dropdown state when the query is cleared via the native control. * refactor(search): generic scoped browse query helper, drop dead code Rename artistsBrowseSearchQuery to scopedBrowseSearchQuery with an expectedScope argument; wire Artists via useScopedBrowseSearchQuery. Remove unused liveSearchScoped dropdown helper (scoped mode blocks it). * feat(search): ghost scope badge and single-click badge remove After clearing the artists scope on /artists, show a faded ghost chip to restore page-only search while keeping the global search placeholder. Active badge removes on one click; tooltips and styles updated. * feat(search): scoped live search for All Albums and New Releases Wire albums and newReleases scope badges with debounced album title search (local index title-only FTS + filtered search3). Plain grid, scroll reset, and session query restore on album grid browse pages. * fix(browse): preserve scroll restore after album/artist detail back Only reset in-page scroll when filter resetKey changes, not when isScrollRestorePending clears after session restore. * feat(search): scoped live search for Tracks browse Wire /tracks to header live search with wide title/artist/album FTS, hide hero and discovery rails while search is active, and remove the inline search field from the browse list. * fix(search): clear header query when leaving scoped browse pages Prevent global live search from firing on album/detail routes after a scoped browse query; browse session stashes still restore on back. * fix(tracks): restore scroll after back from detail during scoped search Hold stashed song results across fetchSongPage churn, defer leave-stash teardown past AppShell scroll reset, restore tracks scroll after the list is ready, and save scroll snapshot when opening artist from song context menu. * fix(tracks): hide discovery headings during scoped search Hide the page subtitle and "Browse all tracks" section title when tracks search is active, matching hero/rails chrome behavior. * feat(search): scoped live search for Composers browse Wire /composers to header live search with composers scope badge, session stash, scroll restore, and plain grid/list during text filter. Remove the in-page filter input; add i18n and navigation helpers. * docs: CHANGELOG and credits for scoped browse live search (PR #938) |
||
|
|
ddf10ee01d |
feat(genres): local index genre browse with Subsonic fallback (#937)
* feat(genres): genre detail browse via local index with aligned counts Move genre detail albums/play/shuffle onto the local library index with Albums-style in-page scroll, session restore, and genre-scoped stash. Unify genre album totals between the cloud and detail pages via library_get_genre_album_counts, and fix grouped browse totals to count distinct albums rather than matching tracks. * perf(genres): local genre browse with scoped counts cache Add dedicated Rust genre album pagination and indexes, slice-mode grid loading, library-filter-aware counts, and a long-lived in-memory catalog cache invalidated on sync so genre pages avoid repeated full-library SQL. * fix(genres): restore scroll after album back; play hold-to-shuffle Pin restore display count in refs so clearing the return stash no longer reloads the genre grid mid-restore. Load the first SQL page only (60 rows), use long-press on Play for shuffle, and add genre play tooltips. * fix(genres): fall back to Subsonic byGenre when local index unavailable Genre detail album grid now matches All Albums: try library_list_albums_by_genre first, then getAlbumsByGenre when the index is off, not ready, or errors. * docs: add CHANGELOG and credits for PR #937 |
||
|
|
d3e5a6b704 |
feat: library browse navigation — restore filters, scroll, and search on back (#936)
* feat(albums): restore scroll position when returning from album detail Save in-page scroll and grid depth when opening an album from All Albums, then on browser back restore filters, preload enough rows, and apply scroll before revealing the grid to avoid a visible jump from the top. * feat(albums): smart back navigation and restore browse session on return Remember the originating route when opening album detail, restore All Albums filters/scroll on back (including explicit returnTo navigation), hide the grid until scroll is applied, and fix filters being cleared after albumBrowseRestore state is stripped from the location. * feat(search): restore Advanced Search session when returning from album Stash filters and results when leaving /search/advanced for album detail, then restore them on back navigation (POP or returnTo with advancedSearchRestore). * feat(search): restore Advanced Search album row scroll on return from album Save horizontal scrollLeft when opening an album from Advanced Search and reapply it via AlbumRow on return; keep main viewport at top. Add snapshot helpers and session stash fields; extend AlbumRow with restoreScrollLeft. * feat(search): restore Advanced Search session scroll and artist return path Save filters, main scroll, and album-row scroll when leaving to album or artist; restore without flash via hidden-until-ready. Add useNavigateToArtist, restoreMainViewportScroll helper, and AppShell scroll reset only on pathname change. * feat(search): speed up Advanced Search back restore and year-only queries Reveal the page right after sync scroll instead of blocking on full viewport and album-row restore. Retry local index without the ready gate during sync; use open-ended byYear params on network fallback, matching All Albums browse. * feat(search): restore Advanced Search artist row scroll on back Save leave snapshot when opening artist from ArtistCardLocal, persist artistRowScrollLeft in session stash, and keep row restore targets in refs so horizontal scroll survives finishLeaveRestoreUi like vertical scrollTop. * feat(nav): route mouse back on album/artist detail like UI back Trap history popstate when returnTo is set and call navigateAlbumDetailBack so browser/mouse back restores browse/search session the same way as the header button. * feat(artists): restore browse filters and scroll on back from artist detail Persist Artists page filters, view settings, and vertical scroll when opening an artist and returning via UI or mouse back, matching All Albums behavior. * feat(search): unify quick and advanced search; fix LiveSearch dismiss on Enter Serve /search and /search/advanced from one page with shared session restore and scroll snapshot. Reset live search overlay state when navigating to full search so the dropdown does not linger or reopen. * feat(tracks): unify with search session and restore scroll on back Route /tracks through AdvancedSearch with shared leave snapshot, song browse stash, and main-viewport scroll restore when returning from album or artist detail. Wait for hero/rails layout before applying scroll. * refactor(search): rename AdvancedSearch page to SearchBrowsePage The shared route shell serves /search, /search/advanced, and /tracks; rename the page component and refresh stale file references in comments. * feat(albums): restore New Releases and Random Albums on back from detail Unify album grid leave-restore with surface-scoped session stash, live scroll snapshot sync, and in-page scroll for Random Albums. Keep the same random batch when returning from album detail; Refresh fetches anew and scrolls up. * docs: add CHANGELOG and credits for PR #936 |
||
|
|
06da15caf3 |
feat(albums): combined browse filters, favorites reconcile, and session restore (#876)
* feat(albums): persist browse sort and genre filter for the session Keep Albums sort and genre selection in an in-memory Zustand store so navigating into album detail and back no longer resets browse context. Fixes #875 (partial). * feat(albums): restore browse filters only when returning from album detail Keep sort in the session store for the app lifetime. Stash genre, year, compilation, starred, and lossless filters when leaving Albums for an album page and restore them on POP (back). Clear the stash when opening Albums from elsewhere via sidebar navigation. * feat(albums): filter quick-clear chips; fix lossless A–Z sort Add inline × on active toolbar filters (genre, year, favorites, lossless, compilations) without opening the popover. Route lossless album browse through advanced search with album sort clauses on Albums and Lossless Albums; client-sort on the network fallback path. * fix(albums): apply year filter when only from or to is set Resolve open-ended year bounds with gte/lte on the local index and partial fromYear/toYear on Subsonic. Update the year filter chip label for single-bound ranges. * refactor(albums): combine browse filters in one query (genre + year + lossless) Replace mutually exclusive load/loadFiltered branches with fetchAlbumBrowsePage that ANDs server-side filters on the local index (genre OR union). Network fallback applies year bounds after genre fetch. Always show sort while a year filter is active. * fix(albums): load favorites filter server-side instead of scanning all albums Starred on Albums was client-only: each page was filtered locally and pendingClientFilterMatch kept paginating the full catalog. Query starred albums via the local index or getAlbumList(starred); apply overrides only for in-session star/unstar. * feat(library): local album/artist favorites via patch-on-use Mirror album- and artist-level stars into the library index (library_patch_album, library_patch_artist, migration 010). Albums and Artists favorites browse use entity starred_at only; normal album catalog stays track-derived so patch stubs do not hide the library. Keep album year on favorite cards via track COALESCE, patch metadata, and safer raw_json merge. * fix(library): reconcile album/artist stars from server, drop stubs Favorites browse uses getAlbumList/getStarred2 as source of truth. library_reconcile_*_stars clears local stars removed elsewhere; patch-on-use updates existing rows only (no stub INSERT). Reconcile on favorites load and after star/unstar in-app. * feat(albums): favorites reconcile, filter combos, and back-navigation fix Album browse keeps filter state when returning from album detail (POP stash read on mount, request-generation guard against stale loads). Favorites use getStarred2 as source of truth: reconcile album.starred_at in the local index (UPDATE only, no stub rows), with a small session cache for instant paint. Combine favorites with lossless or genre via restrictAlbumIds in advanced search. Remove album/artist patch-on-use and migration 010; artist favorites stay network-only. Track patch-on-use unchanged. * feat(albums): catalog year bounds and genre list narrowed by filters Year filter spinners use min/max years from the local track index (not 1900); "from" starts at oldest, "to" at newest, values clamp to catalog. When year, lossless, favorites, or compilation filters are active, the genre picker lists only genres present on matching albums (other filters applied, genre excluded). Adds library_get_catalog_year_bounds for the year UI. * feat(albums): debounce year filter and show genre album counts Debounce year range changes by 350ms before reloading browse. Genre picker lists album counts per genre (from getGenres or from albums matching other active filters) and sorts genres by count descending. * fix(albums): compilation filter detection and scan cap Recognize OpenSubsonic compilation flags (compilation, releaseTypes) so client-side comp filters work on local index rows. Cap background pagination at 500 albums when no matches are visible and show empty state instead of spinning through the whole catalog. * feat(albums): filter compilations via local library index Add `compilation` to advanced search (album entity): reads OpenSubsonic flags from album raw_json. Album browse passes compFilter into library_advanced_search when the index is ready; network-only path keeps client-side filtering with the existing scan cap. * fix(albums): apply compilation filter on track-grouped index browse Album browse uses track aggregation, so compilation clauses were skipped. Filter track raw_json (same SQL as album), merge album flags at sync, and always run the client-side compilation pass as a fallback. * refactor(albums): split browse modules and extract browse_support commands Move album browse fetch/filter logic into focused modules and useAlbumBrowseData; register reconcile/year-bounds Tauri commands from browse_support. Trim dead helpers and barrel exports; fix typecheck in compilation tests. * chore: note PR #876 in CHANGELOG and settings credits * fix(albums): show catalog min/max in partial year filter chip label When only from or to year is set, the active chip now reads e.g. 1990–2020 instead of 1990– or –2025, using indexed catalog bounds when available. |