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 (
+
+
+
+ );
+ }}
+ />
);
}