diff options
author | Paul Frazee <pfrazee@gmail.com> | 2024-01-23 20:33:38 -0800 |
---|---|---|
committer | Paul Frazee <pfrazee@gmail.com> | 2024-01-23 20:33:38 -0800 |
commit | e628556d1f1f364bb6d5a1528a7a816ddd926a1d (patch) | |
tree | 2de08033b9dabda0f67379cf0dacb9cac27e0750 /src | |
parent | e273f4ed210b553b196e31b855637ad107eb4635 (diff) | |
parent | 94f39bb3eb26a6ba2ae7f3eb72d78154006e2fca (diff) | |
download | voidsky-e628556d1f1f364bb6d5a1528a7a816ddd926a1d.tar.zst |
Merge branch 'main' of github.com:bluesky-social/social-app into main
Diffstat (limited to 'src')
-rw-r--r-- | src/view/screens/Feeds.tsx | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/view/screens/Feeds.tsx b/src/view/screens/Feeds.tsx index a913364d4..9b3fd6181 100644 --- a/src/view/screens/Feeds.tsx +++ b/src/view/screens/Feeds.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {ActivityIndicator, StyleSheet, View} from 'react-native' +import {ActivityIndicator, StyleSheet, View, type FlatList} from 'react-native' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome' import {ViewHeader} from 'view/com/util/ViewHeader' @@ -34,6 +34,7 @@ import { import {cleanError} from 'lib/strings/errors' import {useComposerControls} from '#/state/shell/composer' import {useSession} from '#/state/session' +import {isNative} from '#/platform/detection' type Props = NativeStackScreenProps<FeedsTabNavigatorParams, 'Feeds'> @@ -118,6 +119,7 @@ export function FeedsScreen(_props: Props) { error: searchError, } = useSearchPopularFeedsMutation() const {hasSession} = useSession() + const listRef = React.useRef<FlatList>(null) /** * A search query is present. We may not have search results yet. @@ -338,6 +340,35 @@ export function FeedsScreen(_props: Props) { ) }, [pal, _]) + const searchBarIndex = items.findIndex( + item => item.type === 'popularFeedsHeader', + ) + + const onChangeSearchFocus = React.useCallback( + (focus: boolean) => { + if (focus && searchBarIndex > -1) { + if (isNative) { + // scrollToIndex scrolls the exact right amount, so use if available + listRef.current?.scrollToIndex({ + index: searchBarIndex, + animated: true, + }) + } else { + // web implementation only supports scrollToOffset + // thus, we calculate the offset based on the index + // pixel values are estimates, I wasn't able to get it pixel perfect :( + const headerHeight = isMobile ? 43 : 53 + const feedItemHeight = isMobile ? 49 : 58 + listRef.current?.scrollToOffset({ + offset: searchBarIndex * feedItemHeight - headerHeight, + animated: true, + }) + } + } + }, + [searchBarIndex, isMobile], + ) + const renderItem = React.useCallback( ({item}: {item: FlatlistSlice}) => { if (item.type === 'error') { @@ -415,6 +446,7 @@ export function FeedsScreen(_props: Props) { onChangeQuery={onChangeQuery} onPressCancelSearch={onPressCancelSearch} onSubmitQuery={onSubmitQuery} + setIsInputFocused={onChangeSearchFocus} style={{flex: 1, maxWidth: 250}} /> )} @@ -427,6 +459,7 @@ export function FeedsScreen(_props: Props) { onChangeQuery={onChangeQuery} onPressCancelSearch={onPressCancelSearch} onSubmitQuery={onSubmitQuery} + setIsInputFocused={onChangeSearchFocus} /> </View> )} @@ -469,6 +502,7 @@ export function FeedsScreen(_props: Props) { onChangeQuery, onPressCancelSearch, onSubmitQuery, + onChangeSearchFocus, ], ) @@ -486,6 +520,7 @@ export function FeedsScreen(_props: Props) { {preferences ? <View /> : <ActivityIndicator />} <List + ref={listRef} style={[!isTabletOrDesktop && s.flex1, styles.list]} data={items} keyExtractor={item => item.key} |