mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

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

at static-click 128 lines 3.4 kB view raw
1import React from 'react' 2import {AppBskyActorDefs as ActorDefs} from '@atproto/api' 3import {msg} from '@lingui/macro' 4import {useLingui} from '@lingui/react' 5 6import {cleanError} from '#/lib/strings/errors' 7import {logger} from '#/logger' 8import {useProfileFollowersQuery} from '#/state/queries/profile-followers' 9import {useResolveDidQuery} from '#/state/queries/resolve-uri' 10import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' 11import {isWeb} from 'platform/detection' 12import {useSession} from 'state/session' 13import {ListFooter, ListMaybePlaceholder} from '#/components/Lists' 14import {List} from '../util/List' 15import {ProfileCardWithFollowBtn} from './ProfileCard' 16 17function renderItem({ 18 item, 19 index, 20}: { 21 item: ActorDefs.ProfileViewBasic 22 index: number 23}) { 24 return ( 25 <ProfileCardWithFollowBtn 26 key={item.did} 27 profile={item} 28 noBorder={index === 0 && !isWeb} 29 /> 30 ) 31} 32 33function keyExtractor(item: ActorDefs.ProfileViewBasic) { 34 return item.did 35} 36 37export function ProfileFollowers({name}: {name: string}) { 38 const {_} = useLingui() 39 const initialNumToRender = useInitialNumToRender() 40 const {currentAccount} = useSession() 41 42 const [isPTRing, setIsPTRing] = React.useState(false) 43 const { 44 data: resolvedDid, 45 isLoading: isDidLoading, 46 error: resolveError, 47 } = useResolveDidQuery(name) 48 const { 49 data, 50 isLoading: isFollowersLoading, 51 isFetchingNextPage, 52 hasNextPage, 53 fetchNextPage, 54 error, 55 refetch, 56 } = useProfileFollowersQuery(resolvedDid) 57 58 const isError = !!resolveError || !!error 59 const isMe = resolvedDid === currentAccount?.did 60 61 const followers = React.useMemo(() => { 62 if (data?.pages) { 63 return data.pages.flatMap(page => page.followers) 64 } 65 return [] 66 }, [data]) 67 68 const onRefresh = React.useCallback(async () => { 69 setIsPTRing(true) 70 try { 71 await refetch() 72 } catch (err) { 73 logger.error('Failed to refresh followers', {message: err}) 74 } 75 setIsPTRing(false) 76 }, [refetch, setIsPTRing]) 77 78 const onEndReached = React.useCallback(async () => { 79 if (isFetchingNextPage || !hasNextPage || !!error) return 80 try { 81 await fetchNextPage() 82 } catch (err) { 83 logger.error('Failed to load more followers', {message: err}) 84 } 85 }, [isFetchingNextPage, hasNextPage, error, fetchNextPage]) 86 87 if (followers.length < 1) { 88 return ( 89 <ListMaybePlaceholder 90 isLoading={isDidLoading || isFollowersLoading} 91 isError={isError} 92 emptyType="results" 93 emptyMessage={ 94 isMe 95 ? _(msg`You do not have any followers.`) 96 : _(msg`This user doesn't have any followers.`) 97 } 98 errorMessage={cleanError(resolveError || error)} 99 onRetry={isError ? refetch : undefined} 100 sideBorders={false} 101 /> 102 ) 103 } 104 105 return ( 106 <List 107 data={followers} 108 renderItem={renderItem} 109 keyExtractor={keyExtractor} 110 refreshing={isPTRing} 111 onRefresh={onRefresh} 112 onEndReached={onEndReached} 113 onEndReachedThreshold={4} 114 ListFooterComponent={ 115 <ListFooter 116 isFetchingNextPage={isFetchingNextPage} 117 error={cleanError(error)} 118 onRetry={fetchNextPage} 119 /> 120 } 121 // @ts-ignore our .web version only -prf 122 desktopFixedHeight 123 initialNumToRender={initialNumToRender} 124 windowSize={11} 125 sideBorders={false} 126 /> 127 ) 128}