Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
119
fork

Configure Feed

Select the types of activity you want to include in your feed.

at a876aae44ea07494ebea9727350aa060b81f317b 109 lines 2.5 kB view raw
1import {useState} from 'react' 2import {View} from 'react-native' 3import {useSift} from '@bsky.app/sift' 4import {StackActions, useNavigation} from '@react-navigation/native' 5 6import {type NavigationProp} from '#/lib/routes/types' 7import {atoms as a} from '#/alf' 8import { 9 Autocomplete as AutocompleteBase, 10 type AutocompleteItem, 11 useAutocomplete, 12} from '#/components/Autocomplete' 13import {SearchInput} from '#/components/forms/SearchInput' 14 15export function DesktopSearch() { 16 const navigation = useNavigation<NavigationProp>() 17 const [active, setActive] = useState(false) 18 const [query, setQuery] = useState<string>('') 19 const showResults = active && !!query.length 20 21 const sift = useSift({ 22 offset: a.p_sm.padding, 23 placement: 'bottom', 24 }) 25 26 const onFocus = () => { 27 if (query.length) setActive(true) 28 } 29 30 const onChangeText = (text: string) => { 31 setQuery(text) 32 if (!active) { 33 setActive(true) 34 } 35 } 36 37 const onClearText = () => { 38 setQuery('') 39 setActive(false) 40 } 41 42 const onSubmit = () => { 43 if (!query.length) return 44 onClearText() 45 sift.elements.input.blur() 46 navigation.dispatch(StackActions.push('Search', {q: query})) 47 } 48 49 const onSelect = (item: AutocompleteItem) => { 50 if (item.type === 'profile') { 51 onClearText() 52 sift.elements.input.blur() 53 navigation.navigate('Profile', {name: item.profile.handle}) 54 } else if (item.type === 'search') { 55 onClearText() 56 sift.elements.input.blur() 57 navigation.navigate('Search', {q: item.value}) 58 } 59 } 60 61 return ( 62 <View collapsable={false} ref={sift.refs.setAnchor}> 63 <SearchInput 64 hotkey 65 value={query} 66 onFocus={onFocus} 67 onChangeText={onChangeText} 68 onClearText={onClearText} 69 onSubmitEditing={onSubmit} 70 {...sift.targetProps} 71 /> 72 {showResults && ( 73 <Inner 74 query={query} 75 sift={sift} 76 onSelect={onSelect} 77 onDismiss={() => setActive(false)} 78 /> 79 )} 80 </View> 81 ) 82} 83 84function Inner({ 85 query, 86 sift, 87 onSelect, 88 onDismiss, 89}: { 90 query: string 91 sift: ReturnType<typeof useSift> 92 onSelect: (item: AutocompleteItem) => void 93 onDismiss: () => void 94}) { 95 const {items} = useAutocomplete({ 96 type: 'profile', 97 query, 98 showSearchFallback: true, 99 }) 100 101 return items && items.length ? ( 102 <AutocompleteBase 103 sift={sift} 104 data={items} 105 onSelect={onSelect} 106 onDismiss={onDismiss} 107 /> 108 ) : null 109}