animate search
This commit is contained in:
@@ -12,6 +12,14 @@ import {
|
|||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {ScrollView as RNGHScrollView} from 'react-native-gesture-handler'
|
import {ScrollView as RNGHScrollView} from 'react-native-gesture-handler'
|
||||||
import RNPickerSelect from 'react-native-picker-select'
|
import RNPickerSelect from 'react-native-picker-select'
|
||||||
|
import Animated, {
|
||||||
|
LayoutAnimationConfig,
|
||||||
|
LinearTransition,
|
||||||
|
SlideInLeft,
|
||||||
|
SlideInRight,
|
||||||
|
SlideOutLeft,
|
||||||
|
SlideOutRight,
|
||||||
|
} from 'react-native-reanimated'
|
||||||
import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api'
|
import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api'
|
||||||
import {
|
import {
|
||||||
FontAwesomeIcon,
|
FontAwesomeIcon,
|
||||||
@@ -63,6 +71,7 @@ import {atoms as a, useBreakpoints, useTheme as useThemeNew, web} from '#/alf'
|
|||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import * as FeedCard from '#/components/FeedCard'
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
import {SearchInput} from '#/components/forms/SearchInput'
|
import {SearchInput} from '#/components/forms/SearchInput'
|
||||||
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron'
|
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron'
|
||||||
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
|
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
|
||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
@@ -844,7 +853,10 @@ export function SearchScreen(
|
|||||||
[selectedProfiles],
|
[selectedProfiles],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const {state: isFocused, onIn: onFocus, onOut: onBlur} = useInteractionState()
|
||||||
|
|
||||||
const onSearchInputFocus = React.useCallback(() => {
|
const onSearchInputFocus = React.useCallback(() => {
|
||||||
|
onFocus()
|
||||||
if (isWeb) {
|
if (isWeb) {
|
||||||
// Prevent a jump on iPad by ensuring that
|
// Prevent a jump on iPad by ensuring that
|
||||||
// the initial focused render has no result list.
|
// the initial focused render has no result list.
|
||||||
@@ -854,7 +866,7 @@ export function SearchScreen(
|
|||||||
} else {
|
} else {
|
||||||
setShowAutocomplete(true)
|
setShowAutocomplete(true)
|
||||||
}
|
}
|
||||||
}, [setShowAutocomplete])
|
}, [setShowAutocomplete, onFocus])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout.Screen testID="searchScreen">
|
<Layout.Screen testID="searchScreen">
|
||||||
@@ -872,46 +884,58 @@ export function SearchScreen(
|
|||||||
}),
|
}),
|
||||||
]}
|
]}
|
||||||
sideBorders={gtMobile}>
|
sideBorders={gtMobile}>
|
||||||
<View style={[a.flex_row, a.gap_sm]}>
|
<LayoutAnimationConfig skipEntering skipExiting>
|
||||||
{!gtMobile && (
|
<View style={[a.flex_row, a.gap_sm]}>
|
||||||
<Button
|
{!gtMobile && !isFocused && (
|
||||||
testID="viewHeaderBackOrMenuBtn"
|
<Animated.View
|
||||||
onPress={onPressMenu}
|
layout={LinearTransition}
|
||||||
hitSlop={HITSLOP_10}
|
entering={SlideInLeft}
|
||||||
label={_(msg`Menu`)}
|
exiting={SlideOutLeft}>
|
||||||
accessibilityHint={_(msg`Access navigation links and settings`)}
|
<Button
|
||||||
size="large"
|
testID="viewHeaderBackOrMenuBtn"
|
||||||
variant="solid"
|
onPress={onPressMenu}
|
||||||
color="secondary"
|
hitSlop={HITSLOP_10}
|
||||||
shape="square">
|
label={_(msg`Menu`)}
|
||||||
<ButtonIcon icon={Menu} size="lg" />
|
accessibilityHint={_(
|
||||||
</Button>
|
msg`Access navigation links and settings`,
|
||||||
)}
|
)}
|
||||||
<View style={[a.flex_1]}>
|
size="large"
|
||||||
<SearchInput
|
variant="solid"
|
||||||
ref={textInput}
|
color="secondary"
|
||||||
value={searchText}
|
shape="square">
|
||||||
onFocus={onSearchInputFocus}
|
<ButtonIcon icon={Menu} size="lg" />
|
||||||
onChangeText={onChangeText}
|
</Button>
|
||||||
onClearText={onPressClearQuery}
|
</Animated.View>
|
||||||
onSubmitEditing={onSubmit}
|
)}
|
||||||
/>
|
<Animated.View style={[a.flex_1]} layout={LinearTransition}>
|
||||||
|
<SearchInput
|
||||||
|
ref={textInput}
|
||||||
|
value={searchText}
|
||||||
|
onFocus={onSearchInputFocus}
|
||||||
|
onBlur={onBlur}
|
||||||
|
onChangeText={onChangeText}
|
||||||
|
onClearText={onPressClearQuery}
|
||||||
|
onSubmitEditing={onSubmit}
|
||||||
|
/>
|
||||||
|
</Animated.View>
|
||||||
|
{showAutocomplete && (
|
||||||
|
<Animated.View entering={SlideInRight} exiting={SlideOutRight}>
|
||||||
|
<Button
|
||||||
|
label={_(msg`Cancel search`)}
|
||||||
|
size="large"
|
||||||
|
variant="ghost"
|
||||||
|
color="secondary"
|
||||||
|
style={[a.px_sm]}
|
||||||
|
onPress={onPressCancelSearch}
|
||||||
|
hitSlop={HITSLOP_10}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Cancel</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Button>
|
||||||
|
</Animated.View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
{showAutocomplete && (
|
</LayoutAnimationConfig>
|
||||||
<Button
|
|
||||||
label={_(msg`Cancel search`)}
|
|
||||||
size="large"
|
|
||||||
variant="ghost"
|
|
||||||
color="secondary"
|
|
||||||
style={[a.px_sm]}
|
|
||||||
onPress={onPressCancelSearch}
|
|
||||||
hitSlop={HITSLOP_10}>
|
|
||||||
<ButtonText>
|
|
||||||
<Trans>Cancel</Trans>
|
|
||||||
</ButtonText>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{showFilters && (
|
{showFilters && (
|
||||||
<View
|
<View
|
||||||
|
|||||||
Reference in New Issue
Block a user