Merge remote-tracking branch 'soapbox/develop' into birthdays
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
||||
import { debounce } from 'lodash';
|
||||
import { debounce, throttle } from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
@ -13,8 +13,11 @@ import { NavLink } from 'react-router-dom';
|
||||
|
||||
import { openModal } from 'soapbox/actions/modal';
|
||||
import Avatar from 'soapbox/components/avatar';
|
||||
import Badge from 'soapbox/components/badge';
|
||||
import Icon from 'soapbox/components/icon';
|
||||
import IconButton from 'soapbox/components/icon_button';
|
||||
import StillImage from 'soapbox/components/still_image';
|
||||
import VerificationBadge from 'soapbox/components/verification_badge';
|
||||
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
|
||||
import ActionButton from 'soapbox/features/ui/components/action_button';
|
||||
import SubscriptionButton from 'soapbox/features/ui/components/subscription_button';
|
||||
@ -29,8 +32,10 @@ import {
|
||||
isRemote,
|
||||
getDomain,
|
||||
} from 'soapbox/utils/accounts';
|
||||
import { getAcct } from 'soapbox/utils/accounts';
|
||||
import { getFeatures } from 'soapbox/utils/features';
|
||||
import { shortNumberFormat } from 'soapbox/utils/numbers';
|
||||
import { displayFqn } from 'soapbox/utils/state';
|
||||
|
||||
const messages = defineMessages({
|
||||
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
||||
@ -71,6 +76,8 @@ const messages = defineMessages({
|
||||
unsubscribe: { id: 'account.unsubscribe', defaultMessage: 'Unsubscribe to notifications from @{name}' },
|
||||
suggestUser: { id: 'admin.users.actions.suggest_user', defaultMessage: 'Suggest @{name}' },
|
||||
unsuggestUser: { id: 'admin.users.actions.unsuggest_user', defaultMessage: 'Unsuggest @{name}' },
|
||||
deactivated: { id: 'account.deactivated', defaultMessage: 'Deactivated' },
|
||||
bot: { id: 'account.badges.bot', defaultMessage: 'Bot' },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => {
|
||||
@ -83,6 +90,8 @@ const mapStateToProps = state => {
|
||||
me,
|
||||
meAccount: account,
|
||||
features,
|
||||
displayFqn: displayFqn(state),
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@ -97,10 +106,12 @@ class Header extends ImmutablePureComponent {
|
||||
intl: PropTypes.object.isRequired,
|
||||
username: PropTypes.string,
|
||||
features: PropTypes.object,
|
||||
displayFqn: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
isSmallScreen: (window.innerWidth <= 895),
|
||||
isLocked: false,
|
||||
}
|
||||
|
||||
isStatusesPageActive = (match, location) => {
|
||||
@ -112,19 +123,34 @@ class Header extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('scroll', this.handleScroll);
|
||||
window.addEventListener('resize', this.handleResize, { passive: true });
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('scroll', this.handleScroll);
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
}
|
||||
|
||||
setRef = (c) => {
|
||||
this.node = c;
|
||||
}
|
||||
|
||||
handleResize = debounce(() => {
|
||||
this.setState({ isSmallScreen: (window.innerWidth <= 895) });
|
||||
}, 5, {
|
||||
trailing: true,
|
||||
});
|
||||
|
||||
handleScroll = throttle(() => {
|
||||
const { top } = this.node.getBoundingClientRect();
|
||||
const isLocked = top <= 60;
|
||||
|
||||
if (this.state.isLocked !== isLocked) {
|
||||
this.setState({ isLocked });
|
||||
}
|
||||
}, 100, { trailing: true });
|
||||
|
||||
onAvatarClick = () => {
|
||||
const avatar_url = this.props.account.get('avatar');
|
||||
const avatar = ImmutableMap({
|
||||
@ -515,16 +541,18 @@ class Header extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { account, intl, username, me, features } = this.props;
|
||||
const { isSmallScreen } = this.state;
|
||||
const { account, displayFqn, intl, username, me, features } = this.props;
|
||||
const { isSmallScreen, isLocked } = this.state;
|
||||
|
||||
if (!account) {
|
||||
return (
|
||||
<div className='account__header'>
|
||||
<div className='account__header__image account__header__image--none' />
|
||||
<div className='account__header__bar'>
|
||||
<div className='account__header__bar' ref={this.setRef}>
|
||||
<div className='account__header__extra'>
|
||||
<div className='account__header__avatar' />
|
||||
<div className='account__header__card'>
|
||||
<div className='account__header__avatar' />
|
||||
</div>
|
||||
</div>
|
||||
{isSmallScreen && (
|
||||
<div className='account-mobile-container account-mobile-container--nonuser'>
|
||||
@ -547,6 +575,9 @@ class Header extends ImmutablePureComponent {
|
||||
const avatarSize = isSmallScreen ? 90 : 200;
|
||||
const deactivated = !account.getIn(['pleroma', 'is_active'], true);
|
||||
|
||||
const displayNameHtml = deactivated ? { __html: intl.formatMessage(messages.deactivated) } : { __html: account.get('display_name_html') };
|
||||
const verified = account.getIn(['pleroma', 'tags'], ImmutableList()).includes('verified');
|
||||
|
||||
return (
|
||||
<div className={classNames('account__header', { inactive: !!account.get('moved'), deactivated: deactivated })}>
|
||||
<div className={classNames('account__header__image', { /* 'account__header__image--none': headerMissing || deactivated */ })}>
|
||||
@ -563,12 +594,28 @@ class Header extends ImmutablePureComponent {
|
||||
</div>}
|
||||
</div>
|
||||
|
||||
<div className='account__header__bar'>
|
||||
<div className='account__header__bar' ref={this.setRef}>
|
||||
<div className='account__header__extra'>
|
||||
|
||||
<a className='account__header__avatar' href={account.get('avatar')} onClick={this.handleAvatarClick} target='_blank'>
|
||||
<Avatar account={account} size={avatarSize} />
|
||||
</a>
|
||||
<div className={classNames('account__header__card', { 'is-locked': !isSmallScreen && isLocked })}>
|
||||
<a className='account__header__avatar' href={account.get('avatar')} onClick={this.handleAvatarClick} target='_blank' aria-hidden={!isSmallScreen && isLocked}>
|
||||
<Avatar account={account} size={avatarSize} />
|
||||
</a>
|
||||
<div className='account__header__name' aria-hidden={isSmallScreen || !isLocked}>
|
||||
<Avatar account={account} size={40} />
|
||||
<div>
|
||||
<span dangerouslySetInnerHTML={displayNameHtml} className={classNames('profile-info-panel__name-content', { 'with-badge': verified })} />
|
||||
{verified && <VerificationBadge />}
|
||||
{account.get('bot') && <Badge slug='bot' title={intl.formatMessage(messages.bot)} />}
|
||||
<small>
|
||||
@{getAcct(account, displayFqn)}
|
||||
{account.get('locked') && (
|
||||
<Icon src={require('@tabler/icons/icons/lock.svg')} title={intl.formatMessage(messages.account_locked)} />
|
||||
)}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='account__header__extra__links'>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user