Redesign profile column in web UI to match design on public pages (#10337)
* Redesign profile column in web UI to match design on public pages * Make the tab links text bolder
This commit is contained in:
		
							parent
							
								
									ac0cc692f5
								
							
						
					
					
						commit
						a96181f16f
					
				
					 6 changed files with 357 additions and 462 deletions
				
			
		|  | @ -1,190 +0,0 @@ | |||
| import React from 'react'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import DropdownMenuContainer from '../../../containers/dropdown_menu_container'; | ||||
| import { NavLink } from 'react-router-dom'; | ||||
| import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; | ||||
| import { me, isStaff  } from '../../../initial_state'; | ||||
| import { shortNumberFormat } from '../../../utils/numbers'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|   mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' }, | ||||
|   direct: { id: 'account.direct', defaultMessage: 'Direct message @{name}' }, | ||||
|   edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, | ||||
|   unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, | ||||
|   unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, | ||||
|   unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }, | ||||
|   block: { id: 'account.block', defaultMessage: 'Block @{name}' }, | ||||
|   mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, | ||||
|   follow: { id: 'account.follow', defaultMessage: 'Follow' }, | ||||
|   report: { id: 'account.report', defaultMessage: 'Report @{name}' }, | ||||
|   share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' }, | ||||
|   media: { id: 'account.media', defaultMessage: 'Media' }, | ||||
|   blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' }, | ||||
|   unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' }, | ||||
|   hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' }, | ||||
|   showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' }, | ||||
|   pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' }, | ||||
|   preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, | ||||
|   follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, | ||||
|   favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, | ||||
|   lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, | ||||
|   blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, | ||||
|   domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' }, | ||||
|   mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, | ||||
|   endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' }, | ||||
|   unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, | ||||
|   add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, | ||||
|   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, | ||||
| }); | ||||
| 
 | ||||
| export default @injectIntl | ||||
| class ActionBar extends React.PureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|     account: ImmutablePropTypes.map.isRequired, | ||||
|     onFollow: PropTypes.func, | ||||
|     onBlock: PropTypes.func.isRequired, | ||||
|     onMention: PropTypes.func.isRequired, | ||||
|     onDirect: PropTypes.func.isRequired, | ||||
|     onReblogToggle: PropTypes.func.isRequired, | ||||
|     onReport: PropTypes.func.isRequired, | ||||
|     onMute: PropTypes.func.isRequired, | ||||
|     onBlockDomain: PropTypes.func.isRequired, | ||||
|     onUnblockDomain: PropTypes.func.isRequired, | ||||
|     onEndorseToggle: PropTypes.func.isRequired, | ||||
|     onAddToList: PropTypes.func.isRequired, | ||||
|     intl: PropTypes.object.isRequired, | ||||
|   }; | ||||
| 
 | ||||
|   handleShare = () => { | ||||
|     navigator.share({ | ||||
|       url: this.props.account.get('url'), | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   isStatusesPageActive = (match, location) => { | ||||
|     if (!match) { | ||||
|       return false; | ||||
|     } | ||||
|     return !location.pathname.match(/\/(followers|following)\/?$/); | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { account, intl } = this.props; | ||||
| 
 | ||||
|     let menu = []; | ||||
|     let extraInfo = ''; | ||||
| 
 | ||||
|     if (account.get('id') !== me) { | ||||
|       menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.props.onMention }); | ||||
|       menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.props.onDirect }); | ||||
|       menu.push(null); | ||||
|     } | ||||
| 
 | ||||
|     if ('share' in navigator) { | ||||
|       menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare }); | ||||
|       menu.push(null); | ||||
|     } | ||||
| 
 | ||||
|     if (account.get('id') === me) { | ||||
|       menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' }); | ||||
|       menu.push(null); | ||||
|       menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' }); | ||||
|       menu.push(null); | ||||
|       menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' }); | ||||
|     } else { | ||||
|       if (account.getIn(['relationship', 'following'])) { | ||||
|         if (account.getIn(['relationship', 'showing_reblogs'])) { | ||||
|           menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); | ||||
|         } else { | ||||
|           menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); | ||||
|         } | ||||
| 
 | ||||
|         menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle }); | ||||
|         menu.push({ text: intl.formatMessage(messages.add_or_remove_from_list), action: this.props.onAddToList }); | ||||
|         menu.push(null); | ||||
|       } | ||||
| 
 | ||||
|       if (account.getIn(['relationship', 'muting'])) { | ||||
|         menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.props.onMute }); | ||||
|       } else { | ||||
|         menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.props.onMute }); | ||||
|       } | ||||
| 
 | ||||
