Bluesky app fork with some witchin' additions 馃挮
at linkat-integration 115 lines 3.6 kB view raw
1import {useState} from 'react' 2import {type ListRenderItemInfo, View} from 'react-native' 3import {KeyboardAwareScrollView} from 'react-native-keyboard-controller' 4import {type AppBskyActorDefs, type ModerationOpts} from '@atproto/api' 5import {Trans} from '@lingui/macro' 6 7import {useA11y} from '#/state/a11y' 8import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete' 9import {useActorSearch} from '#/state/queries/actor-search' 10import {List} from '#/view/com/util/List' 11import {useWizardState} from '#/screens/StarterPack/Wizard/State' 12import {atoms as a, useTheme} from '#/alf' 13import {SearchInput} from '#/components/forms/SearchInput' 14import {Loader} from '#/components/Loader' 15import {ScreenTransition} from '#/components/ScreenTransition' 16import {WizardProfileCard} from '#/components/StarterPack/Wizard/WizardListCard' 17import {Text} from '#/components/Typography' 18import {IS_NATIVE} from '#/env' 19import type * as bsky from '#/types/bsky' 20 21function keyExtractor(item: AppBskyActorDefs.ProfileViewBasic) { 22 return item?.did ?? '' 23} 24 25export function StepProfiles({ 26 moderationOpts, 27}: { 28 moderationOpts: ModerationOpts 29}) { 30 const t = useTheme() 31 const [state, dispatch] = useWizardState() 32 const [query, setQuery] = useState('') 33 const {screenReaderEnabled} = useA11y() 34 35 const { 36 data: topPages, 37 fetchNextPage, 38 isLoading: isLoadingTopPages, 39 } = useActorSearch({ 40 query: encodeURIComponent('*'), 41 }) 42 const topFollowers = topPages?.pages 43 .flatMap(p => p.actors) 44 .filter(p => !p.associated?.labeler) 45 46 const {data: resultsUnfiltered, isFetching: isFetchingResults} = 47 useActorAutocompleteQuery(query, true, 12) 48 const results = resultsUnfiltered?.filter(p => !p.associated?.labeler) 49 50 const isLoading = isLoadingTopPages || isFetchingResults 51 52 const renderItem = ({ 53 item, 54 }: ListRenderItemInfo<bsky.profile.AnyProfileView>) => { 55 return ( 56 <WizardProfileCard 57 profile={item} 58 btnType="checkbox" 59 state={state} 60 dispatch={dispatch} 61 moderationOpts={moderationOpts} 62 /> 63 ) 64 } 65 66 return ( 67 <ScreenTransition 68 style={[a.flex_1]} 69 direction={state.transitionDirection} 70 enabledWeb> 71 <View style={[a.border_b, t.atoms.border_contrast_medium]}> 72 <View style={[a.py_sm, a.px_md, {height: 60}]}> 73 <SearchInput 74 value={query} 75 onChangeText={setQuery} 76 onClearText={() => setQuery('')} 77 /> 78 </View> 79 </View> 80 <List 81 data={query ? results : topFollowers} 82 renderItem={renderItem} 83 keyExtractor={keyExtractor} 84 renderScrollComponent={props => <KeyboardAwareScrollView {...props} />} 85 keyboardShouldPersistTaps="handled" 86 disableFullWindowScroll={true} 87 sideBorders={false} 88 style={[a.flex_1]} 89 onEndReached={ 90 !query && !screenReaderEnabled ? () => fetchNextPage() : undefined 91 } 92 onEndReachedThreshold={IS_NATIVE ? 2 : 0.25} 93 keyboardDismissMode="on-drag" 94 ListEmptyComponent={ 95 <View style={[a.flex_1, a.align_center, a.mt_lg, a.px_lg]}> 96 {isLoading ? ( 97 <Loader size="lg" /> 98 ) : ( 99 <Text 100 style={[ 101 a.font_semi_bold, 102 a.text_lg, 103 a.text_center, 104 a.mt_lg, 105 a.leading_snug, 106 ]}> 107 <Trans>Nobody was found. Try searching for someone else.</Trans> 108 </Text> 109 )} 110 </View> 111 } 112 /> 113 </ScreenTransition> 114 ) 115}