diff options
Diffstat (limited to 'src/view/screens/Search/Search.tsx')
-rw-r--r-- | src/view/screens/Search/Search.tsx | 116 |
1 files changed, 71 insertions, 45 deletions
diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx index 142726701..c0f4cf195 100644 --- a/src/view/screens/Search/Search.tsx +++ b/src/view/screens/Search/Search.tsx @@ -1,58 +1,60 @@ import React from 'react' import { - View, - StyleSheet, ActivityIndicator, - TextInput, - Pressable, Platform, + Pressable, + StyleSheet, + TextInput, + View, } from 'react-native' -import {ScrollView, CenteredView} from '#/view/com/util/Views' -import {List} from '#/view/com/util/List' import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' import { FontAwesomeIcon, FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' -import {useFocusEffect} from '@react-navigation/native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import AsyncStorage from '@react-native-async-storage/async-storage' +import {useFocusEffect, useNavigation} from '@react-navigation/native' +import {useAnalytics} from '#/lib/analytics/analytics' +import {HITSLOP_10} from '#/lib/constants' +import {usePalette} from '#/lib/hooks/usePalette' +import {MagnifyingGlassIcon} from '#/lib/icons' +import {NavigationProp} from '#/lib/routes/types' +import {augmentSearchQuery} from '#/lib/strings/helpers' +import {s} from '#/lib/styles' import {logger} from '#/logger' +import {isNative, isWeb} from '#/platform/detection' +import {listenSoftReset} from '#/state/events' +import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete' +import {useActorSearch} from '#/state/queries/actor-search' +import {useModerationOpts} from '#/state/queries/preferences' +import {useSearchPostsQuery} from '#/state/queries/search-posts' +import {useGetSuggestedFollowersByActor} from '#/state/queries/suggested-follows' +import {useSession} from '#/state/session' +import {useSetDrawerOpen} from '#/state/shell' +import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell' +import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import { NativeStackScreenProps, SearchTabNavigatorParams, } from 'lib/routes/types' -import {Text} from '#/view/com/util/text/Text' -import {ProfileCardFeedLoadingPlaceholder} from 'view/com/util/LoadingPlaceholder' -import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard' -import {Post} from '#/view/com/post/Post' +import {useTheme} from 'lib/ThemeContext' import {Pager} from '#/view/com/pager/Pager' import {TabBar} from '#/view/com/pager/TabBar' -import {HITSLOP_10} from '#/lib/constants' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {usePalette} from '#/lib/hooks/usePalette' -import {useTheme} from 'lib/ThemeContext' -import {useSession} from '#/state/session' -import {useGetSuggestedFollowersByActor} from '#/state/queries/suggested-follows' -import {useSearchPostsQuery} from '#/state/queries/search-posts' -import {useActorSearch} from '#/state/queries/actor-search' -import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete' -import {useSetDrawerOpen} from '#/state/shell' -import {useAnalytics} from '#/lib/analytics/analytics' -import {MagnifyingGlassIcon} from '#/lib/icons' -import {useModerationOpts} from '#/state/queries/preferences' +import {Post} from '#/view/com/post/Post' +import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard' +import {List} from '#/view/com/util/List' +import {Text} from '#/view/com/util/text/Text' +import {CenteredView, ScrollView} from '#/view/com/util/Views' import { MATCH_HANDLE, SearchLinkCard, SearchProfileCard, } from '#/view/shell/desktop/Search' -import {useSetMinimalShellMode, useSetDrawerSwipeDisabled} from '#/state/shell' -import {isNative, isWeb} from '#/platform/detection' -import {listenSoftReset} from '#/state/events' -import {s} from '#/lib/styles' -import AsyncStorage from '@react-native-async-storage/async-storage' -import {augmentSearchQuery} from '#/lib/strings/helpers' +import {ProfileCardFeedLoadingPlaceholder} from 'view/com/util/LoadingPlaceholder' +import {atoms as a} from '#/alf' function Loader() { const pal = usePalette('default') @@ -140,6 +142,7 @@ function SearchScreenSuggestedFollows() { friends.slice(0, 4).map(friend => getSuggestedFollowsByActor(friend.did).then(foafsRes => { for (const user of foafsRes.suggestions) { + if (user.associated?.labeler) continue friendsOfFriends.set(user.did, user) } }), @@ -448,6 +451,7 @@ export function SearchScreenInner({ export function SearchScreen( props: NativeStackScreenProps<SearchTabNavigatorParams, 'Search'>, ) { + const navigation = useNavigation<NavigationProp>() const theme = useTheme() const textInput = React.useRef<TextInput>(null) const {_} = useLingui() @@ -472,6 +476,27 @@ export function SearchScreen( React.useState(false) const [searchHistory, setSearchHistory] = React.useState<string[]>([]) + /** + * The Search screen's `q` param + */ + const queryParam = props.route?.params?.q + + /** + * If `true`, this means we received new instructions from the router. This + * is handled in a effect, and used to update the value of `query` locally + * within this screen. + */ + const routeParamsMismatch = queryParam && queryParam !== query + + React.useEffect(() => { + if (queryParam && routeParamsMismatch) { + // reset immediately and let local state take over + navigation.setParams({q: ''}) + // update query for next search + setQuery(queryParam) + } + }, [queryParam, routeParamsMismatch, navigation]) + React.useEffect(() => { const loadSearchHistory = async () => { try { @@ -749,19 +774,27 @@ export function SearchScreen( {searchHistory.length > 0 && ( <View style={styles.searchHistoryContent}> <Text style={[pal.text, styles.searchHistoryTitle]}> - Recent Searches + <Trans>Recent Searches</Trans> </Text> {searchHistory.map((historyItem, index) => ( - <View key={index} style={styles.historyItemContainer}> + <View + key={index} + style={[ + a.flex_row, + a.mt_md, + a.justify_center, + a.justify_between, + ]}> <Pressable accessibilityRole="button" onPress={() => handleHistoryItemClick(historyItem)} - style={styles.historyItem}> + style={[a.flex_1, a.py_sm]}> <Text style={pal.text}>{historyItem}</Text> </Pressable> <Pressable accessibilityRole="button" - onPress={() => handleRemoveHistoryItem(historyItem)}> + onPress={() => handleRemoveHistoryItem(historyItem)} + style={[a.px_md, a.py_xs, a.justify_center]}> <FontAwesomeIcon icon="xmark" size={16} @@ -774,6 +807,8 @@ export function SearchScreen( )} </View> </CenteredView> + ) : routeParamsMismatch ? ( + <ActivityIndicator /> ) : ( <SearchScreenInner query={query} /> )} @@ -846,13 +881,4 @@ const styles = StyleSheet.create({ searchHistoryTitle: { fontWeight: 'bold', }, - historyItem: { - paddingVertical: 8, - }, - historyItemContainer: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - paddingVertical: 8, - }, }) |