diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/state/models/discovery/feeds.ts | 19 | ||||
-rw-r--r-- | src/view/com/auth/create/Step1.tsx | 2 | ||||
-rw-r--r-- | src/view/com/search/HeaderWithInput.tsx | 24 | ||||
-rw-r--r-- | src/view/screens/DiscoverFeeds.tsx | 43 |
4 files changed, 75 insertions, 13 deletions
diff --git a/src/state/models/discovery/feeds.ts b/src/state/models/discovery/feeds.ts index c484f7328..fa4054ff0 100644 --- a/src/state/models/discovery/feeds.ts +++ b/src/state/models/discovery/feeds.ts @@ -82,6 +82,21 @@ export class FeedsDiscoveryModel { this._xIdle() }) + search = async (query: string) => { + this._xLoading(false) + try { + const results = + await this.rootStore.agent.app.bsky.unspecced.getPopularFeedGenerators({ + limit: DEFAULT_LIMIT, + query: query, + }) + this._replaceAll(results) + } catch (e: any) { + this._xIdle(e) + } + this._xIdle() + } + clear() { this.isLoading = false this.isRefreshing = false @@ -93,9 +108,9 @@ export class FeedsDiscoveryModel { // state transitions // = - _xLoading() { + _xLoading(isRefreshing = true) { this.isLoading = true - this.isRefreshing = true + this.isRefreshing = isRefreshing this.error = '' } diff --git a/src/view/com/auth/create/Step1.tsx b/src/view/com/auth/create/Step1.tsx index 5038c8819..5d3dec430 100644 --- a/src/view/com/auth/create/Step1.tsx +++ b/src/view/com/auth/create/Step1.tsx @@ -37,7 +37,7 @@ export const Step1 = observer(({model}: {model: CreateAccountModel}) => { }, [setIsDefaultSelected, model]) const fetchServiceDescription = React.useMemo( - () => debounce(() => model.fetchServiceDescription(), 1e3), + () => debounce(() => model.fetchServiceDescription(), 1e3), // debouce for 1 second (1e3 = 1000ms) [model], ) diff --git a/src/view/com/search/HeaderWithInput.tsx b/src/view/com/search/HeaderWithInput.tsx index 0d65d98fd..2ec079dde 100644 --- a/src/view/com/search/HeaderWithInput.tsx +++ b/src/view/com/search/HeaderWithInput.tsx @@ -21,6 +21,7 @@ interface Props { onPressClearQuery: () => void onPressCancelSearch: () => void onSubmitQuery: () => void + showMenu?: boolean } export function HeaderWithInput({ isInputFocused, @@ -30,6 +31,7 @@ export function HeaderWithInput({ onPressClearQuery, onPressCancelSearch, onSubmitQuery, + showMenu = true, }: Props) { const store = useStores() const theme = useTheme() @@ -49,16 +51,18 @@ export function HeaderWithInput({ return ( <View style={[pal.view, pal.border, styles.header]}> - <TouchableOpacity - testID="viewHeaderBackOrMenuBtn" - onPress={onPressMenu} - hitSlop={MENU_HITSLOP} - style={styles.headerMenuBtn} - accessibilityRole="button" - accessibilityLabel="Menu" - accessibilityHint="Access navigation links and settings"> - <FontAwesomeIcon icon="bars" size={18} color={pal.colors.textLight} /> - </TouchableOpacity> + {showMenu ? ( + <TouchableOpacity + testID="viewHeaderBackOrMenuBtn" + onPress={onPressMenu} + hitSlop={MENU_HITSLOP} + style={styles.headerMenuBtn} + accessibilityRole="button" + accessibilityLabel="Menu" + accessibilityHint="Access navigation links and settings"> + <FontAwesomeIcon icon="bars" size={18} color={pal.colors.textLight} /> + </TouchableOpacity> + ) : null} <View style={[ {backgroundColor: pal.colors.backgroundLight}, diff --git a/src/view/screens/DiscoverFeeds.tsx b/src/view/screens/DiscoverFeeds.tsx index b6a6744db..e7b685ebc 100644 --- a/src/view/screens/DiscoverFeeds.tsx +++ b/src/view/screens/DiscoverFeeds.tsx @@ -14,6 +14,8 @@ import {isDesktopWeb} from 'platform/detection' import {usePalette} from 'lib/hooks/usePalette' import {s} from 'lib/styles' import {CustomFeedModel} from 'state/models/feeds/custom-feed' +import {HeaderWithInput} from 'view/com/search/HeaderWithInput' +import debounce from 'lodash.debounce' type Props = NativeStackScreenProps<CommonNavigatorParams, 'DiscoverFeeds'> export const DiscoverFeedsScreen = withAuthRequired( @@ -22,6 +24,37 @@ export const DiscoverFeedsScreen = withAuthRequired( const pal = usePalette('default') const feeds = React.useMemo(() => new FeedsDiscoveryModel(store), [store]) + // search stuff + const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false) + const [query, setQuery] = React.useState<string>('') + const debouncedSearchFeeds = React.useMemo( + () => debounce(() => feeds.search(query), 200), // debouce for 200 ms + [feeds, query], + ) + const onChangeQuery = React.useCallback( + (text: string) => { + setQuery(text) + if (text.length > 1) { + debouncedSearchFeeds() + } else { + feeds.refresh() + } + }, + [debouncedSearchFeeds, feeds], + ) + const onPressClearQuery = React.useCallback(() => { + setQuery('') + feeds.refresh() + }, [feeds]) + const onPressCancelSearch = React.useCallback(() => { + setIsInputFocused(false) + setQuery('') + feeds.refresh() + }, [feeds]) + const onSubmitQuery = React.useCallback(() => { + feeds.search(query) + }, [feeds, query]) + useFocusEffect( React.useCallback(() => { store.shell.setMinimalShellMode(false) @@ -68,6 +101,16 @@ export const DiscoverFeedsScreen = withAuthRequired( <CenteredView style={[styles.container, pal.view]}> <View style={[isDesktopWeb && styles.containerDesktop, pal.border]}> <ViewHeader title="Discover Feeds" showOnDesktop /> + <HeaderWithInput + isInputFocused={isInputFocused} + query={query} + setIsInputFocused={setIsInputFocused} + onChangeQuery={onChangeQuery} + onPressClearQuery={onPressClearQuery} + onPressCancelSearch={onPressCancelSearch} + onSubmitQuery={onSubmitQuery} + showMenu={false} + /> </View> <FlatList style={[!isDesktopWeb && s.flex1]} |