mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at rnw 212 lines 5.0 kB view raw
1import React from 'react' 2import {StyleSheet, TouchableOpacity, View} from 'react-native' 3import {observer} from 'mobx-react-lite' 4import {Link} from '../util/Link' 5import {Text} from '../util/text/Text' 6import {UserAvatar} from '../util/UserAvatar' 7import * as Toast from '../util/Toast' 8import {s} from 'lib/styles' 9import {usePalette} from 'lib/hooks/usePalette' 10import {useStores} from 'state/index' 11import * as apilib from 'lib/api/index' 12 13export function ProfileCard({ 14 handle, 15 displayName, 16 avatar, 17 description, 18 isFollowedBy, 19 noBorder, 20 renderButton, 21}: { 22 handle: string 23 displayName?: string 24 avatar?: string 25 description?: string 26 isFollowedBy?: boolean 27 noBorder?: boolean 28 renderButton?: () => JSX.Element 29}) { 30 const pal = usePalette('default') 31 return ( 32 <Link 33 style={[ 34 styles.outer, 35 pal.view, 36 pal.border, 37 noBorder && styles.outerNoBorder, 38 ]} 39 href={`/profile/${handle}`} 40 title={handle} 41 noFeedback> 42 <View style={styles.layout}> 43 <View style={styles.layoutAvi}> 44 <UserAvatar 45 size={40} 46 displayName={displayName} 47 handle={handle} 48 avatar={avatar} 49 /> 50 </View> 51 <View style={styles.layoutContent}> 52 <Text 53 type="lg" 54 style={[s.bold, pal.text]} 55 numberOfLines={1} 56 lineHeight={1.2}> 57 {displayName || handle} 58 </Text> 59 <Text type="md" style={[pal.textLight]} numberOfLines={1}> 60 @{handle} 61 </Text> 62 {isFollowedBy && ( 63 <View style={s.flexRow}> 64 <View style={[s.mt5, pal.btn, styles.pill]}> 65 <Text type="xs">Follows You</Text> 66 </View> 67 </View> 68 )} 69 </View> 70 {renderButton ? ( 71 <View style={styles.layoutButton}>{renderButton()}</View> 72 ) : undefined} 73 </View> 74 {description ? ( 75 <View style={styles.details}> 76 <Text style={pal.text} numberOfLines={4}> 77 {description} 78 </Text> 79 </View> 80 ) : undefined} 81 </Link> 82 ) 83} 84 85export const ProfileCardWithFollowBtn = observer( 86 ({ 87 did, 88 declarationCid, 89 handle, 90 displayName, 91 avatar, 92 description, 93 isFollowedBy, 94 }: { 95 did: string 96 declarationCid: string 97 handle: string 98 displayName?: string 99 avatar?: string 100 description?: string 101 isFollowedBy?: boolean 102 }) => { 103 const store = useStores() 104 const isMe = store.me.handle === handle 105 const isFollowing = store.me.follows.isFollowing(did) 106 const onToggleFollow = async () => { 107 if (store.me.follows.isFollowing(did)) { 108 try { 109 await apilib.unfollow(store, store.me.follows.getFollowUri(did)) 110 store.me.follows.removeFollow(did) 111 } catch (e: any) { 112 store.log.error('Failed fo delete follow', e) 113 Toast.show('An issue occurred, please try again.') 114 } 115 } else { 116 try { 117 const res = await apilib.follow(store, did, declarationCid) 118 store.me.follows.addFollow(did, res.uri) 119 } catch (e: any) { 120 store.log.error('Failed fo create follow', e) 121 Toast.show('An issue occurred, please try again.') 122 } 123 } 124 } 125 return ( 126 <ProfileCard 127 handle={handle} 128 displayName={displayName} 129 avatar={avatar} 130 description={description} 131 isFollowedBy={isFollowedBy} 132 renderButton={ 133 isMe 134 ? undefined 135 : () => ( 136 <FollowBtn isFollowing={isFollowing} onPress={onToggleFollow} /> 137 ) 138 } 139 /> 140 ) 141 }, 142) 143 144function FollowBtn({ 145 isFollowing, 146 onPress, 147}: { 148 isFollowing: boolean 149 onPress: () => void 150}) { 151 const pal = usePalette('default') 152 return ( 153 <TouchableOpacity onPress={onPress}> 154 <View style={[styles.btn, pal.btn]}> 155 <Text type="button" style={[pal.text]}> 156 {isFollowing ? 'Unfollow' : 'Follow'} 157 </Text> 158 </View> 159 </TouchableOpacity> 160 ) 161} 162 163const styles = StyleSheet.create({ 164 outer: { 165 borderTopWidth: 1, 166 paddingHorizontal: 6, 167 }, 168 outerNoBorder: { 169 borderTopWidth: 0, 170 }, 171 layout: { 172 flexDirection: 'row', 173 alignItems: 'center', 174 }, 175 layoutAvi: { 176 width: 60, 177 paddingLeft: 10, 178 paddingTop: 8, 179 paddingBottom: 10, 180 }, 181 avi: { 182 width: 40, 183 height: 40, 184 borderRadius: 20, 185 resizeMode: 'cover', 186 }, 187 layoutContent: { 188 flex: 1, 189 paddingRight: 10, 190 paddingTop: 10, 191 paddingBottom: 10, 192 }, 193 layoutButton: { 194 paddingRight: 10, 195 }, 196 details: { 197 paddingLeft: 60, 198 paddingRight: 10, 199 paddingBottom: 10, 200 }, 201 pill: { 202 borderRadius: 4, 203 paddingHorizontal: 6, 204 paddingVertical: 2, 205 }, 206 btn: { 207 paddingVertical: 7, 208 borderRadius: 50, 209 marginLeft: 6, 210 paddingHorizontal: 14, 211 }, 212})