From 6df1bcad31a4e58a7cdade6d19e75bd7c0b5ee9a Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 21:16:11 -0500 Subject: [PATCH] add suggested follow section to profile header (#1481) * add suggested follow section to profile header * fix button overflow * don't even render on preview * fix useFollowDid and FollowButton race condition * add section header, close button, active state * lighten icon --- src/lib/hooks/useFollowDid.ts | 46 +++ src/view/com/modals/ProfilePreview.tsx | 7 +- src/view/com/profile/FollowButton.tsx | 47 +-- src/view/com/profile/ProfileHeader.tsx | 52 +++- .../profile/ProfileHeaderSuggestedFollows.tsx | 288 ++++++++++++++++++ 5 files changed, 406 insertions(+), 34 deletions(-) create mode 100644 src/lib/hooks/useFollowDid.ts create mode 100644 src/view/com/profile/ProfileHeaderSuggestedFollows.tsx diff --git a/src/lib/hooks/useFollowDid.ts b/src/lib/hooks/useFollowDid.ts new file mode 100644 index 00000000..223adb04 --- /dev/null +++ b/src/lib/hooks/useFollowDid.ts @@ -0,0 +1,46 @@ +import React from 'react' + +import {useStores} from 'state/index' +import {FollowState} from 'state/models/cache/my-follows' + +export function useFollowDid({did}: {did: string}) { + const store = useStores() + const state = store.me.follows.getFollowState(did) + + return { + state, + following: state === FollowState.Following, + toggle: React.useCallback(async () => { + if (state === FollowState.Following) { + try { + await store.agent.deleteFollow(store.me.follows.getFollowUri(did)) + store.me.follows.removeFollow(did) + return { + state: FollowState.NotFollowing, + following: false, + } + } catch (e: any) { + store.log.error('Failed to delete follow', e) + throw e + } + } else if (state === FollowState.NotFollowing) { + try { + const res = await store.agent.follow(did) + store.me.follows.addFollow(did, res.uri) + return { + state: FollowState.Following, + following: true, + } + } catch (e: any) { + store.log.error('Failed to create follow', e) + throw e + } + } + + return { + state: FollowState.Unknown, + following: false, + } + }, [store, did, state]), + } +} diff --git a/src/view/com/modals/ProfilePreview.tsx b/src/view/com/modals/ProfilePreview.tsx index 6f189cf1..e0b3ec07 100644 --- a/src/view/com/modals/ProfilePreview.tsx +++ b/src/view/com/modals/ProfilePreview.tsx @@ -41,7 +41,12 @@ export const Component = observer(function ProfilePreviewImpl({ styles.headerWrapper, isLoading && isIOS && styles.headerPositionAdjust, ]}> - {}} /> + {}} + isProfilePreview + /> diff --git a/src/view/com/profile/FollowButton.tsx b/src/view/com/profile/FollowButton.tsx index 4b2b944f..217d326e 100644 --- a/src/view/com/profile/FollowButton.tsx +++ b/src/view/com/profile/FollowButton.tsx @@ -2,9 +2,9 @@ import React from 'react' import {StyleProp, TextStyle, View} from 'react-native' import {observer} from 'mobx-react-lite' import {Button, ButtonType} from '../util/forms/Button' -import {useStores} from 'state/index' import * as Toast from '../util/Toast' import {FollowState} from 'state/models/cache/my-follows' +import {useFollowDid} from 'lib/hooks/useFollowDid' export const FollowButton = observer(function FollowButtonImpl({ unfollowedType = 'inverted', @@ -19,44 +19,27 @@ export const FollowButton = observer(function FollowButtonImpl({ onToggleFollow?: (v: boolean) => void labelStyle?: StyleProp }) { - const store = useStores() - const followState = store.me.follows.getFollowState(did) + const {state, following, toggle} = useFollowDid({did}) - if (followState === FollowState.Unknown) { - return - } - - const onToggleFollowInner = async () => { - const updatedFollowState = await store.me.follows.fetchFollowState(did) - if (updatedFollowState === FollowState.Following) { - try { - onToggleFollow?.(false) - await store.agent.deleteFollow(store.me.follows.getFollowUri(did)) - store.me.follows.removeFollow(did) - } catch (e: any) { - store.log.error('Failed to delete follow', e) - Toast.show('An issue occurred, please try again.') - } - } else if (updatedFollowState === FollowState.NotFollowing) { - try { - onToggleFollow?.(true) - const res = await store.agent.follow(did) - store.me.follows.addFollow(did, res.uri) - } catch (e: any) { - store.log.error('Failed to create follow', e) - Toast.show('An issue occurred, please try again.') - } + const onPress = React.useCallback(async () => { + try { + const {following} = await toggle() + onToggleFollow?.(following) + } catch (e: any) { + Toast.show('An issue occurred, please try again.') } + }, [toggle, onToggleFollow]) + + if (state === FollowState.Unknown) { + return } return (