|       if (account.getIn(['relationship', 'blocking'])) { | ||||
|         menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.props.onBlock }); | ||||
|       } else { | ||||
|         menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.props.onBlock }); | ||||
|       } | ||||
| 
 | ||||
|       menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.props.onReport }); | ||||
|     } | ||||
| 
 | ||||
|     if (account.get('acct') !== account.get('username')) { | ||||
|       const domain = account.get('acct').split('@')[1]; | ||||
| 
 | ||||
|       extraInfo = ( | ||||
|         <div className='account__disclaimer'> | ||||
|           <FormattedMessage | ||||
|             id='account.disclaimer_full' | ||||
|             defaultMessage="Information below may reflect the user's profile incompletely." | ||||
|           /> | ||||
|           {' '} | ||||
|           <a target='_blank' rel='noopener' href={account.get('url')}> | ||||
|             <FormattedMessage id='account.view_full_profile' defaultMessage='View full profile' /> | ||||
|           </a> | ||||
|         </div> | ||||
|       ); | ||||
| 
 | ||||
|       menu.push(null); | ||||
| 
 | ||||
|       if (account.getIn(['relationship', 'domain_blocking'])) { | ||||
|         menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain }), action: this.props.onUnblockDomain }); | ||||
|       } else { | ||||
|         menu.push({ text: intl.formatMessage(messages.blockDomain, { domain }), action: this.props.onBlockDomain }); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     if (account.get('id') !== me && isStaff) { | ||||
|       menu.push(null); | ||||
|       menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` }); | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|       <div> | ||||
|         {extraInfo} | ||||
| 
 | ||||
|         <div className='account__action-bar'> | ||||
|           <div className='account__action-bar-links'> | ||||
|             <NavLink isActive={this.isStatusesPageActive} activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}`} title={intl.formatNumber(account.get('statuses_count'))}> | ||||
|               <FormattedMessage id='account.posts' defaultMessage='Toots' /> | ||||
|               <strong>{shortNumberFormat(account.get('statuses_count'))}</strong> | ||||
|             </NavLink> | ||||
| 
 | ||||
|             <NavLink exact activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}/following`} title={intl.formatNumber(account.get('following_count'))}> | ||||
|               <FormattedMessage id='account.follows' defaultMessage='Follows' /> | ||||
|               <strong>{shortNumberFormat(account.get('following_count'))}</strong> | ||||
|             </NavLink> | ||||
| 
 | ||||
|             <NavLink exact activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}/followers`} title={intl.formatNumber(account.get('followers_count'))}> | ||||
|               <FormattedMessage id='account.followers' defaultMessage='Followers' /> | ||||
|               <strong>{shortNumberFormat(account.get('followers_count'))}</strong> | ||||
|             </NavLink> | ||||
|           </div> | ||||
| 
 | ||||
|           <div className='account__action-bar-dropdown'> | ||||
|             <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' /> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | @ -2,13 +2,15 @@ import React from 'react'; | |||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; | ||||
| import IconButton from '../../../components/icon_button'; | ||||
| import Motion from '../../ui/util/optional_motion'; | ||||
| import spring from 'react-motion/lib/spring'; | ||||
| import Button from 'mastodon/components/button'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import { autoPlayGif, me } from '../../../initial_state'; | ||||
| import { autoPlayGif, me, isStaff } from 'mastodon/initial_state'; | ||||
| import classNames from 'classnames'; | ||||
| import Icon from 'mastodon/components/icon'; | ||||
| import Avatar from 'mastodon/components/avatar'; | ||||
| import { shortNumberFormat } from 'mastodon/utils/numbers'; | ||||
| import { NavLink } from 'react-router-dom'; | ||||
| import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|   unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, | ||||
|  | @ -18,6 +20,32 @@ const messages = defineMessages({ | |||
|   edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, | ||||
|   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.' }, | ||||
|   mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' }, | ||||
|   direct: { id: 'account.direct', defaultMessage: 'Direct message @{name}' }, | ||||
|   edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, | ||||
|   unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, | ||||
|   unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }, | ||||
|   block: { id: 'account.block', defaultMessage: 'Block @{name}' }, | ||||
|   mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, | ||||
|   report: { id: 'account.report', defaultMessage: 'Report @{name}' }, | ||||
|   share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' }, | ||||
|   media: { id: 'account.media', defaultMessage: 'Media' }, | ||||
|   blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' }, | ||||
|   unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' }, | ||||
|   hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' }, | ||||
|   showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' }, | ||||
|   pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' }, | ||||
|   preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, | ||||
|   follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, | ||||
|   favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, | ||||
|   lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, | ||||
|   blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, | ||||
|   domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' }, | ||||
|   mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, | ||||
|   endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' }, | ||||
|   unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, | ||||
|   add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, | ||||
|   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, | ||||
| }); | ||||
| 
 | ||||
