Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move FollowButton to ProfileHeader #1842

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions src/view/com/profile/FollowButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,29 @@ import {Button, ButtonType} from '../util/forms/Button'
import * as Toast from '../util/Toast'
import {FollowState} from 'state/models/cache/my-follows'
import {useFollowProfile} from 'lib/hooks/useFollowProfile'
import {s} from '#/lib/styles'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {usePalette} from '#/lib/hooks/usePalette'

type Props = {
unfollowedType?: ButtonType
followedType?: ButtonType
profile: AppBskyActorDefs.ProfileViewBasic
onToggleFollow?: (v: boolean) => void
labelStyle?: StyleProp<TextStyle>
} & React.ComponentProps<typeof Button>

export const FollowButton = observer(function FollowButtonImpl({
unfollowedType = 'inverted',
followedType = 'default',
profile,
onToggleFollow,
labelStyle,
}: {
unfollowedType?: ButtonType
followedType?: ButtonType
profile: AppBskyActorDefs.ProfileViewBasic
onToggleFollow?: (v: boolean) => void
labelStyle?: StyleProp<TextStyle>
}) {
...rest
}: Props) {
const pal = usePalette('default')
const palInverted = usePalette('inverted')

const {state, following, toggle} = useFollowProfile(profile)

const onPress = React.useCallback(async () => {
Expand All @@ -37,11 +46,19 @@ export const FollowButton = observer(function FollowButtonImpl({

return (
<Button
StartIcon={
following ? (
<FontAwesomeIcon icon="check" style={[pal.text, s.mr2]} size={14} />
) : (
<FontAwesomeIcon icon="plus" style={[palInverted.text, s.mr2]} />
)
}
type={following ? followedType : unfollowedType}
labelStyle={labelStyle}
onPress={onPress}
label={following ? 'Unfollow' : 'Follow'}
withLoading={true}
{...rest}
/>
)
})
57 changes: 20 additions & 37 deletions src/view/com/profile/ProfileHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {makeProfileLink} from 'lib/routes/links'
import {Link} from '../util/Link'
import {ProfileHeaderSuggestedFollows} from './ProfileHeaderSuggestedFollows'
import {logger} from '#/logger'
import {FollowButton} from './FollowButton'

interface Props {
view: ProfileModel
Expand Down Expand Up @@ -111,7 +112,6 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
isProfilePreview,
}: Props) {
const pal = usePalette('default')
const palInverted = usePalette('inverted')
const store = useStores()
const navigation = useNavigation<NavigationProp>()
const {track} = useAnalytics()
Expand Down Expand Up @@ -355,6 +355,8 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
const following = formatCount(view.followsCount)
const followers = formatCount(view.followersCount)
const pluralizedFollowers = pluralize(view.followersCount, 'follower')
const isFollowing =
store.me.follows.getFollowState(view.did) === FollowState.Following

return (
<View style={pal.view}>
Expand Down Expand Up @@ -413,7 +415,7 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
pal.text,
{
color: showSuggestedFollows
? colors.white
? pal.textInverted.color
: pal.text.color,
},
]}
Expand All @@ -422,41 +424,22 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
</TouchableOpacity>
)}

{store.me.follows.getFollowState(view.did) ===
FollowState.Following ? (
<TouchableOpacity
testID="unfollowBtn"
onPress={onPressToggleFollow}
style={[styles.btn, styles.mainBtn, pal.btn]}
accessibilityRole="button"
accessibilityLabel={`Unfollow ${view.handle}`}
accessibilityHint={`Hides posts from ${view.handle} in your feed`}>
<FontAwesomeIcon
icon="check"
style={[pal.text, s.mr5]}
size={14}
/>
<Text type="button" style={pal.text}>
Following
</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
testID="followBtn"
onPress={onPressToggleFollow}
style={[styles.btn, styles.mainBtn, palInverted.view]}
accessibilityRole="button"
accessibilityLabel={`Follow ${view.handle}`}
accessibilityHint={`Shows posts from ${view.handle} in your feed`}>
<FontAwesomeIcon
icon="plus"
style={[palInverted.text, s.mr5]}
/>
<Text type="button" style={[palInverted.text, s.bold]}>
Follow
</Text>
</TouchableOpacity>
)}
<FollowButton
style={styles.btn}
testID={isFollowing ? 'unfollowBtn' : 'followBtn'}
unfollowedType="inverted"
profile={view}
accessibilityHint={
isFollowing
? `Hides posts from ${view.handle} in your feed`
: `Shows posts from ${view.handle} in your feed`
}
accessibilityLabel={`${isFollowing ? 'Unfollow' : 'Follow'} ${
view.handle
}`}
onToggleFollow={onPressToggleFollow}
followedType="default"
/>
</>
) : null}
{dropdownItems?.length ? (
Expand Down
27 changes: 22 additions & 5 deletions src/view/com/util/forms/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import {Text} from '../text/Text'
import {useTheme} from 'lib/ThemeContext'
import {choose} from 'lib/functions'
import {s} from '#/lib/styles'

type Event =
| React.MouseEvent<HTMLAnchorElement, MouseEvent>
Expand Down Expand Up @@ -42,6 +43,8 @@ export function Button({
type = 'primary',
label,
style,
StartIcon,
EndIcon,
labelContainerStyle,
labelStyle,
onPress,
Expand All @@ -56,6 +59,8 @@ export function Button({
type?: ButtonType
label?: string
style?: StyleProp<ViewStyle>
StartIcon?: React.ReactElement
EndIcon?: React.ReactElement
labelContainerStyle?: StyleProp<ViewStyle>
labelStyle?: StyleProp<TextStyle>
onPress?: () => void | Promise<void>
Expand Down Expand Up @@ -169,29 +174,40 @@ export function Button({
[typeOuterStyle, style],
)

const renderChildern = React.useCallback(() => {
const renderChildren = React.useCallback(() => {
if (!label) {
return children
}

return (
<View style={[styles.labelContainer, labelContainerStyle]}>
{React.isValidElement(StartIcon) && !isLoading ? StartIcon : null}

{label && withLoading && isLoading ? (
<ActivityIndicator size={12} color={typeLabelStyle.color} />
<ActivityIndicator
style={s.mr2}
size={12}
color={typeLabelStyle.color}
/>
) : null}

<Text type="button" style={[typeLabelStyle, labelStyle]}>
{label}
</Text>

{React.isValidElement(EndIcon) && !isLoading && EndIcon}
</View>
)
}, [
children,
label,
labelContainerStyle,
StartIcon,
withLoading,
isLoading,
labelContainerStyle,
typeLabelStyle,
labelStyle,
EndIcon,
children,
])

return (
Expand All @@ -205,7 +221,7 @@ export function Button({
accessibilityHint={accessibilityHint}
accessibilityLabelledBy={accessibilityLabelledBy}
onAccessibilityEscape={onAccessibilityEscape}>
{renderChildern}
{renderChildren}
</Pressable>
)
}
Expand All @@ -217,6 +233,7 @@ const styles = StyleSheet.create({
borderRadius: 24,
},
labelContainer: {
alignItems: 'center',
flexDirection: 'row',
gap: 8,
},
Expand Down