diff options
author | Eric Bailey <git@esb.lol> | 2023-11-15 17:55:28 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-15 15:55:28 -0800 |
commit | 22b76423a0a0e5cfb40bb00c22dec628f5a5a4c0 (patch) | |
tree | 6aa44409fa109d17f9e9f97b6f12aa51a6507ffb /src/view/shell/desktop/Search.tsx | |
parent | d5ea31920caa2eade6015ad59122f06a8b280ab9 (diff) | |
download | voidsky-22b76423a0a0e5cfb40bb00c22dec628f5a5a4c0.tar.zst |
Search page (#1912)
* Desktop web work * Mobile search * Dedupe suggestions * Clean up and reorg * Cleanup * Cleanup * Use Pager * Delete unused code * Fix conflicts * Remove search ui model * Soft reset * Fix scrollable results, remove observer * Use correct ScrollView * Clean up layout --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Diffstat (limited to 'src/view/shell/desktop/Search.tsx')
-rw-r--r-- | src/view/shell/desktop/Search.tsx | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/src/view/shell/desktop/Search.tsx b/src/view/shell/desktop/Search.tsx index d1598c3d3..831eda7ca 100644 --- a/src/view/shell/desktop/Search.tsx +++ b/src/view/shell/desktop/Search.tsx @@ -5,6 +5,7 @@ import { View, StyleSheet, TouchableOpacity, + ActivityIndicator, } from 'react-native' import {useNavigation, StackActions} from '@react-navigation/native' import { @@ -12,7 +13,6 @@ import { moderateProfile, ProfileModeration, } from '@atproto/api' -import {observer} from 'mobx-react-lite' import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -84,14 +84,15 @@ export function SearchResultCard({ ) } -export const DesktopSearch = observer(function DesktopSearch() { +export function DesktopSearch() { const {_} = useLingui() const pal = usePalette('default') const navigation = useNavigation<NavigationProp>() const searchDebounceTimeout = React.useRef<NodeJS.Timeout | undefined>( undefined, ) - const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false) + const [isActive, setIsActive] = React.useState<boolean>(false) + const [isFetching, setIsFetching] = React.useState<boolean>(false) const [query, setQuery] = React.useState<string>('') const [searchResults, setSearchResults] = React.useState< AppBskyActorDefs.ProfileViewBasic[] @@ -104,7 +105,10 @@ export const DesktopSearch = observer(function DesktopSearch() { async (text: string) => { setQuery(text) - if (text.length > 0 && isInputFocused) { + if (text.length > 0) { + setIsFetching(true) + setIsActive(true) + if (searchDebounceTimeout.current) clearTimeout(searchDebounceTimeout.current) @@ -113,24 +117,34 @@ export const DesktopSearch = observer(function DesktopSearch() { if (results) { setSearchResults(results) + setIsFetching(false) } }, 300) } else { if (searchDebounceTimeout.current) clearTimeout(searchDebounceTimeout.current) setSearchResults([]) + setIsFetching(false) + setIsActive(false) } }, - [setQuery, isInputFocused, search, setSearchResults], + [setQuery, search, setSearchResults], ) const onPressCancelSearch = React.useCallback(() => { - onChangeText('') - }, [onChangeText]) - + setQuery('') + setIsActive(false) + if (searchDebounceTimeout.current) + clearTimeout(searchDebounceTimeout.current) + }, [setQuery]) const onSubmit = React.useCallback(() => { + setIsActive(false) + if (!query.length) return + setSearchResults([]) + if (searchDebounceTimeout.current) + clearTimeout(searchDebounceTimeout.current) navigation.dispatch(StackActions.push('Search', {q: query})) - }, [query, navigation]) + }, [query, navigation, setSearchResults]) return ( <View style={[styles.container, pal.view]}> @@ -149,8 +163,6 @@ export const DesktopSearch = observer(function DesktopSearch() { returnKeyType="search" value={query} style={[pal.textLight, styles.input]} - onFocus={() => setIsInputFocused(true)} - onBlur={() => setIsInputFocused(false)} onChangeText={onChangeText} onSubmitEditing={onSubmit} accessibilityRole="search" @@ -174,29 +186,37 @@ export const DesktopSearch = observer(function DesktopSearch() { </View> </View> - {query !== '' && ( + {query !== '' && isActive && moderationOpts && ( <View style={[pal.view, pal.borderDark, styles.resultsContainer]}> - {searchResults.length && moderationOpts ? ( - searchResults.map((item, i) => ( - <SearchResultCard - key={item.did} - profile={item} - moderation={moderateProfile(item, moderationOpts)} - style={i === 0 ? {borderTopWidth: 0} : {}} - /> - )) - ) : ( - <View> - <Text style={[pal.textLight, styles.noResults]}> - <Trans>No results found for {query}</Trans> - </Text> + {isFetching ? ( + <View style={{padding: 8}}> + <ActivityIndicator /> </View> + ) : ( + <> + {searchResults.length ? ( + searchResults.map((item, i) => ( + <SearchResultCard + key={item.did} + profile={item} + moderation={moderateProfile(item, moderationOpts)} + style={i === 0 ? {borderTopWidth: 0} : {}} + /> + )) + ) : ( + <View> + <Text style={[pal.textLight, styles.noResults]}> + <Trans>No results found for {query}</Trans> + </Text> + </View> + )} + </> )} </View> )} </View> ) -}) +} const styles = StyleSheet.create({ container: { |