Make avatars into links to the user profile page

This commit is contained in:
Kimmo Puputti 2017-11-07 11:18:23 +02:00
parent 130d0a5504
commit 807c5005ed
10 changed files with 63 additions and 17 deletions

View file

@ -18,6 +18,10 @@
/* Colors */
background-image: linear-gradient(-180deg, #e16b56 0%, #c0392b 100%);
color: var(--matterColorLight);
&:hover {
text-decoration: none;
}
}
}

View file

@ -171,3 +171,13 @@ export const WithProfileImageUserLarge = {
},
group: 'avatar',
};
export const WithoutProfileLink = {
component: AvatarLarge,
props: {
user: userWithProfileImage,
disableProfileLink: true,
intl: fakeIntl,
},
group: 'avatar',
};

View file

@ -4,12 +4,12 @@ import { injectIntl, intlShape } from 'react-intl';
import classNames from 'classnames';
import * as propTypes from '../../util/propTypes';
import { ensureUser, userDisplayName, userAbbreviatedName } from '../../util/data';
import { ResponsiveImage, IconBannedUser } from '../../components/';
import { ResponsiveImage, IconBannedUser, NamedLink } from '../../components/';
import css from './Avatar.css';
export const AvatarComponent = props => {
const { rootClassName, className, user, intl } = props;
const { rootClassName, className, user, disableProfileLink, intl } = props;
const classes = classNames(rootClassName || css.root, className);
const avatarUser = ensureUser(user);
const isBannedUser = avatarUser.attributes.banned;
@ -21,10 +21,35 @@ export const AvatarComponent = props => {
const displayName = userDisplayName(avatarUser, bannedUserDisplayName);
const abbreviatedName = userAbbreviatedName(avatarUser, bannedUserAbbreviatedName);
const rootProps = { className: classes, title: displayName };
const linkProps = avatarUser.id
? { name: 'ProfilePage', params: { id: avatarUser.id.uuid } }
: { name: 'ProfileBasePage' };
const hasProfileImage = avatarUser.profileImage && avatarUser.profileImage.id;
if (avatarUser.profileImage && avatarUser.profileImage.id) {
if (isBannedUser) {
return (
<div className={classes} title={displayName}>
<div {...rootProps}>
<IconBannedUser className={css.bannedUserIcon} />
</div>
);
} else if (hasProfileImage && !disableProfileLink) {
return (
<NamedLink {...rootProps} {...linkProps}>
<ResponsiveImage
rootClassName={css.avatarImage}
alt={displayName}
image={avatarUser.profileImage}
nameSet={[
{ name: 'square-xlarge2x', size: '1x' },
{ name: 'square-xlarge4x', size: '2x' },
]}
/>
</NamedLink>
);
} else if (hasProfileImage) {
return (
<div {...rootProps}>
<ResponsiveImage
rootClassName={css.avatarImage}
alt={displayName}
@ -36,35 +61,39 @@ export const AvatarComponent = props => {
/>
</div>
);
} else if (isBannedUser) {
} else if (!disableProfileLink) {
// Placeholder avatar (initials)
return (
<div className={classes} title={displayName}>
<IconBannedUser className={css.bannedUserIcon} />
</div>
<NamedLink {...rootProps} {...linkProps}>
<span className={css.initials}>{abbreviatedName}</span>
</NamedLink>
);
} else {
// Placeholder avatar (initials)
return (
<div className={classes} title={displayName}>
<div {...rootProps}>
<span className={css.initials}>{abbreviatedName}</span>
</div>
);
}
};
const { string, oneOfType } = PropTypes;
AvatarComponent.defaultProps = {
className: null,
rootClassName: null,
user: null,
disableProfileLink: false,
};
const { string, oneOfType, bool } = PropTypes;
AvatarComponent.propTypes = {
rootClassName: string,
className: string,
user: oneOfType([propTypes.user, propTypes.currentUser]),
disableProfileLink: bool,
// from injectIntl
intl: intlShape.isRequired,
};

View file

@ -69,7 +69,7 @@ const TopbarDesktop = props => {
const profileMenu = isAuthenticated ? (
<Menu>
<MenuLabel className={css.profileMenuLabel} isOpenClassName={css.profileMenuIsOpen}>
<Avatar className={css.avatar} user={currentUser} />
<Avatar className={css.avatar} user={currentUser} disableProfileLink />
</MenuLabel>
<MenuContent className={css.profileMenuContent}>
<MenuItem key="ManageListingsPage">

View file

@ -293,7 +293,7 @@ export class CheckoutPageComponent extends Component {
/>
</div>
<div className={classNames(css.avatarWrapper, css.avatarMobile)}>
<AvatarMedium user={currentAuthor} />
<AvatarMedium user={currentAuthor} disableProfileLink />
</div>
<div className={css.bookListingContainer}>
<div className={css.heading}>
@ -348,7 +348,7 @@ export class CheckoutPageComponent extends Component {
/>
</div>
<div className={css.avatarWrapper}>
<AvatarMedium user={currentAuthor} />
<AvatarMedium user={currentAuthor} disableProfileLink />
</div>
<div className={css.detailsHeadings}>
<h2 className={css.detailsTitle}>{listingTitle}</h2>

View file

@ -49,6 +49,7 @@ exports[`CheckoutPage matches snapshot 1`] = `
className=""
>
<AvatarMedium
disableProfileLink={true}
user={
Object {
"attributes": Object {
@ -132,6 +133,7 @@ exports[`CheckoutPage matches snapshot 1`] = `
</div>
<div>
<AvatarMedium
disableProfileLink={true}
user={
Object {
"attributes": Object {

View file

@ -133,7 +133,7 @@ export const InboxItem = props => {
params={{ id: tx.id.uuid }}
>
<div className={css.itemAvatar}>
<Avatar user={otherUser} />
<Avatar user={otherUser} disableProfileLink />
</div>
<div className={css.rowNotificationDot}>{rowNotificationDot}</div>
<div className={css.itemInfo}>

View file

@ -61,7 +61,7 @@ export const ProfilePageComponent = props => {
const asideContent = (
<div className={css.asideContent}>
<AvatarLarge className={css.avatar} user={user} />
<AvatarLarge className={css.avatar} user={user} disableProfileLink />
<h1 className={css.mobileHeading}>
{displayName ? (
<FormattedMessage id="ProfilePage.mobileHeading" values={{ name: displayName }} />

View file

@ -32,6 +32,7 @@ exports[`ProfilePage matches snapshot 1`] = `
>
<div>
<AvatarLarge
disableProfileLink={true}
user={
Object {
"attributes": Object {

View file

@ -191,7 +191,7 @@ class ProfileSettingsFormComponent extends Component {
});
const avatarComponent =
!fileUploadInProgress && profileImage.imageId ? (
<Avatar className={avatarClasses} user={transientUser} />
<Avatar className={avatarClasses} user={transientUser} disableProfileLink />
) : null;
const chooseAvatarLabel =