'use strict'; import { List as ImmutableList } from 'immutable'; import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { connect } from 'react-redux'; import { initAccountNoteModal } from 'soapbox/actions/account_notes'; import Badge from 'soapbox/components/badge'; import { Icon, HStack, Stack, Text } from 'soapbox/components/ui'; import VerificationBadge from 'soapbox/components/verification_badge'; import { isLocal } from 'soapbox/utils/accounts'; import { displayFqn } from 'soapbox/utils/state'; import ProfileStats from './profile_stats'; // Basically ensure the URL isn't `javascript:alert('hi')` or something like that const isSafeUrl = text => { try { const url = new URL(text); return ['http:', 'https:'].includes(url.protocol); } catch(e) { return false; } }; const messages = defineMessages({ linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' }, account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' }, deactivated: { id: 'account.deactivated', defaultMessage: 'Deactivated' }, bot: { id: 'account.badges.bot', defaultMessage: 'Bot' }, }); class ProfileInfoPanel extends ImmutablePureComponent { static propTypes = { account: ImmutablePropTypes.record, identity_proofs: ImmutablePropTypes.list, intl: PropTypes.object.isRequired, username: PropTypes.string, displayFqn: PropTypes.bool, onShowNote: PropTypes.func, }; getStaffBadge = () => { const { account } = this.props; if (account?.admin) { return ; } else if (account?.moderator) { return ; } else { return null; } } getBadges = () => { const { account } = this.props; const staffBadge = this.getStaffBadge(); const isPatron = account.getIn(['patron', 'is_patron']); const badges = []; if (staffBadge) { badges.push(staffBadge); } if (isPatron) { badges.push(); } return badges; } renderBirthday = () => { const { account, intl } = this.props; const birthday = account.get('birthday'); if (!birthday) return null; const formattedBirthday = intl.formatDate(birthday, { timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' }); const date = new Date(birthday); const today = new Date(); const hasBirthday = date.getDate() === today.getDate() && date.getMonth() === today.getMonth(); return ( {hasBirthday ? ( ) : ( )} ); } handleShowNote = e => { const { account, onShowNote } = this.props; e.preventDefault(); onShowNote(account); } render() { const { account, displayFqn, intl, username } = this.props; if (!account) { return (
@{username}
); } const content = { __html: account.get('note_emojified') }; const deactivated = !account.getIn(['pleroma', 'is_active'], true); const displayNameHtml = deactivated ? { __html: intl.formatMessage(messages.deactivated) } : { __html: account.get('display_name_html') }; const memberSinceDate = intl.formatDate(account.get('created_at'), { month: 'long', year: 'numeric' }); const verified = account.get('verified'); const badges = this.getBadges(); return (
{/* Not sure if this is actual used. */} {/*
*/} {verified && } {account.bot && } {badges.length > 0 && ( {badges} )} @{displayFqn ? account.fqn : account.acct} {account.get('locked') && ( )} { (account.get('note').length > 0 && account.get('note') !== '

') && }
{isLocal(account) ? ( ) : null} {account.get('location') ? ( {account.get('location')} ) : null} {account.get('website') ? (
{isSafeUrl(account.get('website')) ? ( {account.get('website')} ) : ( account.get('website') )}
) : null} {this.renderBirthday()}
); } } const mapStateToProps = (state, { account }) => { const identity_proofs = account ? state.getIn(['identity_proofs', account.get('id')], ImmutableList()) : ImmutableList(); return { identity_proofs, domain: state.getIn(['meta', 'domain']), displayFqn: displayFqn(state), }; }; const mapDispatchToProps = (dispatch) => ({ onShowNote(account) { dispatch(initAccountNoteModal(account)); }, }); export default injectIntl( connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true, }, )(ProfileInfoPanel));