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