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