Scroll feed search bar to top of screen on focus (#2602)
* Scroll feed search bar to top on focus * update commentzio/stable
parent
382383ca87
commit
94f39bb3eb
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue