import React from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePureComponent from 'react-immutable-pure-component' import { defineMessages, injectIntl } from 'react-intl' import Sticky from 'react-stickynode' import { CX, POPOVER_PROFILE_OPTIONS, PLACEHOLDER_MISSING_HEADER_SRC, MODAL_EDIT_PROFILE, BREAKPOINT_EXTRA_SMALL, } from '../constants' import { addShortcut, removeShortcut, } from '../actions/shortcuts' import { createChatConversation } from '../actions/chat_conversations' import { openModal } from '../actions/modal' import { openPopover } from '../actions/popover' import { me } from '../initial_state' import AccountActionButton from './account_action_button' import Avatar from './avatar' import Button from './button' import DisplayName from './display_name' import Image from './image' import TabBar from './tab_bar' import Pills from './pills' import Text from './text' import Responsive from '../features/ui/util/responsive_component'; import ProfileHeaderXSPlaceholder from './placeholder/profile_header_xs_placeholder' class ProfileHeader extends ImmutablePureComponent { static contextTypes = { router: PropTypes.object } state = { stickied: false, } handleOnEditProfile = () => { this.props.onEditProfile() } handleOpenMore = () => { const { openProfileOptionsPopover, account } = this.props openProfileOptionsPopover({ account, targetRef: this.openMoreNode, position: 'left', }) } handleToggleShortcut = () => { const { account, isShortcut } = this.props const accountId = !!account ? account.get('id') : null if (!accountId) return if (isShortcut) { this.props.onRemoveShortcut(accountId) } else { this.props.onAddShortcut(accountId) } } onStickyStateChange = (status) => { if (status.status === Sticky.STATUS_FIXED) { this.setState({ stickied: true }) } else { this.setState({ stickied: false }) } } handleOnCreateChatConversation = () => { const { account } = this.props const accountId = !!account ? account.get('id') : null if (!accountId) return this.props.onCreateChatConversation(accountId, this.context.router.history) } setOpenMoreNodeRef = (n) => { this.openMoreNode = n } render() { const { account, children, intl, isShortcut, isXS } = this.props const { stickied } = this.state if (isXS && !account) { return (
) } const tabs = !account ? null : [ { to: `/${account.get('acct')}`, title: intl.formatMessage(messages.timeline), }, { to: `/${account.get('acct')}/comments`, title: intl.formatMessage(messages.comments), }, { to: `/${account.get('acct')}/photos`, title: intl.formatMessage(messages.photos), }, { to: `/${account.get('acct')}/videos`, title: intl.formatMessage(messages.videos), }, ] const isMyProfile = !account ? false : account.get('id') === me if (isMyProfile) { tabs.push({ to: `/${account.get('acct')}/likes`, title: 'Likes', }) tabs.push({ to: `/${account.get('acct')}/bookmarks`, title: intl.formatMessage(messages.bookmarks), }) } const headerSrc = !!account ? account.get('header') : undefined const headerMissing = !headerSrc ? true : headerSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 const avatarSize = headerMissing ? 75 : 150 const top = headerMissing ? -46 : -380 const avatarContainerClasses = CX({ d: 1, circle: 1, mtNeg75PX: !headerMissing, boxShadowProfileAvatar: !headerMissing, }) const stickyBarContainerClasses = CX({ d: 1, flexRow: 1, px15: 1, aiCenter: 1, displayNone: !stickied, }) const tabBarContainerClasses = CX({ d: 1, displayNone: stickied, }) const mobileDescriptionContainerClasses = CX({ d: 1, w100PC: 1, px15: 1, mb10: 1, pt15: !!me, }) return (
{ !headerMissing &&
{intl.formatMessage(messages.headerPhoto)}
} { headerMissing &&
}
{ account && account.get('id') === me &&
} { account && account.get('id') !== me && !!me &&
}
{children}
{ /** desktop */ }
{ !headerMissing &&
{intl.formatMessage(messages.headerPhoto)}
} { headerMissing &&
}
{ account && } { !account &&
}
{ account && account.get('id') === me &&
} { account && account.get('id') !== me &&
{ !!me &&
}
}
) } } const mapStateToProps = (state, { account }) => { const accountId = account ? account.get('id') : null const shortcuts = state.getIn(['shortcuts', 'items']) const isShortcut = !!shortcuts.find((s) => { return s.get('shortcut_id') == accountId && s.get('shortcut_type') === 'account' }) return { isShortcut } } const messages = defineMessages({ followers: { id: 'account.followers', defaultMessage: 'Followers' }, follows: { id: 'account.follows', defaultMessage: 'Following' }, profile: { id: 'account.profile', defaultMessage: 'Profile' }, headerPhoto: { id: 'header_photo', defaultMessage: 'Header photo' }, timeline: { id: 'timeline', defaultMessage: 'Timeline' }, comments: { id: 'comments', defaultMessage: 'Comments' }, photos: { id: 'photos', defaultMessage: 'Photos' }, videos: { id: 'videos', defaultMessage: 'Videos' }, bookmarks: { id: 'bookmarks', defaultMessage: 'Bookmarks' }, accountFollowsYou: { id: 'account.follows_you', defaultMessage: 'Follows you' }, editProfile: { id: "account.edit_profile", defaultMessage: "Edit profile" }, }) const mapDispatchToProps = (dispatch) => ({ openProfileOptionsPopover(props) { dispatch(openPopover(POPOVER_PROFILE_OPTIONS, props)) }, onEditProfile() { dispatch(openModal(MODAL_EDIT_PROFILE)) }, onAddShortcut(accountId) { dispatch(addShortcut('account', accountId)) }, onRemoveShortcut(accountId) { dispatch(removeShortcut(null, 'account', accountId)) }, onCreateChatConversation(accountId, routerHistory) { dispatch(createChatConversation(accountId, routerHistory)) }, }); ProfileHeader.propTypes = { account: ImmutablePropTypes.map, children: PropTypes.any, intl: PropTypes.object.isRequired, onAddShortcut: PropTypes.func.isRequired, onEditProfile: PropTypes.func.isRequired, onRemoveShortcut: PropTypes.func.isRequired, openProfileOptionsPopover: PropTypes.func.isRequired, isShortcut: PropTypes.bool.isRequired, isXS: PropTypes.bool, } export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ProfileHeader))