diff --git a/components/search/TVJellyseerrSearchResults.tsx b/components/search/TVJellyseerrSearchResults.tsx index cba3a5548..699c50401 100644 --- a/components/search/TVJellyseerrSearchResults.tsx +++ b/components/search/TVJellyseerrSearchResults.tsx @@ -401,10 +401,6 @@ export const TVJellyseerrSearchResults: React.FC< }) => { const { t } = useTranslation(); - const hasMovies = movieResults && movieResults.length > 0; - const hasTv = tvResults && tvResults.length > 0; - const hasPersons = personResults && personResults.length > 0; - if (loading) { return null; } @@ -431,22 +427,26 @@ export const TVJellyseerrSearchResults: React.FC< return ( + {/* No section requests `hasTVPreferredFocus`: the native search field + keeps focus while typing, otherwise the first result would re-grab + focus on every keystroke as results re-render. The user navigates + down to the grid manually. */} diff --git a/components/search/TVSearchPage.tsx b/components/search/TVSearchPage.tsx index ab928d845..580e8a002 100644 --- a/components/search/TVSearchPage.tsx +++ b/components/search/TVSearchPage.tsx @@ -235,10 +235,13 @@ export const TVSearchPage: React.FC = ({ module). It renders the native search bar + grid keyboard and forwards typed text into the existing query pipeline via setSearch; our own results grid renders below. */} + {/* No horizontal margin here: the native tvOS search bar centers itself + and renders a trailing "Hold to Dictate in " hint. Extra + margins squeeze the bar's width and clip that trailing hint, so let + the native view span the full width and own its own insets. */} @@ -280,13 +283,17 @@ export const TVSearchPage: React.FC = ({ {/* Library Search Results */} {isLibraryMode && !loading && ( - {sections.map((section, index) => ( + {sections.map((section) => ( = ({ removeClippedSubviews={false} getItemLayout={getItemLayout} style={{ overflow: "visible" }} - contentInset={{ - left: edgePadding, - right: edgePadding, - }} - contentOffset={{ x: -edgePadding, y: 0 }} + // Edge padding via contentContainerStyle, NOT contentInset+contentOffset. + // contentOffset only applies on initial mount; since this FlatList is + // reused across searches (stable key), a second search left the inset + // without the offset and the grid snapped flush to the left edge. contentContainerStyle={{ + paddingHorizontal: edgePadding, paddingVertical: SCALE_PADDING, }} />