From 100cc14eda4cf22955f16235596898b07021510a Mon Sep 17 00:00:00 2001 From: vineyardbovines Date: Wed, 22 Apr 2026 10:55:03 -0400 Subject: [PATCH] fix(gifPicker): only remount grid on recents/network boundary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The viewKey added to prevent stale search cells in the recents view was keyed on `network:${effectiveSearch}`, so it changed on every throttled search update and category switch. Remounting the FlatList remounts its ListHeaderComponent too, which blurred the sticky-header search input (eating the first typed character) and caused a visible reload when switching categories. Drop the search term from the key — the recents bug was about crossing the recents/network boundary, and React reconciliation handles item changes within the network view on its own. Addresses PR #10261 feedback from surfdude29: keyboard dismissing on search and category-switch reload glitch. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/features/gifPicker/GifPickerDialog.tsx | 11 +++++++---- src/features/gifPicker/components/GifPickerGrid.tsx | 7 ++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/features/gifPicker/GifPickerDialog.tsx b/src/features/gifPicker/GifPickerDialog.tsx index 24476d08fd..08d126b876 100644 --- a/src/features/gifPicker/GifPickerDialog.tsx +++ b/src/features/gifPicker/GifPickerDialog.tsx @@ -100,9 +100,12 @@ function GifPickerBody({ const items = isRecentsActive ? getRecents() : networkItems const hasData = items.length > 0 - // Remount the grid when the data source changes so FlatList doesn't carry - // stale virtualized cells between e.g. a search and the recents list. - const viewKey = isRecentsActive ? 'recents' : `network:${effectiveSearch}` + // Remount the grid only when switching between the network view and the + // local recents list, so FlatList doesn't carry stale virtualized cells + // across that boundary. Within the network view we rely on normal React + // reconciliation as `items` changes — remounting on every search keystroke + // would blur the sticky-header search input. + const viewKey = isRecentsActive ? 'recents' : 'network' const onEndReached = () => { if (isRecentsActive) return @@ -142,7 +145,7 @@ function GifPickerBody({ control.close()} + onGoBack={onGoBack} onEscape={() => control.close()} /> {showPills && ( diff --git a/src/features/gifPicker/components/GifPickerGrid.tsx b/src/features/gifPicker/components/GifPickerGrid.tsx index dccb3c094c..5d3870954e 100644 --- a/src/features/gifPicker/components/GifPickerGrid.tsx +++ b/src/features/gifPicker/components/GifPickerGrid.tsx @@ -16,9 +16,10 @@ type Props = { isFetchingNextPage: boolean error: unknown /** - * Identifies the current data source (e.g. "recents", "trending", a search - * term). Used to remount the underlying FlatList when switching sources so - * virtualized cells from the previous view can't bleed into the next one. + * Identifies the current data source at a coarse grain ("recents" vs + * "network"). Used to remount the underlying FlatList when crossing that + * boundary so virtualized cells from the previous view can't bleed into the + * next one. */ viewKey: string fetchNextPage: () => Promise