| const dateFormatOptions = { | ||||
|  | @ -29,54 +57,6 @@ const dateFormatOptions = { | |||
|   minute: '2-digit', | ||||
| }; | ||||
| 
 | ||||
| class Avatar extends ImmutablePureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|     account: ImmutablePropTypes.map.isRequired, | ||||
|   }; | ||||
| 
 | ||||
|   state = { | ||||
|     isHovered: false, | ||||
|   }; | ||||
| 
 | ||||
|   handleMouseOver = () => { | ||||
|     if (this.state.isHovered) return; | ||||
|     this.setState({ isHovered: true }); | ||||
|   } | ||||
| 
 | ||||
|   handleMouseOut = () => { | ||||
|     if (!this.state.isHovered) return; | ||||
|     this.setState({ isHovered: false }); | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { account }   = this.props; | ||||
|     const { isHovered } = this.state; | ||||
| 
 | ||||
|     return ( | ||||
|       <Motion defaultStyle={{ radius: 90 }} style={{ radius: spring(isHovered ? 30 : 90, { stiffness: 180, damping: 12 }) }}> | ||||
|         {({ radius }) => ( | ||||
|           <a | ||||
|             href={account.get('url')} | ||||
|             className='account__header__avatar' | ||||
|             role='presentation' | ||||
|             target='_blank' | ||||
|             rel='noopener' | ||||
|             style={{ borderRadius: `${radius}px`, backgroundImage: `url(${autoPlayGif || isHovered ? account.get('avatar') : account.get('avatar_static')})` }} | ||||
|             onMouseOver={this.handleMouseOver} | ||||
|             onMouseOut={this.handleMouseOut} | ||||
|             onFocus={this.handleMouseOver} | ||||
|             onBlur={this.handleMouseOut} | ||||
|           > | ||||
|             <span style={{ display: 'none' }}>{account.get('acct')}</span> | ||||
|           </a> | ||||
|         )} | ||||
|       </Motion> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| export default @injectIntl | ||||
| class Header extends ImmutablePureComponent { | ||||
| 
 | ||||
|  | @ -85,64 +65,57 @@ class Header extends ImmutablePureComponent { | |||
|     onFollow: PropTypes.func.isRequired, | ||||
|     onBlock: PropTypes.func.isRequired, | ||||
|     intl: PropTypes.object.isRequired, | ||||
|     domain: PropTypes.string.isRequired, | ||||
|   }; | ||||
| 
 | ||||
|   openEditProfile = () => { | ||||
|     window.open('/settings/profile', '_blank'); | ||||
|   } | ||||
| 
 | ||||
|   isStatusesPageActive = (match, location) => { | ||||
|     if (!match) { | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     return !location.pathname.match(/\/(followers|following)\/?$/); | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { account, intl } = this.props; | ||||
|     const { account, intl, domain } = this.props; | ||||
| 
 | ||||
|     if (!account) { | ||||
|       return null; | ||||
|     } | ||||
| 
 | ||||
|     let info        = ''; | ||||
|     let mutingInfo  = ''; | ||||
|     let info        = []; | ||||
|     let actionBtn   = ''; | ||||
|     let lockedIcon  = ''; | ||||
|     let menu        = []; | ||||
| 
 | ||||
|     if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) { | ||||
|       info = <span className='account--follows-info'><FormattedMessage id='account.follows_you' defaultMessage='Follows you' /></span>; | ||||
|       info.push(<span className='relationship-tag'><FormattedMessage id='account.follows_you' defaultMessage='Follows you' /></span>); | ||||
|     } else if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) { | ||||
|       info = <span className='account--follows-info'><FormattedMessage id='account.blocked' defaultMessage='Blocked' /></span>; | ||||
|       info.push(<span className='relationship-tag'><FormattedMessage id='account.blocked' defaultMessage='Blocked' /></span>); | ||||
|     } | ||||
| 
 | ||||
|     if (me !== account.get('id') && account.getIn(['relationship', 'muting'])) { | ||||
|       mutingInfo = <span className='account--muting-info'><FormattedMessage id='account.muted' defaultMessage='Muted' /></span>; | ||||
|       info.push(<span className='relationship-tag'><FormattedMessage id='account.muted' defaultMessage='Muted' /></span>); | ||||
|     } else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) { | ||||
|       mutingInfo = <span className='account--muting-info'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain hidden' /></span>; | ||||
|       info.push(<span className='relationship-tag'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain hidden' /></span>); | ||||
|     } | ||||
| 
 | ||||
|     if (me !== account.get('id')) { | ||||
|       if (!account.get('relationship')) { // Wait until the relationship is loaded
 | ||||
|         actionBtn = ''; | ||||
|       } else if (account.getIn(['relationship', 'requested'])) { | ||||
|         actionBtn = ( | ||||
|           <div className='account--action-button'> | ||||
|             <IconButton size={26} active icon='hourglass' title={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} /> | ||||
|           </div> | ||||
|         ); | ||||
|         actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} />; | ||||
|       } else if (!account.getIn(['relationship', 'blocking'])) { | ||||
|         actionBtn = ( | ||||
|           <div className='account--action-button'> | ||||
|             <IconButton size={26} icon={account.getIn(['relationship', 'following']) ? 'user-times' : 'user-plus'} active={account.getIn(['relationship', 'following'])} title={intl.formatMessage(account.getIn(['relationship', 'following']) ? messages.unfollow : messages.follow)} onClick={this.props.onFollow} /> | ||||
|           </div> | ||||
|         ); | ||||
|         actionBtn = <Button className={classNames('logo-button', { 'button--destructive': account.getIn(['relationship', 'following']) })} text={intl.formatMessage(account.getIn(['relationship', 'following']) ? messages.unfollow : messages.follow)} onClick={this.props.onFollow} />; | ||||
|       } else if (account.getIn(['relationship', 'blocking'])) { | ||||
|         actionBtn = ( | ||||
|           <div className='account--action-button'> | ||||
|             <IconButton size={26} icon='unlock' title={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.props.onBlock} /> | ||||
|           </div> | ||||
|         ); | ||||
|         actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.props.onBlock} />; | ||||
|       } | ||||
|     } else { | ||||
|       actionBtn = ( | ||||
|         <div className='account--action-button'> | ||||
|           <IconButton size={26} icon='pencil' title={intl.formatMessage(messages.edit_profile)} onClick={this.openEditProfile} /> | ||||
|         </div> | ||||
|       ); | ||||
|       actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.edit_profile)} onClick={this.openEditProfile} />; | ||||
|     } | ||||
| 
 | ||||
