fix(playlist): sorting a column no longer snaps the viewport (#840) (#848)

* fix(playlist): sorting a column no longer snaps the viewport (#840)

Sorting flipped `isFiltered` (which means displayedSongs !== songs, so it
also goes true once a sort is active), and the scroll-to-list effect fired
on `[id, isFiltered]` → the viewport snapped down to the list. Drive that
effect from a dedicated `hasActiveFilter` (filter text only), so sorting
applies in place; filter and playlist-switch scrolling are unchanged.

* docs(changelog): playlist sort viewport fix (#848)
This commit is contained in:
Frank Stellmacher
2026-05-22 01:18:29 +02:00
committed by GitHub
parent 5bf2441ccf
commit bd742c958c
3 changed files with 15 additions and 2 deletions
+8
View File
@@ -127,6 +127,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Playlists — column sorting keeps the viewport in place
**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#848](https://github.com/Psychotoxical/psysonic/pull/848)**
* Sorting a playlist column no longer snaps the viewport down to the list when scrolled to the top.
## [1.46.0] - 2026-05-18
> **🙏 Special thanks to [@zz5zz](https://github.com/zz5zz)** for his tireless quirk-spotting and bug reports on the [Psysonic Discord](https://discord.gg/AMnDRErm4u) — several of the polish fixes in this release landed directly off the back of his messages.
@@ -41,6 +41,10 @@ interface Props {
displayedSongs: SubsonicSong[];
displayedTracks: Track[];
isFiltered: boolean;
/** True only while a filter text is active — distinct from `isFiltered`,
* which also goes true while sorting (displayedSongs !== songs). Drives the
* scroll-to-list effect so sorting doesn't snap the viewport (issue #840). */
hasActiveFilter: boolean;
id: string | undefined;
// Sort
@@ -82,7 +86,7 @@ interface Props {
export default function PlaylistTracklist({
allColumns, visibleCols, gridStyle, colVisible, toggleColumn, resetColumns,
pickerOpen, setPickerOpen, pickerRef, startResize, tracklistRef,
songs, displayedSongs, displayedTracks, isFiltered, id,
songs, displayedSongs, displayedTracks, isFiltered, hasActiveFilter, id,
sortKey, setSortKey, sortDir, setSortDir, sortClickCount, setSortClickCount,
selectedIds, setSelectedIds, allSelected, toggleAll, toggleSelect,
showBulkPlPicker, setShowBulkPlPicker, bulkRemove,
@@ -190,7 +194,7 @@ export default function PlaylistTracklist({
const sc = document.getElementById(APP_MAIN_SCROLL_VIEWPORT_ID);
if (sc) sc.scrollTop = scrollMargin;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id, isFiltered]);
}, [id, hasActiveFilter]);
const autoScrollRef = useRef(0);
const pointerYRef = useRef(0);
+1
View File
@@ -349,6 +349,7 @@ export default function PlaylistDetail() {
displayedSongs={displayedSongs}
displayedTracks={displayedTracks}
isFiltered={isFiltered}
hasActiveFilter={filterText.trim().length > 0}
id={id}
sortKey={sortKey}
setSortKey={setSortKey}