about summary refs log tree commit diff
path: root/src/view/com/discover/SuggestedFollows.tsx
blob: 1e40956ce778ef2fd1a35f182dbcd10ae60164c3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import React from 'react'
import {ActivityIndicator, StyleSheet, View} from 'react-native'
import {CenteredView, FlatList} from '../util/Views'
import {observer} from 'mobx-react-lite'
import {ErrorScreen} from '../util/error/ErrorScreen'
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
import {useStores} from 'state/index'
import {
  SuggestedActorsViewModel,
  SuggestedActor,
} from 'state/models/suggested-actors-view'
import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'

export const SuggestedFollows = observer(
  ({onNoSuggestions}: {onNoSuggestions?: () => void}) => {
    const pal = usePalette('default')
    const store = useStores()

    const view = React.useMemo<SuggestedActorsViewModel>(
      () => new SuggestedActorsViewModel(store),
      [store],
    )

    React.useEffect(() => {
      view
        .loadMore()
        .catch((err: any) =>
          store.log.error('Failed to fetch suggestions', err),
        )
    }, [view, store.log])

    React.useEffect(() => {
      if (!view.isLoading && !view.hasError && !view.hasContent) {
        onNoSuggestions?.()
      }
    }, [view, view.isLoading, view.hasError, view.hasContent, onNoSuggestions])

    const onRefresh = () => {
      view
        .refresh()
        .catch((err: any) =>
          store.log.error('Failed to fetch suggestions', err),
        )
    }
    const onEndReached = () => {
      view
        .loadMore()
        .catch(err =>
          view?.rootStore.log.error('Failed to load more suggestions', err),
        )
    }

    const renderItem = ({item}: {item: SuggestedActor}) => {
      return (
        <ProfileCardWithFollowBtn
          key={item.did}
          did={item.did}
          declarationCid={item.declaration.cid}
          handle={item.handle}
          displayName={item.displayName}
          avatar={item.avatar}
          description={item.description}
        />
      )
    }
    return (
      <View style={styles.container}>
        {view.hasError ? (
          <CenteredView>
            <ErrorScreen
              title="Failed to load suggestions"
              message="There was an error while trying to load suggested follows."
              details={view.error}
              onPressTryAgain={onRefresh}
            />
          </CenteredView>
        ) : view.isEmpty ? (
          <View />
        ) : (
          <View style={[styles.suggestionsContainer, pal.view]}>
            <FlatList
              data={view.suggestions}
              keyExtractor={item => item.did}
              refreshing={view.isRefreshing}
              onRefresh={onRefresh}
              onEndReached={onEndReached}
              renderItem={renderItem}
              initialNumToRender={15}
              ListFooterComponent={() => (
                <View style={styles.footer}>
                  {view.isLoading && <ActivityIndicator />}
                </View>
              )}
              contentContainerStyle={s.contentContainer}
            />
          </View>
        )}
      </View>
    )
  },
)

const styles = StyleSheet.create({
  container: {
    height: '100%',
  },

  suggestionsContainer: {
    height: '100%',
  },
  footer: {
    height: 200,
    paddingTop: 20,
  },
})