|     if (account.get('moved') && !account.getIn(['relationship', 'following'])) { | ||||
|  | @ -153,40 +126,145 @@ class Header extends ImmutablePureComponent { | |||
|       lockedIcon = <Icon id='lock' title={intl.formatMessage(messages.account_locked)} />; | ||||
|     } | ||||
| 
 | ||||
|     if (account.get('id') !== me) { | ||||
|       menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.props.onMention }); | ||||
|       menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.props.onDirect }); | ||||
|       menu.push(null); | ||||
|     } | ||||
| 
 | ||||
|     if ('share' in navigator) { | ||||
|       menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare }); | ||||
|       menu.push(null); | ||||
|     } | ||||
| 
 | ||||
|     if (account.get('id') === me) { | ||||
|       menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' }); | ||||
|       menu.push(null); | ||||
|       menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' }); | ||||
|       menu.push(null); | ||||
|       menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' }); | ||||
|       menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' }); | ||||
|     } else { | ||||
|       if (account.getIn(['relationship', 'following'])) { | ||||
|         if (account.getIn(['relationship', 'showing_reblogs'])) { | ||||
|           menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); | ||||
|         } else { | ||||
|           menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); | ||||
|         } | ||||
| 
 | ||||
|         menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle }); | ||||
|         menu.push({ text: intl.formatMessage(messages.add_or_remove_from_list), action: this.props.onAddToList }); | ||||
|         menu.push(null); | ||||
|       } | ||||
| 
 | ||||
|       if (account.getIn(['relationship', 'muting'])) { | ||||
|         menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.props.onMute }); | ||||
|       } else { | ||||
|         menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.props.onMute }); | ||||
|       } | ||||
| 
 | ||||
|       if (account.getIn(['relationship', 'blocking'])) { | ||||
|         menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.props.onBlock }); | ||||
|       } else { | ||||
|         menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.props.onBlock }); | ||||
|       } | ||||
| 
 | ||||
|       menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.props.onReport }); | ||||
|     } | ||||
| 
 | ||||
