import React, {useMemo} from 'react'
import {observer} from 'mobx-react-lite'
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native'
import LinearGradient from 'react-native-linear-gradient'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {AtUri} from '../../../third-party/uri'
import {ProfileViewModel} from '../../../state/models/profile-view'
import {useStores} from '../../../state'
import {
ConfirmModel,
EditProfileModel,
InviteToSceneModel,
} from '../../../state/models/shell-ui'
import {pluralize} from '../../../lib/strings'
import {s, colors} from '../../lib/styles'
import {getGradient} from '../../lib/asset-gen'
import {DropdownBtn, DropdownItem} from '../util/DropdownBtn'
import * as Toast from '../util/Toast'
import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
import {RichText} from '../util/RichText'
import {UserAvatar} from '../util/UserAvatar'
import {UserBanner} from '../util/UserBanner'
import {UserInfoText} from '../util/UserInfoText'
export const ProfileHeader = observer(function ProfileHeader({
view,
onRefreshAll,
}: {
view: ProfileViewModel
onRefreshAll: () => void
}) {
const store = useStores()
const isMember = useMemo(
() => view.isScene && view.myState.member,
[view.myState.member],
)
const onPressBack = () => {
store.nav.tab.goBack()
}
const onPressSearch = () => {
store.nav.navigate(`/search`)
}
const onPressToggleFollow = () => {
view?.toggleFollowing().then(
() => {
Toast.show(
`${view.myState.follow ? 'Following' : 'No longer following'} ${
view.displayName || view.handle
}`,
)
},
err => console.error('Failed to toggle follow', err),
)
}
const onPressEditProfile = () => {
store.shell.openModal(new EditProfileModel(view, onRefreshAll))
}
const onPressFollowers = () => {
store.nav.navigate(`/profile/${view.handle}/followers`)
}
const onPressFollows = () => {
store.nav.navigate(`/profile/${view.handle}/follows`)
}
const onPressMembers = () => {
store.nav.navigate(`/profile/${view.handle}/members`)
}
const onPressInviteMembers = () => {
store.shell.openModal(new InviteToSceneModel(view))
}
const onPressLeaveScene = () => {
store.shell.openModal(
new ConfirmModel(
'Leave this scene?',
`You'll be able to come back unless your invite is revoked.`,
onPressConfirmLeaveScene,
),
)
}
const onPressConfirmLeaveScene = async () => {
if (view.myState.member) {
await store.api.app.bsky.graph.confirmation.delete({
did: store.me.did || '',
rkey: new AtUri(view.myState.member).rkey,
})
Toast.show(`Scene left`)
}
onRefreshAll()
}
// loading
// =
if (!view || !view.hasLoaded) {
return (
{view.displayName || view.handle}
)
}
// error
// =
if (view.hasError) {
return (
{view.error}
)
}
// loaded
// =
const gradient = getGradient(view.handle)
const isMe = store.me.did === view.did
const isCreator = view.isScene && view.creator === store.me.did
let dropdownItems: DropdownItem[] | undefined
if (isCreator || isMember) {
dropdownItems = []
if (isCreator) {
dropdownItems.push({
label: 'Edit Profile',
onPress: onPressEditProfile,
})
}
if (isMember) {
dropdownItems.push({
label: 'Leave Scene...',
onPress: onPressLeaveScene,
})
}
}
return (
{isMe ? (
Edit Profile
) : (
<>
{view.myState.follow ? (
Following
) : (
Follow
)}
>
)}
{view.isScene &&
(view.myState.member || view.creator === store.me.did) ? (
) : undefined}
{view.displayName || view.handle}
{view.isScene ? (
Scene
) : undefined}
@{view.handle}
{view.followersCount}
{pluralize(view.followersCount, 'follower')}
{view.isUser ? (
{view.followsCount}
following
) : undefined}
{view.isScene ? (
{view.membersCount}
{pluralize(view.membersCount, 'member')}
) : undefined}
{view.postsCount}
{pluralize(view.postsCount, 'post')}
{view.description ? (
) : undefined}
{view.isScene && view.creator ? (
Created by
) : undefined}
{view.isScene && view.myState.member ? (
You are a member
) : undefined}
{view.isScene && view.creator === store.me.did ? (
Invite Members
) : undefined}
)
})
const styles = StyleSheet.create({
outer: {
backgroundColor: colors.white,
},
banner: {
width: '100%',
height: 120,
},
avi: {
position: 'absolute',
top: 80,
left: 10,
width: 84,
height: 84,
borderRadius: 42,
borderWidth: 2,
borderColor: colors.white,
backgroundColor: colors.white,
},
content: {
paddingTop: 8,
paddingHorizontal: 14,
paddingBottom: 4,
},
buttonsLine: {
flexDirection: 'row',
marginLeft: 'auto',
marginBottom: 12,
},
gradientBtn: {
paddingHorizontal: 24,
paddingVertical: 6,
},
mainBtn: {
paddingHorizontal: 24,
},
secondaryBtn: {
paddingHorizontal: 14,
},
btn: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 7,
borderRadius: 50,
backgroundColor: colors.gray1,
marginLeft: 6,
},
displayNameLine: {
// paddingLeft: 86,
// marginBottom: 14,
},
displayName: {
fontSize: 28,
fontWeight: 'bold',
},
handleLine: {
flexDirection: 'row',
marginBottom: 8,
},
handle: {
fontSize: 15,
fontWeight: 'bold',
color: colors.gray5,
},
typeLabelWrapper: {
backgroundColor: colors.gray1,
paddingHorizontal: 4,
borderRadius: 4,
marginRight: 5,
},
typeLabel: {
fontSize: 15,
fontWeight: 'bold',
color: colors.gray5,
},
metricsLine: {
flexDirection: 'row',
marginBottom: 8,
},
metricsText: {
fontSize: 15,
},
description: {
marginBottom: 8,
fontSize: 16,
lineHeight: 20.8, // 1.3 of 16px
},
relationshipsLine: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 5,
},
sceneAdminContainer: {
borderColor: colors.gray1,
borderTopWidth: 1,
borderBottomWidth: 1,
paddingVertical: 12,
paddingHorizontal: 12,
},
sceneAdminBtn: {
paddingVertical: 8,
},
})