diff options
Diffstat (limited to 'src/view/com/discover/SuggestedFollows.tsx')
-rw-r--r-- | src/view/com/discover/SuggestedFollows.tsx | 86 |
1 files changed, 72 insertions, 14 deletions
diff --git a/src/view/com/discover/SuggestedFollows.tsx b/src/view/com/discover/SuggestedFollows.tsx index e73d9a7db..4f6ac042e 100644 --- a/src/view/com/discover/SuggestedFollows.tsx +++ b/src/view/com/discover/SuggestedFollows.tsx @@ -1,4 +1,4 @@ -import React, {useMemo, useEffect} from 'react' +import React, {useMemo, useEffect, useState} from 'react' import { ActivityIndicator, FlatList, @@ -10,9 +10,12 @@ import { 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, @@ -22,6 +25,7 @@ import {s, colors, gradients} from '../../lib/styles' export const SuggestedFollows = observer( ({onNoSuggestions}: {onNoSuggestions?: () => void}) => { const store = useStores() + const [follows, setFollows] = useState<Record<string, string>>({}) const view = useMemo<SuggestedActorsViewModel>( () => new SuggestedActorsViewModel(store), @@ -46,7 +50,39 @@ export const SuggestedFollows = observer( .setup() .catch((err: any) => console.error('Failed to fetch suggestions', err)) - const renderItem = ({item}: {item: SuggestedActor}) => <User item={item} /> + 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}) => ( + <User + item={item} + follow={follows[item.did]} + onPressFollow={onPressFollow} + onPressUnfollow={onPressUnfollow} + /> + ) return ( <View style={styles.container}> {view.isLoading ? ( @@ -75,7 +111,17 @@ export const SuggestedFollows = observer( }, ) -const User = ({item}: {item: SuggestedActor}) => { +const User = ({ + item, + follow, + onPressFollow, + onPressUnfollow, +}: { + item: SuggestedActor + follow: string | undefined + onPressFollow: (item: SuggestedActor) => void + onPressUnfollow: (item: SuggestedActor) => void +}) => { return ( <View style={styles.actor}> <View style={styles.actorMeta}> @@ -88,23 +134,35 @@ const User = ({item}: {item: SuggestedActor}) => { </View> <View style={styles.actorContent}> <Text style={[s.f17, s.bold]} numberOfLines={1}> - {item.displayName} + {item.displayName || item.handle} </Text> <Text style={[s.f14, s.gray5]} numberOfLines={1}> @{item.handle} </Text> </View> <View style={styles.actorBtn}> - <TouchableOpacity> - <LinearGradient - colors={[gradients.primary.start, gradients.primary.end]} - start={{x: 0, y: 0}} - end={{x: 1, y: 1}} - style={[styles.btn, styles.gradientBtn]}> - <FontAwesomeIcon icon="plus" style={[s.white, s.mr5]} size={15} /> - <Text style={[s.white, s.fw600, s.f15]}>Follow</Text> - </LinearGradient> - </TouchableOpacity> + {follow ? ( + <TouchableOpacity onPress={() => onPressUnfollow(item)}> + <View style={[styles.btn, styles.secondaryBtn]}> + <Text style={[s.gray5, s.fw600, s.f15]}>Unfollow</Text> + </View> + </TouchableOpacity> + ) : ( + <TouchableOpacity onPress={() => onPressFollow(item)}> + <LinearGradient + colors={[gradients.primary.start, gradients.primary.end]} + start={{x: 0, y: 0}} + end={{x: 1, y: 1}} + style={[styles.btn, styles.gradientBtn]}> + <FontAwesomeIcon + icon="plus" + style={[s.white, s.mr5]} + size={15} + /> + <Text style={[s.white, s.fw600, s.f15]}>Follow</Text> + </LinearGradient> + </TouchableOpacity> + )} </View> </View> {item.description ? ( |