|     if (account.get('acct') !== account.get('username')) { | ||||
|       const domain = account.get('acct').split('@')[1]; | ||||
| 
 | ||||
|       menu.push(null); | ||||
| 
 | ||||
|       if (account.getIn(['relationship', 'domain_blocking'])) { | ||||
|         menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain }), action: this.props.onUnblockDomain }); | ||||
|       } else { | ||||
|         menu.push({ text: intl.formatMessage(messages.blockDomain, { domain }), action: this.props.onBlockDomain }); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     if (account.get('id') !== me && isStaff) { | ||||
|       menu.push(null); | ||||
|       menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` }); | ||||
|     } | ||||
| 
 | ||||
|     const content         = { __html: account.get('note_emojified') }; | ||||
|     const displayNameHtml = { __html: account.get('display_name_html') }; | ||||
|     const fields          = account.get('fields'); | ||||
|     const badge           = account.get('bot') ? (<div className='roles'><div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div></div>) : null; | ||||
|     const badge           = account.get('bot') ? (<div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div>) : null; | ||||
|     const acct            = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct'); | ||||
| 
 | ||||
|     return ( | ||||
|       <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${autoPlayGif ? account.get('header') : account.get('header_static')})` }}> | ||||
|         <div> | ||||
|           <Avatar account={account} /> | ||||
|       <div className={classNames('account__header', { inactive: !!account.get('moved') })}> | ||||
|         <div className='account__header__image'> | ||||
|           <div className='account__header__info'> | ||||
|             {info} | ||||
|           </div> | ||||
| 
 | ||||
|           <span className='account__header__display-name' dangerouslySetInnerHTML={displayNameHtml} /> | ||||
|           <span className='account__header__username'>@{account.get('acct')} {lockedIcon}</span> | ||||
|           <img src={autoPlayGif ? account.get('header') : account.get('header_static')} alt='' className='parallax' /> | ||||
|         </div> | ||||
| 
 | ||||
|           {badge} | ||||
|         <div className='account__header__bar'> | ||||
|           <div className='account__header__tabs'> | ||||
|             <a className='avatar' href={account.get('url')}> | ||||
|               <Avatar account={account} size={90} /> | ||||
|             </a> | ||||
| 
 | ||||
|           <div className='account__header__content' dangerouslySetInnerHTML={content} /> | ||||
|             <div className='spacer' /> | ||||
| 
 | ||||
|           {fields.size > 0 && ( | ||||
|             <div className='account__header__fields'> | ||||
|               {fields.map((pair, i) => ( | ||||
|                 <dl key={i}> | ||||
|                   <dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} /> | ||||
|             <div className='account__header__tabs__buttons'> | ||||
|               <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' /> | ||||
| 
 | ||||
|                   <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') }} /> | ||||
|                   </dd> | ||||
|                 </dl> | ||||
|               ))} | ||||
|               {actionBtn} | ||||
|             </div> | ||||
|           )} | ||||
|           </div> | ||||
| 
 | ||||
|           {info} | ||||
|           {mutingInfo} | ||||
|           {actionBtn} | ||||
|           <div className='account__header__tabs__name'> | ||||
|             <h1> | ||||
|               <span dangerouslySetInnerHTML={displayNameHtml} /> {badge} | ||||
|               <small>@{acct} {lockedIcon}</small> | ||||
|             </h1> | ||||
|           </div> | ||||
| 
 | ||||
|           <div className='account__header__extra'> | ||||
|             <div className='account__header__bio'> | ||||
|               {fields.size > 0 && ( | ||||
|                 <div className='account__header__fields'> | ||||
|                   {fields.map((pair, i) => ( | ||||
|                     <dl 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') }} /> | ||||
|                       </dd> | ||||
|                     </dl> | ||||
|                   ))} | ||||
|                 </div> | ||||
|               )} | ||||
| 
 | ||||
|               {account.get('note').length > 0 && account.get('note') !== '<p></p>' && <div className='account__header__content' dangerouslySetInnerHTML={content} />} | ||||
|             </div> | ||||
| 
 | ||||
|             <div className='account__header__extra__links'> | ||||
|               <NavLink isActive={this.isStatusesPageActive} activeClassName='active' to={`/accounts/${account.get('id')}`} title={intl.formatNumber(account.get('statuses_count'))}> | ||||
|                 <strong>{shortNumberFormat(account.get('statuses_count'))}</strong> <FormattedMessage id='account.posts' defaultMessage='Toots' /> | ||||
|               </NavLink> | ||||
| 
 | ||||
|               <NavLink exact activeClassName='active' to={`/accounts/${account.get('id')}/following`} title={intl.formatNumber(account.get('following_count'))}> | ||||
|                 <strong>{shortNumberFormat(account.get('following_count'))}</strong> <FormattedMessage id='account.follows' defaultMessage='Follows' /> | ||||
|               </NavLink> | ||||
| 
 | ||||
