diff options
author | Hailey <me@haileyok.com> | 2024-02-12 13:47:48 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-12 13:47:48 -0800 |
commit | b936da1c0fa7b8a49e84a1b36ae064db9f8c0e47 (patch) | |
tree | de9fba4a47fb505a5dfb754bc1dd469701cfcece /src | |
parent | ba7463cadf15bd5420e1a8cc46952bde2c81cad9 (diff) | |
download | voidsky-b936da1c0fa7b8a49e84a1b36ae064db9f8c0e47.tar.zst |
Add search button to header on feeds screen (#2848)
* add search bar to header * add button on web
Diffstat (limited to 'src')
-rw-r--r-- | src/view/com/util/forms/SearchInput.tsx | 125 | ||||
-rw-r--r-- | src/view/screens/Feeds.tsx | 73 |
2 files changed, 126 insertions, 72 deletions
diff --git a/src/view/com/util/forms/SearchInput.tsx b/src/view/com/util/forms/SearchInput.tsx index a78d23c9b..5a21d8fdd 100644 --- a/src/view/com/util/forms/SearchInput.tsx +++ b/src/view/com/util/forms/SearchInput.tsx @@ -26,64 +26,79 @@ interface Props { onSubmitQuery: () => void style?: StyleProp<ViewStyle> } -export function SearchInput({ - query, - setIsInputFocused, - onChangeQuery, - onPressCancelSearch, - onSubmitQuery, - style, -}: Props) { - const theme = useTheme() - const pal = usePalette('default') - const {_} = useLingui() - const textInput = React.useRef<TextInput>(null) - const onPressCancelSearchInner = React.useCallback(() => { - onPressCancelSearch() - textInput.current?.blur() - }, [onPressCancelSearch, textInput]) +export interface SearchInputRef { + focus?: () => void +} + +export const SearchInput = React.forwardRef<SearchInputRef, Props>( + function SearchInput( + { + query, + setIsInputFocused, + onChangeQuery, + onPressCancelSearch, + onSubmitQuery, + style, + }, + ref, + ) { + const theme = useTheme() + const pal = usePalette('default') + const {_} = useLingui() + const textInput = React.useRef<TextInput>(null) + + const onPressCancelSearchInner = React.useCallback(() => { + onPressCancelSearch() + textInput.current?.blur() + }, [onPressCancelSearch, textInput]) - return ( - <View style={[pal.viewLight, styles.container, style]}> - <MagnifyingGlassIcon style={[pal.icon, styles.icon]} size={21} /> - <TextInput - testID="searchTextInput" - ref={textInput} - placeholder={_(msg`Search`)} - placeholderTextColor={pal.colors.textLight} - selectTextOnFocus - returnKeyType="search" - value={query} - style={[pal.text, styles.input]} - keyboardAppearance={theme.colorScheme} - onFocus={() => setIsInputFocused?.(true)} - onBlur={() => setIsInputFocused?.(false)} - onChangeText={onChangeQuery} - onSubmitEditing={onSubmitQuery} - accessibilityRole="search" - accessibilityLabel={_(msg`Search`)} - accessibilityHint="" - autoCorrect={false} - autoCapitalize="none" - /> - {query ? ( - <TouchableOpacity - onPress={onPressCancelSearchInner} - accessibilityRole="button" - accessibilityLabel={_(msg`Clear search query`)} + React.useImperativeHandle(ref, () => ({ + focus: () => textInput.current?.focus(), + blur: () => textInput.current?.blur(), + })) + + return ( + <View style={[pal.viewLight, styles.container, style]}> + <MagnifyingGlassIcon style={[pal.icon, styles.icon]} size={21} /> + <TextInput + testID="searchTextInput" + ref={textInput} + placeholder={_(msg`Search`)} + placeholderTextColor={pal.colors.textLight} + selectTextOnFocus + returnKeyType="search" + value={query} + style={[pal.text, styles.input]} + keyboardAppearance={theme.colorScheme} + onFocus={() => setIsInputFocused?.(true)} + onBlur={() => setIsInputFocused?.(false)} + onChangeText={onChangeQuery} + onSubmitEditing={onSubmitQuery} + accessibilityRole="search" + accessibilityLabel={_(msg`Search`)} accessibilityHint="" - hitSlop={HITSLOP_10}> - <FontAwesomeIcon - icon="xmark" - size={16} - style={pal.textLight as FontAwesomeIconStyle} - /> - </TouchableOpacity> - ) : undefined} - </View> - ) -} + autoCorrect={false} + autoCapitalize="none" + /> + {query ? ( + <TouchableOpacity + onPress={onPressCancelSearchInner} + accessibilityRole="button" + accessibilityLabel={_(msg`Clear search query`)} + accessibilityHint="" + hitSlop={HITSLOP_10}> + <FontAwesomeIcon + icon="xmark" + size={16} + style={pal.textLight as FontAwesomeIconStyle} + /> + </TouchableOpacity> + ) : undefined} + </View> + ) + }, +) const styles = StyleSheet.create({ container: { diff --git a/src/view/screens/Feeds.tsx b/src/view/screens/Feeds.tsx index 6651084bd..7216fd109 100644 --- a/src/view/screens/Feeds.tsx +++ b/src/view/screens/Feeds.tsx @@ -1,5 +1,11 @@ import React from 'react' -import {ActivityIndicator, StyleSheet, View, type FlatList} from 'react-native' +import { + ActivityIndicator, + StyleSheet, + View, + type FlatList, + Pressable, +} from 'react-native' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome' import {ViewHeader} from 'view/com/util/ViewHeader' @@ -8,9 +14,9 @@ import {Link} from 'view/com/util/Link' import {NativeStackScreenProps, FeedsTabNavigatorParams} from 'lib/routes/types' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {ComposeIcon2, CogIcon} from 'lib/icons' +import {ComposeIcon2, CogIcon, MagnifyingGlassIcon2} from 'lib/icons' import {s} from 'lib/styles' -import {SearchInput} from 'view/com/util/forms/SearchInput' +import {SearchInput, SearchInputRef} from 'view/com/util/forms/SearchInput' import {UserAvatar} from 'view/com/util/UserAvatar' import { LoadingPlaceholder, @@ -36,6 +42,7 @@ import {cleanError} from 'lib/strings/errors' import {useComposerControls} from '#/state/shell/composer' import {useSession} from '#/state/session' import {isNative} from '#/platform/detection' +import {HITSLOP_10} from 'lib/constants' type Props = NativeStackScreenProps<FeedsTabNavigatorParams, 'Feeds'> @@ -121,6 +128,7 @@ export function FeedsScreen(_props: Props) { } = useSearchPopularFeedsMutation() const {hasSession} = useSession() const listRef = React.useRef<FlatList>(null) + const searchInputRef = React.useRef<SearchInputRef>(null) /** * A search query is present. We may not have search results yet. @@ -330,14 +338,26 @@ export function FeedsScreen(_props: Props) { const renderHeaderBtn = React.useCallback(() => { return ( - <Link - href="/settings/saved-feeds" - hitSlop={10} - accessibilityRole="button" - accessibilityLabel={_(msg`Edit Saved Feeds`)} - accessibilityHint={_(msg`Opens screen to edit Saved Feeds`)}> - <CogIcon size={22} strokeWidth={2} style={pal.textLight} /> - </Link> + <View style={styles.headerBtnGroup}> + <Pressable + accessibilityRole="button" + hitSlop={HITSLOP_10} + onPress={searchInputRef.current?.focus}> + <MagnifyingGlassIcon2 + size={22} + strokeWidth={2} + style={pal.textLight} + /> + </Pressable> + <Link + href="/settings/saved-feeds" + hitSlop={10} + accessibilityRole="button" + accessibilityLabel={_(msg`Edit Saved Feeds`)} + accessibilityHint={_(msg`Opens screen to edit Saved Feeds`)}> + <CogIcon size={22} strokeWidth={2} style={pal.textLight} /> + </Link> + </View> ) }, [pal, _]) @@ -398,12 +418,24 @@ export function FeedsScreen(_props: Props) { <Text type="title-lg" style={[pal.text, s.bold]}> <Trans>My Feeds</Trans> </Text> - <Link - href="/settings/saved-feeds" - accessibilityLabel={_(msg`Edit My Feeds`)} - accessibilityHint=""> - <CogIcon strokeWidth={1.5} style={pal.icon} size={28} /> - </Link> + <View style={styles.headerBtnGroup}> + <Pressable + accessibilityRole="button" + hitSlop={HITSLOP_10} + onPress={searchInputRef.current?.focus}> + <MagnifyingGlassIcon2 + size={22} + strokeWidth={2} + style={pal.icon} + /> + </Pressable> + <Link + href="/settings/saved-feeds" + accessibilityLabel={_(msg`Edit My Feeds`)} + accessibilityHint=""> + <CogIcon strokeWidth={1.5} style={pal.icon} size={28} /> + </Link> + </View> </View> ) } @@ -443,6 +475,7 @@ export function FeedsScreen(_props: Props) { {!isMobile && ( <SearchInput + ref={searchInputRef} query={query} onChangeQuery={onChangeQuery} onPressCancelSearch={onPressCancelSearch} @@ -456,6 +489,7 @@ export function FeedsScreen(_props: Props) { {isMobile && ( <View style={{paddingHorizontal: 8, paddingBottom: 10}}> <SearchInput + ref={searchInputRef} query={query} onChangeQuery={onChangeQuery} onPressCancelSearch={onPressCancelSearch} @@ -663,4 +697,9 @@ const styles = StyleSheet.create({ paddingHorizontal: 4, paddingVertical: 2, }, + headerBtnGroup: { + flexDirection: 'row', + gap: 15, + alignItems: 'center', + }, }) |