mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 22:45:41 +00:00
fix(virtual): apply scrollMargin to remaining useVirtualizer call-sites (#766)
* refactor(virtual): extract scrollMargin measurement into a reusable hook VirtualCardGrid carried its own useLayoutEffect + ResizeObserver block for the scroll-margin computation introduced in #764. The same pattern is needed on every other useVirtualizer site whose wrapper sits below other content; pull it out as useVirtualizerScrollMargin so each call-site is a single hook invocation instead of a 20-line duplicate. No behavior change for VirtualCardGrid — same scroll element, same deps, same observed nodes. * fix(virtual): apply scrollMargin to the remaining useVirtualizer call-sites #764 fixed the symptom for VirtualCardGrid (Albums / Artists grid via the shared component, Composers grid, "More by …" rail, etc.) but four more useVirtualizer call-sites have the same shape — wrapper sits below a sticky page header and TanStack would otherwise place rows starting at the scroll-element top, unmounting rows that are still in the viewport and at higher offsets refusing to render at all: - Artists grid view (Artists.tsx + ArtistsGridView.tsx) — under the sticky title + filter row + alphabet bar (~150–250 px depending on alphabet wrap). - Artists list view (Artists.tsx + ArtistsListView.tsx) — same header stack; flat letter/row stream means a noticeable jump on long libraries. - Composers list view (Composers.tsx) — identical header stack to Artists. - VirtualSongList — ~36 px sticky song-list header inside its own scroll container; the offset was small enough to be absorbed by overscan, but the pattern was the same so wire it up for consistency. Each call-site now feeds wrapRef + scroll-element lookup into useVirtualizerScrollMargin and forwards the value into useVirtualizer + the translateY of each rendered row. * docs(changelog): note PR #766 under Fixed in v1.46.0
This commit is contained in:
committed by
GitHub
parent
d3fc5c91fc
commit
48a69754d6
@@ -2,6 +2,7 @@ import { searchSongsPaged } from '../api/subsonicSearch';
|
||||
import type { SubsonicSong } from '../api/subsonicTypes';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useRefElementClientHeight } from '../hooks/useResizeClientHeight';
|
||||
import { useVirtualizerScrollMargin } from '../hooks/useVirtualizerScrollMargin';
|
||||
import { Search as SearchIcon, X } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
@@ -139,11 +140,19 @@ export default function VirtualSongList({ title, emptyBrowseText }: Props) {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const virtualWrapRef = useRef<HTMLDivElement>(null);
|
||||
const scrollMargin = useVirtualizerScrollMargin(
|
||||
virtualWrapRef,
|
||||
() => scrollParentRef.current,
|
||||
{ active: true, deps: [songs.length] },
|
||||
);
|
||||
|
||||
const virtualizer = useVirtualizer({
|
||||
count: songs.length,
|
||||
getScrollElement: () => scrollParentRef.current,
|
||||
estimateSize: () => ROW_HEIGHT,
|
||||
overscan: songListOverscan,
|
||||
scrollMargin,
|
||||
});
|
||||
|
||||
const totalSize = virtualizer.getTotalSize();
|
||||
@@ -187,7 +196,7 @@ export default function VirtualSongList({ title, emptyBrowseText }: Props) {
|
||||
<>
|
||||
<div ref={scrollParentRef} className="virtual-song-list-scroll">
|
||||
<SongListHeader />
|
||||
<div style={{ height: totalSize, width: '100%', position: 'relative' }}>
|
||||
<div ref={virtualWrapRef} style={{ height: totalSize, width: '100%', position: 'relative' }}>
|
||||
{virtualizer.getVirtualItems().map(vi => {
|
||||
const song = songs[vi.index];
|
||||
if (!song) return null;
|
||||
@@ -200,7 +209,7 @@ export default function VirtualSongList({ title, emptyBrowseText }: Props) {
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: ROW_HEIGHT,
|
||||
transform: `translateY(${vi.start}px)`,
|
||||
transform: `translateY(${vi.start - scrollMargin}px)`,
|
||||
}}
|
||||
>
|
||||
<SongRow
|
||||
|
||||
Reference in New Issue
Block a user