import React, {memo, useMemo} from 'react' import {View} from 'react-native' import { AppBskyActorDefs, moderateProfile, ModerationOpts, RichText as RichTextAPI, } from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {logger} from '#/logger' import {isIOS} from '#/platform/detection' import {Shadow} from '#/state/cache/types' import {useModalControls} from '#/state/modals' import { useProfileBlockMutationQueue, useProfileFollowMutationQueue, } from '#/state/queries/profile' import {useRequireAuth, useSession} from '#/state/session' import {useAnalytics} from 'lib/analytics/analytics' import {sanitizeDisplayName} from 'lib/strings/display-names' import {useProfileShadow} from 'state/cache/profile-shadow' import {ProfileMenu} from '#/view/com/profile/ProfileMenu' import * as Toast from '#/view/com/util/Toast' import {atoms as a} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {MessageProfileButton} from '#/components/dms/MessageProfileButton' import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' import { KnownFollowers, shouldShowKnownFollowers, } from '#/components/KnownFollowers' import * as Prompt from '#/components/Prompt' import {RichText} from '#/components/RichText' import {ProfileHeaderDisplayName} from './DisplayName' import {ProfileHeaderHandle} from './Handle' import {ProfileHeaderMetrics} from './Metrics' import {ProfileHeaderShell} from './Shell' interface Props { profile: AppBskyActorDefs.ProfileViewDetailed descriptionRT: RichTextAPI | null moderationOpts: ModerationOpts hideBackButton?: boolean isPlaceholderProfile?: boolean } let ProfileHeaderStandard = ({ profile: profileUnshadowed, descriptionRT, moderationOpts, hideBackButton = false, isPlaceholderProfile, }: Props): React.ReactNode => { const profile: Shadow = useProfileShadow(profileUnshadowed) const {currentAccount, hasSession} = useSession() const {_} = useLingui() const {openModal} = useModalControls() const {track} = useAnalytics() const moderation = useMemo( () => moderateProfile(profile, moderationOpts), [profile, moderationOpts], ) const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( profile, 'ProfileHeader', ) const [_queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) const unblockPromptControl = Prompt.usePromptControl() const requireAuth = useRequireAuth() const isBlockedUser = profile.viewer?.blocking || profile.viewer?.blockedBy || profile.viewer?.blockingByList const onPressEditProfile = React.useCallback(() => { track('ProfileHeader:EditProfileButtonClicked') openModal({ name: 'edit-profile', profile, }) }, [track, openModal, profile]) const onPressFollow = () => { requireAuth(async () => { try { track('ProfileHeader:FollowButtonClicked') await queueFollow() Toast.show( _( msg`Following ${sanitizeDisplayName( profile.displayName || profile.handle, moderation.ui('displayName'), )}`, ), ) } catch (e: any) { if (e?.name !== 'AbortError') { logger.error('Failed to follow', {message: String(e)}) Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') } } }) } const onPressUnfollow = () => { requireAuth(async () => { try { track('ProfileHeader:UnfollowButtonClicked') await queueUnfollow() Toast.show( _( msg`No longer following ${sanitizeDisplayName( profile.displayName || profile.handle, moderation.ui('displayName'), )}`, ), ) } catch (e: any) { if (e?.name !== 'AbortError') { logger.error('Failed to unfollow', {message: String(e)}) Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') } } }) } const unblockAccount = React.useCallback(async () => { track('ProfileHeader:UnblockAccountButtonClicked') try { await queueUnblock() Toast.show(_(msg`Account unblocked`)) } catch (e: any) { if (e?.name !== 'AbortError') { logger.error('Failed to unblock account', {message: e}) Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') } } }, [_, queueUnblock, track]) const isMe = React.useMemo( () => currentAccount?.did === profile.did, [currentAccount, profile], ) return ( {isMe ? ( ) : profile.viewer?.blocking ? ( profile.viewer?.blockingByList ? null : ( ) ) : !profile.viewer?.blockedBy ? ( <> {hasSession && } ) : null} {!isPlaceholderProfile && !isBlockedUser && ( <> {descriptionRT && !moderation.ui('profileView').blur ? ( ) : undefined} {!isMe && !isBlockedUser && shouldShowKnownFollowers(profile.viewer?.knownFollowers) && ( )} )} ) } ProfileHeaderStandard = memo(ProfileHeaderStandard) export {ProfileHeaderStandard}