From eb625c9d96e0fe4226e03bc5d56b09d1ff05f644 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Mon, 23 Jun 2025 00:36:32 +0200 Subject: [PATCH] Virtualize source list --- src/modules/browse/screens/Browse.tsx | 2 +- src/modules/source/components/SourceCard.tsx | 7 +- src/modules/source/screens/Sources.tsx | 76 +++++++++++++------- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/modules/browse/screens/Browse.tsx b/src/modules/browse/screens/Browse.tsx index 139d2162..a1d49769 100644 --- a/src/modules/browse/screens/Browse.tsx +++ b/src/modules/browse/screens/Browse.tsx @@ -58,7 +58,7 @@ export function Browse() { - + diff --git a/src/modules/source/components/SourceCard.tsx b/src/modules/source/components/SourceCard.tsx index febf6641..21bddb20 100644 --- a/src/modules/source/components/SourceCard.tsx +++ b/src/modules/source/components/SourceCard.tsx @@ -59,12 +59,7 @@ export const SourceCard: React.FC = (props: IProps) => { ); return ( - + ('shownSourceLangs', getDefaultLanguages()); @@ -66,6 +70,23 @@ export function Sources() { () => SourceService.areFromMultipleRepos(filteredSources), [filteredSources], ); + const visibleSources = useMemo( + () => sourcesByLanguage.map(([, sourcesOfLanguage]) => sourcesOfLanguage).flat(1), + [sourcesByLanguage], + ); + + const groupCounts = useMemo( + () => sourcesByLanguage.map((sourceGroup) => sourceGroup[1].length), + [sourcesByLanguage], + ); + const computeItemKey = VirtuosoUtil.useCreateGroupedComputeItemKey( + groupCounts, + useCallback((index) => sourcesByLanguage[index][0], [sourcesByLanguage]), + useCallback( + (index, groupIndex) => `${sourcesByLanguage[groupIndex][0]}_${visibleSources[index].id}`, + [visibleSources], + ), + ); const navigate = useNavigate(); @@ -102,27 +123,32 @@ export function Sources() { } return ( - <> - {sourcesByLanguage.map(([language, sourcesOfLanguage]) => ( - - - {translateExtensionLanguage(language)} - - {sourcesOfLanguage.map((source) => ( - - ))} - - ))} - + { + const [language] = sourcesByLanguage[index]; + + return ( + + + {translateExtensionLanguage(language)} + + + ); + }} + itemContent={(index) => { + const source = visibleSources[index]; + + return ( + + + + ); + }} + /> ); }