Skip to content

Commit

Permalink
Show boosted user's avatar (mastodon#2518)
Browse files Browse the repository at this point in the history
* Show boosted user's avatar

* add .status__avatar-boost

* margin

* apply to notifications too.

* account__avatar-boost

* Add inline prop to Avatar component

* Add AvatarOverlay component

* rename mixins.scss

* move files for latest master

* fixed for webpack
  • Loading branch information
kawax authored and Gargron committed May 3, 2017
1 parent bf8031e commit 383c0b7
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 15 deletions.
17 changes: 13 additions & 4 deletions app/javascript/mastodon/components/avatar.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ class Avatar extends React.PureComponent {
}

render () {
const { src, size, staticSrc, animate } = this.props;
const { src, size, staticSrc, animate, inline } = this.props;
const { hovering } = this.state;

let className = 'account__avatar';

if (inline) {
className = className + ' account__avatar-inline';
}

const style = {
...this.props.style,
width: `${size}px`,
Expand All @@ -43,7 +49,7 @@ class Avatar extends React.PureComponent {

return (
<div
className='account__avatar'
className={className}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
style={style}
Expand All @@ -58,11 +64,14 @@ Avatar.propTypes = {
staticSrc: PropTypes.string,
size: PropTypes.number.isRequired,
style: PropTypes.object,
animate: PropTypes.bool
animate: PropTypes.bool,
inline: PropTypes.bool
};

Avatar.defaultProps = {
animate: false
animate: false,
size: 20,
inline: false
};

export default Avatar;
30 changes: 30 additions & 0 deletions app/javascript/mastodon/components/avatar_overlay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';

class AvatarOverlay extends React.PureComponent {
render() {
const {staticSrc, overlaySrc} = this.props;

const baseStyle = {
backgroundImage: `url(${staticSrc})`
};

const overlayStyle = {
backgroundImage: `url(${overlaySrc})`
};

return (
<div className='account__avatar-overlay'>
<div className="account__avatar-overlay-base" style={baseStyle} />
<div className="account__avatar-overlay-overlay" style={overlayStyle} />
</div>
);
}
}

AvatarOverlay.propTypes = {
staticSrc: PropTypes.string.isRequired,
overlaySrc: PropTypes.string.isRequired,
};

export default AvatarOverlay;
15 changes: 12 additions & 3 deletions app/javascript/mastodon/components/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Avatar from './avatar';
import AvatarOverlay from './avatar_overlay';
import RelativeTimestamp from './relative_timestamp';
import DisplayName from './display_name';
import MediaGallery from './media_gallery';
Expand Down Expand Up @@ -36,7 +37,8 @@ class Status extends ImmutablePureComponent {

render () {
let media = '';
const { status, ...other } = this.props;
let statusAvatar;
const { status, account, ...other } = this.props;

if (status === null) {
return <div />;
Expand All @@ -58,7 +60,7 @@ class Status extends ImmutablePureComponent {
<FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name muted'><strong dangerouslySetInnerHTML={displayNameHTML} /></a> }} />
</div>

<Status {...other} wrapped={true} status={status.get('reblog')} />
<Status {...other} wrapped={true} status={status.get('reblog')} account={status.get('account')} />
</div>
);
}
Expand All @@ -73,6 +75,12 @@ class Status extends ImmutablePureComponent {
}
}

if (account === undefined || account === null) {
statusAvatar = <Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48}/>;
}else{
statusAvatar = <AvatarOverlay staticSrc={status.getIn(['account', 'avatar_static'])} overlaySrc={account.get('avatar_static')} />;
}

return (
<div className={this.props.muted ? 'status muted' : 'status'}>
<div className='status__info'>
Expand All @@ -82,7 +90,7 @@ class Status extends ImmutablePureComponent {

<a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name'>
<div className='status__avatar'>
<Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />
{statusAvatar}
</div>

<DisplayName account={status.get('account')} />
Expand All @@ -106,6 +114,7 @@ Status.contextTypes = {

Status.propTypes = {
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
wrapped: PropTypes.bool,
onReply: PropTypes.func,
onFavourite: PropTypes.func,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import StatusContainer from '../../../containers/status_container';
import AccountContainer from '../../../containers/account_container';
import Avatar from '../../../components/avatar';
import { FormattedMessage } from 'react-intl';
import Permalink from '../../../components/permalink';
import emojify from '../../../emoji';
Expand Down Expand Up @@ -37,11 +38,10 @@ class Notification extends ImmutablePureComponent {
<div className='notification__favourite-icon-wrapper'>
<i className='fa fa-fw fa-star star-icon'/>
</div>

<FormattedMessage id='notification.favourite' defaultMessage='{name} favourited your status' values={{ name: link }} />
</div>

<StatusContainer id={notification.get('status')} muted={true} />
<StatusContainer id={notification.get('status')} account={notification.get('account')} muted={true} />
</div>
);
}
Expand All @@ -53,11 +53,10 @@ class Notification extends ImmutablePureComponent {
<div className='notification__favourite-icon-wrapper'>
<i className='fa fa-fw fa-retweet' />
</div>

<FormattedMessage id='notification.reblog' defaultMessage='{name} boosted your status' values={{ name: link }} />
</div>

<StatusContainer id={notification.get('status')} muted={true} />
<StatusContainer id={notification.get('status')} account={notification.get('account')} muted={true} />
</div>
);
}
Expand Down
12 changes: 12 additions & 0 deletions app/javascript/styles/_mixins.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@mixin avatar-radius() {
border-radius: 4px;
background: transparent no-repeat;
background-position: 50%;
background-clip: padding-box;
}

@mixin avatar-size($size:48px) {
width: $size;
height: $size;
background-size: $size $size;
}
1 change: 1 addition & 0 deletions app/javascript/styles/application.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@import 'mixins';
@import 'variables';
@import 'fonts/roboto';
@import 'fonts/roboto-mono';
Expand Down
30 changes: 26 additions & 4 deletions app/javascript/styles/components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -673,11 +673,33 @@ a.status__content__spoiler-link {
}

.account__avatar {
border-radius: 4px;
background: transparent no-repeat;
background-position: 50%;
background-clip: padding-box;
@include avatar-radius();
position: relative;

&-inline {
display: inline-block;
vertical-align: middle;
margin-right: 5px;
}
}

.account__avatar-overlay {
@include avatar-size(48px);

&-base {
@include avatar-radius();
@include avatar-size(36px);
}

&-overlay {
@include avatar-radius();
@include avatar-size(24px);

position: absolute;
bottom: 0;
right: 0;
z-index: 1;
}
}

.account__relationship {
Expand Down

0 comments on commit 383c0b7

Please sign in to comment.