2020-03-27 13:59:38 -07:00
'use strict' ;
import React from 'react' ;
import ImmutablePropTypes from 'react-immutable-proptypes' ;
import PropTypes from 'prop-types' ;
import { connect } from 'react-redux' ;
import { defineMessages , injectIntl , FormattedMessage } from 'react-intl' ;
2021-09-11 14:49:05 -07:00
import BundleContainer from 'soapbox/features/ui/containers/bundle_container' ;
2020-03-27 13:59:38 -07:00
import ImmutablePureComponent from 'react-immutable-pure-component' ;
2020-05-28 15:52:07 -07:00
import Icon from 'soapbox/components/icon' ;
import VerificationBadge from 'soapbox/components/verification_badge' ;
import Badge from 'soapbox/components/badge' ;
2020-03-27 13:59:38 -07:00
import { List as ImmutableList } from 'immutable' ;
2021-09-21 15:29:47 -07:00
import { getAcct , isAdmin , isModerator , isLocal , isVerified } from 'soapbox/utils/accounts' ;
2021-04-10 12:13:07 -07:00
import { displayFqn } from 'soapbox/utils/state' ;
2020-08-12 11:02:20 -07:00
import classNames from 'classnames' ;
2021-09-11 14:49:05 -07:00
import { CryptoAddress } from 'soapbox/features/ui/util/async-components' ;
2021-09-13 11:09:11 -07:00
import ProfileStats from './profile_stats' ;
2021-06-09 18:36:02 -07:00
const TICKER _REGEX = /\$([a-zA-Z]*)/i ;
const getTicker = value => ( value . match ( TICKER _REGEX ) || [ ] ) [ 1 ] ;
const isTicker = value => Boolean ( getTicker ( value ) ) ;
2020-03-27 13:59:38 -07:00
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.' } ,
2020-08-12 11:02:20 -07:00
deactivated : { id : 'account.deactivated' , defaultMessage : 'Deactivated' } ,
2021-01-18 10:55:38 -08:00
bot : { id : 'account.badges.bot' , defaultMessage : 'Bot' } ,
2020-03-27 13:59:38 -07:00
} ) ;
const dateFormatOptions = {
month : 'short' ,
day : 'numeric' ,
year : 'numeric' ,
hour12 : false ,
hour : '2-digit' ,
minute : '2-digit' ,
} ;
class ProfileInfoPanel extends ImmutablePureComponent {
static propTypes = {
account : ImmutablePropTypes . map ,
identity _proofs : ImmutablePropTypes . list ,
intl : PropTypes . object . isRequired ,
username : PropTypes . string ,
2021-04-10 12:13:07 -07:00
displayFqn : PropTypes . bool ,
2020-03-27 13:59:38 -07:00
} ;
2021-07-13 09:21:37 -07:00
getStaffBadge = ( ) => {
const { account } = this . props ;
if ( isAdmin ( account ) ) {
2021-09-13 10:59:44 -07:00
return < Badge slug = 'admin' title = 'Admin' key = 'staff' / > ;
2021-07-13 09:21:37 -07:00
} else if ( isModerator ( account ) ) {
2021-09-13 10:59:44 -07:00
return < Badge slug = 'moderator' title = 'Moderator' key = 'staff' / > ;
2021-07-13 09:21:37 -07:00
} else {
return null ;
}
}
2021-09-13 10:59:44 -07:00
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 ( < Badge slug = 'patron' title = 'Patron' key = 'patron' / > ) ;
}
return badges ;
}
2020-04-14 14:47:35 -07:00
render ( ) {
2021-04-10 12:13:07 -07:00
const { account , displayFqn , intl , identity _proofs , username } = this . props ;
2020-03-27 13:59:38 -07:00
if ( ! account ) {
return (
< div className = 'profile-info-panel' >
< div className = 'profile-info-panel__content' >
< div className = 'profile-info-panel-content__name' >
< h1 >
2020-04-14 11:44:40 -07:00
< span / >
2020-03-27 13:59:38 -07:00
< small > @ { username } < / s m a l l >
< / h 1 >
< / d i v >
< / d i v >
< / d i v >
) ;
}
const content = { _ _html : account . get ( 'note_emojified' ) } ;
const fields = account . get ( 'fields' ) ;
2021-01-18 11:59:24 -08:00
const deactivated = ! account . getIn ( [ 'pleroma' , 'is_active' ] , true ) ;
2020-08-12 11:02:20 -07:00
const displayNameHtml = deactivated ? { _ _html : intl . formatMessage ( messages . deactivated ) } : { _ _html : account . get ( 'display_name_html' ) } ;
2020-03-27 13:59:38 -07:00
const memberSinceDate = intl . formatDate ( account . get ( 'created_at' ) , { month : 'long' , year : 'numeric' } ) ;
2021-09-21 15:29:47 -07:00
const verified = isVerified ( account ) ;
2021-09-13 10:59:44 -07:00
const badges = this . getBadges ( ) ;
2020-03-27 13:59:38 -07:00
return (
2020-08-12 11:02:20 -07:00
< div className = { classNames ( 'profile-info-panel' , { 'deactivated' : deactivated } ) } >
2020-03-27 13:59:38 -07:00
< div className = 'profile-info-panel__content' >
< div className = 'profile-info-panel-content__name' >
< h1 >
2020-08-12 11:02:20 -07:00
< span dangerouslySetInnerHTML = { displayNameHtml } className = 'profile-info-panel__name-content' / >
2020-08-05 10:08:52 -07:00
{ verified && < VerificationBadge / > }
2021-01-18 10:55:38 -08:00
{ account . get ( 'bot' ) && < Badge slug = 'bot' title = { intl . formatMessage ( messages . bot ) } / > }
2021-10-14 12:14:13 -07:00
< small >
@ { getAcct ( account , displayFqn ) }
{ account . get ( 'locked' ) && (
< Icon src = { require ( '@tabler/icons/icons/lock.svg' ) } title = { intl . formatMessage ( messages . account _locked ) } / >
) }
< / s m a l l >
2020-03-27 13:59:38 -07:00
< / h 1 >
< / d i v >
2021-09-13 10:59:44 -07:00
{ badges . length > 0 && (
< div className = 'profile-info-panel-content__badges' >
{ badges }
< / d i v >
) }
2020-08-25 11:47:02 -07:00
< div className = 'profile-info-panel-content__deactivated' >
< FormattedMessage
id = 'account.deactivated_description' defaultMessage = 'This account has been deactivated.'
/ >
< / d i v >
2020-03-27 13:59:38 -07:00
2020-08-25 11:47:02 -07:00
{
2020-03-27 13:59:38 -07:00
( account . get ( 'note' ) . length > 0 && account . get ( 'note' ) !== '<p></p>' ) &&
< div className = 'profile-info-panel-content__bio' dangerouslySetInnerHTML = { content } / >
}
2021-09-13 11:36:37 -07:00
{ isLocal ( account ) && < div className = 'profile-info-panel-content__join-date' >
2021-09-27 21:47:43 -07:00
< Icon src = { require ( '@tabler/icons/icons/calendar.svg' ) } / >
2021-09-13 10:53:39 -07:00
< FormattedMessage
id = 'account.member_since' defaultMessage = 'Joined {date}' values = { {
date : memberSinceDate ,
} }
/ >
< / d i v > }
2021-09-13 11:36:37 -07:00
< ProfileStats
className = 'profile-info-panel-content__stats'
account = { account }
/ >
2021-09-13 11:09:11 -07:00
2020-03-27 13:59:38 -07:00
{ ( fields . size > 0 || identity _proofs . size > 0 ) && (
< div className = 'profile-info-panel-content__fields' >
{ identity _proofs . map ( ( proof , i ) => (
< dl className = 'test' key = { i } >
< dt dangerouslySetInnerHTML = { { _ _html : proof . get ( 'provider' ) } } / >
< dd className = 'verified' >
< a href = { proof . get ( 'proof_url' ) } target = '_blank' rel = 'noopener' >
< span title = { intl . formatMessage ( messages . linkVerifiedOn , { date : intl . formatDate ( proof . get ( 'updated_at' ) , dateFormatOptions ) } ) } >
< Icon id = 'check' className = 'verified__mark' / >
< / s p a n >
< / a >
< a href = { proof . get ( 'profile_url' ) } target = '_blank' rel = 'noopener' >
< span dangerouslySetInnerHTML = { { _ _html : ' ' + proof . get ( 'provider_username' ) } } / >
< / a >
< / d d >
< / d l >
) ) }
2021-06-09 18:36:02 -07:00
{ fields . map ( ( pair , i ) =>
isTicker ( pair . get ( 'name' , '' ) ) ? (
2021-10-14 11:38:16 -07:00
< BundleContainer fetchComponent = { CryptoAddress } key = { i } >
2021-09-11 14:49:05 -07:00
{ Component => (
< Component
key = { i }
ticker = { getTicker ( pair . get ( 'name' ) ) . toLowerCase ( ) }
address = { pair . get ( 'value_plain' ) }
/ >
) }
< / B u n d l e C o n t a i n e r >
2021-06-09 18:36:02 -07:00
) : (
< dl className = 'profile-info-panel-content__fields__item' key = { i } >
< dt dangerouslySetInnerHTML = { { _ _html : pair . get ( 'name_emojified' ) } } title = { pair . get ( 'name' ) } / >
< dd className = { pair . get ( 'verified_at' ) && 'verified' } title = { pair . get ( 'value_plain' ) } >
{ pair . get ( 'verified_at' ) && < span title = { intl . formatMessage ( messages . linkVerifiedOn , { date : intl . formatDate ( pair . get ( 'verified_at' ) , dateFormatOptions ) } ) } > < Icon id = 'check' className = 'verified__mark' / > < /span>} <span dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} / >
< / d d >
< / d l >
) ,
) }
2020-03-27 13:59:38 -07:00
< / d i v >
) }
< / d i v >
< / d i v >
) ;
}
2020-04-14 11:44:40 -07:00
2020-03-27 13:59:38 -07:00
}
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' ] ) ,
2021-04-10 12:13:07 -07:00
displayFqn : displayFqn ( state ) ,
2020-03-27 13:59:38 -07:00
} ;
} ;
export default injectIntl (
connect ( mapStateToProps , null , null , {
forwardRef : true ,
2020-10-07 11:08:36 -07:00
} ,
2020-04-14 11:44:40 -07:00
) ( ProfileInfoPanel ) ) ;