import React from 'react'
import {View, StyleSheet, Pressable, ScrollView} from 'react-native'
import Animated, {
useSharedValue,
withTiming,
useAnimatedStyle,
Easing,
} from 'react-native-reanimated'
import {AppBskyActorDefs, moderateProfile} from '@atproto/api'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import * as Toast from '../util/Toast'
import {usePalette} from 'lib/hooks/usePalette'
import {Text} from 'view/com/util/text/Text'
import {UserAvatar} from 'view/com/util/UserAvatar'
import {Button} from 'view/com/util/forms/Button'
import {sanitizeDisplayName} from 'lib/strings/display-names'
import {sanitizeHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links'
import {Link} from 'view/com/util/Link'
import {useAnalytics} from 'lib/analytics/analytics'
import {isWeb} from 'platform/detection'
import {useModerationOpts} from '#/state/queries/preferences'
import {useSuggestedFollowsByActorQuery} from '#/state/queries/suggested-follows'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useProfileFollowMutationQueue} from '#/state/queries/profile'
const OUTER_PADDING = 10
const INNER_PADDING = 14
const TOTAL_HEIGHT = 250
export function ProfileHeaderSuggestedFollows({
actorDid,
active,
requestDismiss,
}: {
actorDid: string
active: boolean
requestDismiss: () => void
}) {
const {track} = useAnalytics()
const pal = usePalette('default')
const animatedHeight = useSharedValue(0)
const animatedStyles = useAnimatedStyle(() => ({
opacity: animatedHeight.value / TOTAL_HEIGHT,
height: animatedHeight.value,
}))
React.useEffect(() => {
if (active) {
track('ProfileHeader:SuggestedFollowsOpened')
animatedHeight.value = withTiming(TOTAL_HEIGHT, {
duration: 500,
easing: Easing.inOut(Easing.exp),
})
} else {
animatedHeight.value = withTiming(0, {
duration: 500,
easing: Easing.inOut(Easing.exp),
})
}
}, [active, animatedHeight, track])
const {isLoading, data} = useSuggestedFollowsByActorQuery({
did: actorDid,
})
return (
Suggested for you
{isLoading ? (
<>
>
) : data ? (
data.suggestions.map(profile => (
))
) : (
)}
)
}
function SuggestedFollowSkeleton() {
const pal = usePalette('default')
return (
)
}
function SuggestedFollow({
profile: profileUnshadowed,
}: {
profile: AppBskyActorDefs.ProfileView
}) {
const {track} = useAnalytics()
const pal = usePalette('default')
const moderationOpts = useModerationOpts()
const profile = useProfileShadow(profileUnshadowed)
const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile)
const onPressFollow = React.useCallback(async () => {
try {
track('ProfileHeader:SuggestedFollowFollowed')
await queueFollow()
} catch (e: any) {
if (e?.name !== 'AbortError') {
Toast.show('An issue occurred, please try again.')
}
}
}, [queueFollow, track])
const onPressUnfollow = React.useCallback(async () => {
try {
await queueUnfollow()
} catch (e: any) {
if (e?.name !== 'AbortError') {
Toast.show('An issue occurred, please try again.')
}
}
}, [queueUnfollow])
if (!moderationOpts) {
return null
}
const moderation = moderateProfile(profile, moderationOpts)
const following = profile.viewer?.following
return (
{sanitizeDisplayName(
profile.displayName || sanitizeHandle(profile.handle),
moderation.profile,
)}
{sanitizeHandle(profile.handle, '@')}
)
}
const styles = StyleSheet.create({
suggestedFollowCardOuter: {
marginHorizontal: INNER_PADDING / 2,
paddingTop: 10,
paddingBottom: 12,
paddingHorizontal: 10,
borderRadius: 8,
width: 130,
alignItems: 'center',
overflow: 'hidden',
flexShrink: 1,
},
})