import React, {useMemo, useEffect, useState} from 'react' import { ActivityIndicator, FlatList, StyleSheet, Text, TouchableOpacity, View, } from 'react-native' import LinearGradient from 'react-native-linear-gradient' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {observer} from 'mobx-react-lite' import _omit from 'lodash.omit' import {ErrorScreen} from '../util/ErrorScreen' import {UserAvatar} from '../util/UserAvatar' import Toast from '../util/Toast' import {useStores} from '../../../state' import * as apilib from '../../../state/lib/api' import { SuggestedActorsViewModel, SuggestedActor, } from '../../../state/models/suggested-actors-view' import {s, colors, gradients} from '../../lib/styles' export const SuggestedFollows = observer( ({onNoSuggestions}: {onNoSuggestions?: () => void}) => { const store = useStores() const [follows, setFollows] = useState>({}) const view = useMemo( () => new SuggestedActorsViewModel(store), [], ) useEffect(() => { console.log('Fetching suggested actors') view .setup() .catch((err: any) => console.error('Failed to fetch suggestions', err)) }, [view]) useEffect(() => { if (!view.isLoading && !view.hasError && !view.hasContent) { onNoSuggestions?.() } }, [view, view.isLoading, view.hasError, view.hasContent]) const onPressTryAgain = () => view .setup() .catch((err: any) => console.error('Failed to fetch suggestions', err)) const onPressFollow = async (item: SuggestedActor) => { try { const res = await apilib.follow(store, item.did, item.declaration.cid) setFollows({[item.did]: res.uri, ...follows}) } catch (e) { console.log(e) Toast.show('An issue occurred, please try again.', { duration: Toast.durations.LONG, position: Toast.positions.TOP, }) } } const onPressUnfollow = async (item: SuggestedActor) => { try { await apilib.unfollow(store, follows[item.did]) setFollows(_omit(follows, [item.did])) } catch (e) { console.log(e) Toast.show('An issue occurred, please try again.', { duration: Toast.durations.LONG, position: Toast.positions.TOP, }) } } const renderItem = ({item}: {item: SuggestedActor}) => ( ) return ( {view.isLoading ? ( ) : view.hasError ? ( ) : view.isEmpty ? ( You already follow everybody we were going to suggest. Check back in the future! ) : ( item._reactKey} renderItem={renderItem} style={s.flex1} /> )} ) }, ) const User = ({ item, follow, onPressFollow, onPressUnfollow, }: { item: SuggestedActor follow: string | undefined onPressFollow: (item: SuggestedActor) => void onPressUnfollow: (item: SuggestedActor) => void }) => { return ( {item.displayName || item.handle} @{item.handle} {follow ? ( onPressUnfollow(item)}> Unfollow ) : ( onPressFollow(item)}> Follow )} {item.description ? ( {item.description} ) : undefined} ) } const styles = StyleSheet.create({ container: { flex: 1, }, suggestionsContainer: { flex: 1, backgroundColor: colors.gray1, }, emptyContainer: { backgroundColor: colors.gray1, marginHorizontal: 14, paddingHorizontal: 8, paddingVertical: 14, borderRadius: 6, }, actor: { backgroundColor: colors.white, borderRadius: 6, margin: 2, marginBottom: 0, }, actorMeta: { flexDirection: 'row', }, actorAvi: { width: 60, paddingLeft: 10, paddingTop: 10, paddingBottom: 10, }, actorContent: { flex: 1, paddingRight: 10, paddingTop: 10, }, actorBtn: { paddingRight: 10, paddingTop: 10, }, actorDetails: { paddingLeft: 60, paddingRight: 10, paddingBottom: 10, }, gradientBtn: { paddingHorizontal: 24, paddingVertical: 6, }, secondaryBtn: { paddingHorizontal: 14, }, btn: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: 7, borderRadius: 50, backgroundColor: colors.gray1, marginLeft: 6, }, })