|               <NavLink exact activeClassName='active' to={`/accounts/${account.get('id')}/followers`} title={intl.formatNumber(account.get('followers_count'))}> | ||||
|                 <strong>{shortNumberFormat(account.get('followers_count'))}</strong> <FormattedMessage id='account.followers' defaultMessage='Followers' /> | ||||
|               </NavLink> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ import React from 'react'; | |||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import InnerHeader from '../../account/components/header'; | ||||
| import ActionBar from '../../account/components/action_bar'; | ||||
| import MissingIndicator from '../../../components/missing_indicator'; | ||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||
| import MovedNote from './moved_note'; | ||||
|  | @ -25,6 +24,7 @@ export default class Header extends ImmutablePureComponent { | |||
|     onEndorseToggle: PropTypes.func.isRequired, | ||||
|     onAddToList: PropTypes.func.isRequired, | ||||
|     hideTabs: PropTypes.bool, | ||||
|     domain: PropTypes.string.isRequired, | ||||
|   }; | ||||
| 
 | ||||
|   static contextTypes = { | ||||
|  | @ -98,20 +98,7 @@ export default class Header extends ImmutablePureComponent { | |||
|           account={account} | ||||
|           onFollow={this.handleFollow} | ||||
|           onBlock={this.handleBlock} | ||||
|         /> | ||||
| 
 | ||||
|         <ActionBar | ||||
|           account={account} | ||||
|           onBlock={this.handleBlock} | ||||
|           onMention={this.handleMention} | ||||
|           onDirect={this.handleDirect} | ||||
|           onReblogToggle={this.handleReblogToggle} | ||||
|           onReport={this.handleReport} | ||||
|           onMute={this.handleMute} | ||||
|           onBlockDomain={this.handleBlockDomain} | ||||
|           onUnblockDomain={this.handleUnblockDomain} | ||||
|           onEndorseToggle={this.handleEndorseToggle} | ||||
|           onAddToList={this.handleAddToList} | ||||
|           domain={this.props.domain} | ||||
|         /> | ||||
| 
 | ||||
|         {!hideTabs && ( | ||||
|  |  | |||
|  | @ -33,6 +33,7 @@ const makeMapStateToProps = () => { | |||
| 
 | ||||
|   const mapStateToProps = (state, { accountId }) => ({ | ||||
|     account: getAccount(state, accountId), | ||||
|     domain: state.getIn(['meta', 'domain']), | ||||
|   }); | ||||
| 
 | ||||
|   return mapStateToProps; | ||||
|  |  | |||
|  | @ -1186,57 +1186,6 @@ a .account__avatar { | |||
|   white-space: nowrap; | ||||
| } | ||||
| 
 | ||||
| .account__header { | ||||
|   flex: 0 0 auto; | ||||
|   background: lighten($ui-base-color, 4%); | ||||
|   text-align: center; | ||||
|   background-size: cover; | ||||
|   background-position: center; | ||||
|   position: relative; | ||||
| 
 | ||||
|   &.inactive { | ||||
|     opacity: 0.5; | ||||
| 
 | ||||
|     .account__header__avatar { | ||||
|       filter: grayscale(100%); | ||||
|     } | ||||
| 
 | ||||
|     .account__header__username { | ||||
|       color: $secondary-text-color; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   & > div { | ||||
|     background: rgba(lighten($ui-base-color, 4%), 0.9); | ||||
|     padding: 20px 10px; | ||||
|   } | ||||
| 
 | ||||
|   .account__header__content { | ||||
|     color: $secondary-text-color; | ||||
|   } | ||||
| 
 | ||||
|   .account__header__display-name { | ||||
|     color: $primary-text-color; | ||||
|     display: inline-block; | ||||
|     width: 100%; | ||||
|     font-size: 20px; | ||||
|     line-height: 27px; | ||||
|     font-weight: 500; | ||||
|     overflow: hidden; | ||||
|     text-overflow: ellipsis; | ||||
|   } | ||||
| 
 | ||||
|   .account__header__username { | ||||
|     color: $highlight-text-color; | ||||
|     font-size: 14px; | ||||
|     font-weight: 400; | ||||
|     display: block; | ||||
|     margin-bottom: 10px; | ||||
|     overflow: hidden; | ||||
|     text-overflow: ellipsis; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .account__disclaimer { | ||||
|   padding: 10px; | ||||
|   border-top: 1px solid lighten($ui-base-color, 8%); | ||||
|  | @ -1265,39 +1214,6 @@ a .account__avatar { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .account__header__content { | ||||
|   color: $darker-text-color; | ||||
|   font-size: 14px; | ||||
|   font-weight: 400; | ||||
|   overflow: hidden; | ||||
|   word-break: normal; | ||||
|   word-wrap: break-word; | ||||
| 
 | ||||
|   p { | ||||
|     margin-bottom: 20px; | ||||
| 
 | ||||
|     &:last-child { | ||||
|       margin-bottom: 0; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   a { | ||||
|     color: inherit; | ||||
|     text-decoration: underline; | ||||
| 
 | ||||
|     &:hover { | ||||
|       text-decoration: none; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .account__header__display-name { | ||||
|   .emojione { | ||||
|     width: 25px; | ||||
|     height: 25px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .account__action-bar { | ||||
|   border-top: 1px solid lighten($ui-base-color, 8%); | ||||
|   border-bottom: 1px solid lighten($ui-base-color, 8%); | ||||
|  | @ -1369,15 +1285,6 @@ a .account__avatar { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .account__header__avatar { | ||||
|   background-size: 90px 90px; | ||||
|   display: block; | ||||
|   height: 90px; | ||||
|   margin: 0 auto 10px; | ||||
|   overflow: hidden; | ||||
|   width: 90px; | ||||
| } | ||||
| 
 | ||||
| .account-authorize { | ||||
|   padding: 14px 10px; | ||||
| 
 | ||||
|  | @ -3154,13 +3061,11 @@ a.status-card.compact:hover { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .account--follows-info { | ||||
| .relationship-tag { | ||||
|   color: $primary-text-color; | ||||
|   position: absolute; | ||||
|   top: 10px; | ||||
|   left: 10px; | ||||
|   margin-bottom: 4px; | ||||
|   opacity: 0.7; | ||||
|   display: inline-block; | ||||
|   display: block; | ||||
|   vertical-align: top; | ||||
|   background-color: rgba($base-overlay-background, 0.4); | ||||
|   text-transform: uppercase; | ||||
|  | @ -3170,28 +3075,6 @@ a.status-card.compact:hover { | |||
|   border-radius: 4px; | ||||
| } | ||||
| 
 | ||||
| .account--muting-info { | ||||
|   color: $primary-text-color; | ||||
|   position: absolute; | ||||
|   top: 40px; | ||||
|   left: 10px; | ||||
|   opacity: 0.7; | ||||
|   display: inline-block; | ||||
|   vertical-align: top; | ||||
|   background-color: rgba($base-overlay-background, 0.4); | ||||
|   text-transform: uppercase; | ||||
|   font-size: 11px; | ||||
|   font-weight: 500; | ||||
|   padding: 4px; | ||||
|   border-radius: 4px; | ||||
| } | ||||
| 
 | ||||
| .account--action-button { | ||||
|   position: absolute; | ||||
|   top: 10px; | ||||
|   right: 20px; | ||||
| } | ||||
| 
 | ||||
| .setting-toggle { | ||||
|   display: block; | ||||
|   line-height: 24px; | ||||
|  | @ -5348,53 +5231,188 @@ noscript { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .account__header .roles { | ||||
|   margin-top: 20px; | ||||
|   margin-bottom: 20px; | ||||
|   padding: 0 15px; | ||||
| .account__header__content { | ||||
|   color: $darker-text-color; | ||||
|   font-size: 14px; | ||||
|   font-weight: 400; | ||||
|   overflow: hidden; | ||||
|   word-break: normal; | ||||
|   word-wrap: break-word; | ||||
| 
 | ||||
|   p { | ||||
|     margin-bottom: 20px; | ||||
| 
 | ||||
|     &:last-child { | ||||
|       margin-bottom: 0; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   a { | ||||
|     color: inherit; | ||||
|     text-decoration: underline; | ||||
| 
 | ||||
|     &:hover { | ||||
|       text-decoration: none; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .account__header .account__header__fields { | ||||
|   font-size: 14px; | ||||
|   line-height: 20px; | ||||
| .account__header { | ||||
|   overflow: hidden; | ||||
|   margin: 20px -10px -20px; | ||||
|   border-bottom: 0; | ||||
|   border-top: 0; | ||||
| 
 | ||||
|   dl { | ||||
|     border-top: 1px solid lighten($ui-base-color, 4%); | ||||
|     border-bottom: 0; | ||||
|     display: flex; | ||||
|   &.inactive { | ||||
|     opacity: 0.5; | ||||
| 
 | ||||
|     .account__header__image, | ||||
|     .account__avatar { | ||||
|       filter: grayscale(100%); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   dt, | ||||
|   dd { | ||||
|     box-sizing: border-box; | ||||
|     padding: 14px 5px; | ||||
|     text-align: center; | ||||
|     max-height: 48px; | ||||
|   &__info { | ||||
|     position: absolute; | ||||
|     top: 10px; | ||||
|     left: 10px; | ||||
|   } | ||||
| 
 | ||||
|   &__image { | ||||
|     overflow: hidden; | ||||
|     white-space: nowrap; | ||||
|     text-overflow: ellipsis; | ||||
|   } | ||||
| 
 | ||||
|   dt { | ||||
|     color: $darker-text-color; | ||||
|     height: 145px; | ||||
|     position: relative; | ||||
|     background: darken($ui-base-color, 4%); | ||||
|     width: 120px; | ||||
|     flex: 0 0 auto; | ||||
|     font-weight: 500; | ||||
| 
 | ||||
|     img { | ||||
|       object-fit: cover; | ||||
|       display: block; | ||||
|       width: 100%; | ||||
|       height: 100%; | ||||
|       margin: 0; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   dd { | ||||
|     flex: 1 1 auto; | ||||
|     color: $primary-text-color; | ||||
|     background: $ui-base-color; | ||||
|   &__bar { | ||||
|     position: relative; | ||||
|     background: lighten($ui-base-color, 4%); | ||||
|     padding: 5px; | ||||
|     border-bottom: 1px solid lighten($ui-base-color, 12%); | ||||
| 
 | ||||
|     &.verified { | ||||
|       border: 1px solid rgba($valid-value-color, 0.5); | ||||
|       background: rgba($valid-value-color, 0.25); | ||||
|     .avatar { | ||||
|       display: block; | ||||
|       flex: 0 0 auto; | ||||
|       width: 90px; | ||||
|       margin-left: -2px; | ||||
| 
 | ||||
|       .account__avatar { | ||||
|         border: 2px solid lighten($ui-base-color, 4%); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &__tabs { | ||||
|     display: flex; | ||||
|     align-items: flex-start; | ||||
|     padding: 7px 5px; | ||||
|     margin-top: -55px; | ||||
| 
 | ||||
|     &__buttons { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       padding-top: 55px; | ||||
| 
 | ||||
|       .icon-button { | ||||
|         border: 1px solid lighten($ui-base-color, 12%); | ||||
|         border-radius: 4px; | ||||
|         box-sizing: content-box; | ||||
|         padding: 2px; | ||||
|         margin: 0 8px; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &__name { | ||||
|       padding: 5px; | ||||
| 
 | ||||
|       .account-role { | ||||
|         vertical-align: top; | ||||
|       } | ||||
| 
 | ||||
|       .emojione { | ||||
|         width: 22px; | ||||
|         height: 22px; | ||||
|       } | ||||
| 
 | ||||
|       h1 { | ||||
|         font-size: 16px; | ||||
|         line-height: 24px; | ||||
|         color: $primary-text-color; | ||||
|         font-weight: 500; | ||||
|         overflow: hidden; | ||||
|         white-space: nowrap; | ||||
|         text-overflow: ellipsis; | ||||
| 
 | ||||
|         small { | ||||
|           display: block; | ||||
|           font-size: 14px; | ||||
|           color: $darker-text-color; | ||||
|           font-weight: 400; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     .spacer { | ||||
|       flex: 1 1 auto; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &__bio { | ||||
|     overflow: hidden; | ||||
|     margin: 0 -5px; | ||||
| 
 | ||||
|     .account__header__content { | ||||
|       padding: 20px 15px; | ||||
|       padding-bottom: 5px; | ||||
|       color: $primary-text-color; | ||||
|     } | ||||
| 
 | ||||
|     .account__header__fields { | ||||
|       margin: 0; | ||||
|       border-top: 1px solid lighten($ui-base-color, 12%); | ||||
| 
 | ||||
|       a { | ||||
|         color: lighten($ui-highlight-color, 8%); | ||||
|       } | ||||
| 
 | ||||
|       dl:first-child .verified { | ||||
|         border-radius: 0 4px 0 0; | ||||
|       } | ||||
| 
 | ||||
|       .verified a { | ||||
|         color: $valid-value-color; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &__extra { | ||||
|     margin-top: 4px; | ||||
| 
 | ||||
|     &__links { | ||||
|       font-size: 14px; | ||||
|       color: $darker-text-color; | ||||
| 
 | ||||
|       a { | ||||
|         display: inline-block; | ||||
|         color: $darker-text-color; | ||||
|         text-decoration: none; | ||||
|         padding: 10px; | ||||
|         padding-top: 20px; | ||||
|         font-weight: 500; | ||||
| 
 | ||||
|         strong { | ||||
|           font-weight: 700; | ||||
|           color: $primary-text-color; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -677,6 +677,7 @@ | |||
|           color: $darker-text-color; | ||||
|           text-decoration: none; | ||||
|           padding: 15px; | ||||
|           font-weight: 500; | ||||
| 
 | ||||
|           strong { | ||||
|             font-weight: 700; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue