Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/_colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ $ui-light-primary-transparent: hsla(215, 100%, 95%, 0);

$ui-border: hsla(0, 0%, 85%, 1); //#D9D9D9
$ui-border-light-blue: hsla(215, 50%, 90%, 1); //#D9E3F2
$ui-border-orange: hsla(37, 96%, 55%, 1); // #FAA51D

/* modals */
$ui-mint-green: hsl(163, 69%, 44%);
Expand Down
20 changes: 15 additions & 5 deletions src/components/avatar/avatar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@ const classNames = require('classnames');
const PropTypes = require('prop-types');
const React = require('react');

require('./avatar.scss');

const Avatar = ({
className,
src = '//uploads.scratch.mit.edu/get_image/user/2584924_24x24.png?v=1438702210.96',
showAvatarBadge = false,
...rest
}) => (
<img
className={classNames('avatar', className)}
src={src}
{...rest}
/>
<div className={classNames('avatar-wrapper', showAvatarBadge && 'avatar-badge-wrapper')}>
<img
className={classNames(
'avatar',
showAvatarBadge && 'avatar-badge',
className
)}
src={src}
{...rest}
/>
</div>
);

Avatar.propTypes = {
showAvatarBadge: PropTypes.bool,
className: PropTypes.string,
src: PropTypes.string
};
Expand Down
33 changes: 32 additions & 1 deletion src/components/avatar/avatar.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
@use "../../colors";

.avatar-wrapper {
--avatar-size: 1.5rem;
--frame-size: 0;

display: inline-block;
width: var(--avatar-size);
}

.avatar {
border: 1px solid $ui-border;
width: var(--avatar-size);
height: var(--avatar-size);
}

// The selector must be as specific as possible, because the border-radius is often overridden
div.avatar-wrapper.avatar-badge-wrapper img.avatar.avatar-badge {
// On larger sized avatars the border doesn't scale well, so we either have to calculate it based on the size
// or overwrite it for each avatar size
border: calc(var(--avatar-size) * 0.042) solid colors.$ui-border-orange;
box-sizing: border-box;
border-radius: 17%;
box-shadow: none;
}

.avatar-badge-wrapper {
display: inline-block;
width: var(--avatar-size);
height: calc(var(--avatar-size) + var(--frame-size));
align-content: end;

background: url("/svgs/membership/cat-ears.svg") no-repeat top;
background-size: contain;
}
1 change: 1 addition & 0 deletions src/components/grid/grid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
return (
<Thumbnail
avatar={thumbnailUrl(item.author.id)}
showAvatarBadge={!!item.author.profile.membership_avatar_badge}
creator={item.author.username}
favorites={item.stats.favorites}
href={href}
Expand Down Expand Up @@ -81,7 +82,7 @@
Grid.propTypes = {
className: PropTypes.string,
itemType: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.object),

Check warning on line 85 in src/components/grid/grid.jsx

View workflow job for this annotation

GitHub Actions / Build and Unit Tests

Prop type "object" is forbidden
showAvatar: PropTypes.bool,
showFavorites: PropTypes.bool,
showLoves: PropTypes.bool,
Expand Down
13 changes: 9 additions & 4 deletions src/components/grid/grid.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,25 @@
.thumbnail-info {
margin: 0 auto;
width: $thumbnail-inner-width;

.creator-image {
float: left;

img {
margin-right: 8px;
border-radius: 4px;
width: 32px;
height: 32px;
display: block;
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
}

.avatar-wrapper {
--avatar-size: 32px;
--frame-size: 9px;

height: calc(var(--avatar-size) + var(--frame-size));
margin-right: 8px;
}
}

.thumbnail-title {
Expand Down
7 changes: 5 additions & 2 deletions src/components/navigation/www/accountnav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const AccountNav = ({
username,
onClick,
onClickLogout,
onClose
onClose,
avatarBadge
}) => (
<div className="account-nav">
<a
Expand All @@ -34,6 +35,7 @@ const AccountNav = ({
<Avatar
alt=""
src={thumbnailUrl}
showAvatarBadge={avatarBadge}
/>
<span className="profile-name">
{username}
Expand Down Expand Up @@ -96,7 +98,8 @@ AccountNav.propTypes = {
onClose: PropTypes.func,
profileUrl: PropTypes.string,
thumbnailUrl: PropTypes.string,
username: PropTypes.string
username: PropTypes.string,
avatarBadge: PropTypes.number
};

module.exports = injectIntl(AccountNav);
12 changes: 9 additions & 3 deletions src/components/navigation/www/accountnav.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@
font-weight: normal;

.avatar {
margin-right: 10px;
border-radius: 3px;
width: 24px;
height: 24px;
vertical-align: middle;
}

.avatar-wrapper {
margin-right: 10px;
// A bit hacky, but the parent component has a padding of 14px, which pushes the whole content when the ears appear
margin-top: -7px;

--avatar-size: 24px;
--frame-size: 7px;
}

&:hover {
background-color: colors.$active-gray;
}
Expand Down
4 changes: 3 additions & 1 deletion src/components/navigation/www/navigation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class Navigation extends React.Component {
onClick={this.props.handleToggleAccountNav}
onClickLogout={this.props.handleLogOut}
onClose={this.props.handleCloseAccountNav}
avatarBadge={this.props.user.membership_avatar_badge}
/>
</li>
] : [
Expand Down Expand Up @@ -272,7 +273,8 @@ Navigation.propTypes = {
user: PropTypes.shape({
classroomId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
thumbnailUrl: PropTypes.string,
username: PropTypes.string
username: PropTypes.string,
membership_avatar_badge: PropTypes.number
})
};

Expand Down
1 change: 1 addition & 0 deletions src/components/registration/steps.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,7 @@ class ClassInviteNewStudentStep extends React.Component {
className="invite-avatar"
key="avatar"
src={this.props.classroom.educator.profile.images['50x50']}
// TODO: Should we display the avatar badge here as well?
/>,
<h2 key="username">{this.props.classroom.educator.username}</h2>,
<p
Expand Down
6 changes: 5 additions & 1 deletion src/components/thumbnail/thumbnail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const React = require('react');
require('./thumbnail.scss');

const ThumbnailRemoveButton = require('./thumbnail-remove-button.jsx');
const Avatar = require('../avatar/avatar.jsx');

const Thumbnail = ({
alt = '',
Expand All @@ -23,6 +24,7 @@ const Thumbnail = ({
showRemixes = false,
showRemoveButton = false,
showViews = false,
showAvatarBadge = false,
src = '',
title = 'Project',
type = 'project',
Expand Down Expand Up @@ -126,9 +128,10 @@ const Thumbnail = ({
className="creator-image"
href={`/users/${creator}/`}
>
<img
<Avatar
alt={creator}
src={avatar}
showAvatarBadge={showAvatarBadge}
/>
</a>
);
Expand Down Expand Up @@ -173,6 +176,7 @@ Thumbnail.propTypes = {
showRemixes: PropTypes.bool,
showViews: PropTypes.bool,
showRemoveButton: PropTypes.bool,
showAvatarBadge: PropTypes.bool,
src: PropTypes.string,
title: PropTypes.string,
type: PropTypes.string,
Expand Down
1 change: 1 addition & 0 deletions src/components/thumbnailcolumn/thumbnailcolumn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const ThumbnailColumn = ({
showLoves={showLoves}
showRemixes={showRemixes}
showViews={showViews}
showAvatarBadge={!!item.author.profile.membership_avatar_badge}
src={item.image}
title={item.title}
type={'project'}
Expand Down
5 changes: 4 additions & 1 deletion src/views/messages/message-rows/comment-message.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const intlShape = require('../../../lib/intl-shape');
const Comment = require('../../../components/comment/comment.jsx');
const FlexRow = require('../../../components/flex-row/flex-row.jsx');
const SocialMessage = require('../../../components/social-message/social-message.jsx');
const Avatar = require('../../../components/avatar/avatar.jsx');
const thumbnailUrl = require('../../../lib/user-thumbnail');

class CommentMessage extends React.Component {
Expand Down Expand Up @@ -162,10 +163,11 @@ class CommentMessage extends React.Component {
</p>
<FlexRow className="mod-comment-message">
<a href={`/users/${this.props.actorUsername}/`}>
<img
<Avatar
alt={`${this.props.actorUsername}'s avatar`}
className="comment-message-info-img"
src={thumbnailUrl(this.props.actorId)}
showAvatarBadge={!!this.props.actorAvatarBadge}
/>
</a>
<Comment
Expand All @@ -180,6 +182,7 @@ class CommentMessage extends React.Component {
CommentMessage.propTypes = {
actorId: PropTypes.number.isRequired,
actorUsername: PropTypes.string.isRequired,
actorAvatarBadge: PropTypes.number,
className: PropTypes.string,
commentDateTime: PropTypes.string.isRequired,
commentId: PropTypes.number.isRequired,
Expand Down
6 changes: 3 additions & 3 deletions src/views/messages/messages.scss
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@
text-align: left;
}

.comment-message-info-img {
width: 40px;
height: 40px;
.flex-row.mod-comment-message .avatar-wrapper {
--avatar-size: 40px;
--frame-size: 18px;
}

.messages-social-loadmore {
Expand Down
1 change: 1 addition & 0 deletions src/views/messages/presentation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class SocialMessagesList extends React.Component {
<CommentMessage
actorId={message.actor_id}
actorUsername={message.actor_username}
actorAvatarBadge={message.actor_membership_avatar_badge}
className={className}
commentDateTime={message.datetime_created}
commentId={message.comment_id}
Expand Down
8 changes: 6 additions & 2 deletions src/views/preview/comment/comment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ class Comment extends React.Component {
ref={this.setRef}
>
<a href={`/users/${author.username}`}>
<Avatar src={author.image} />
<Avatar
src={author.image}
showAvatarBadge={!!author.membership_avatar_badge}
/>
</a>
<FlexRow className="comment-body column">
<FlexRow className="comment-top-row">
Expand Down Expand Up @@ -278,7 +281,8 @@ Comment.propTypes = {
id: PropTypes.number,
image: PropTypes.string,
scratchteam: PropTypes.bool,
username: PropTypes.string
username: PropTypes.string,
membership_avatar_badge: PropTypes.number
}),
canDelete: PropTypes.bool,
canDeleteWithoutConfirm: PropTypes.bool,
Expand Down
10 changes: 7 additions & 3 deletions src/views/preview/comment/comment.scss
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,15 @@
}

.avatar {
margin-right: .5rem;
border-radius: 4px;
box-shadow: 0px 0px 0px 1px rgba(77, 151, 255, 0.25);
width: 3rem;
height: 3rem;
}

.avatar-wrapper {
margin-right: .5rem;

--avatar-size: 3rem;
--frame-size: 1.1rem;
}

.comment-body {
Expand Down
8 changes: 6 additions & 2 deletions src/views/preview/comment/compose-comment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,10 @@ class ComposeComment extends React.Component {
'compose-disabled' : 'compose-row')}
>
<a href={`/users/${this.props.user.username}`}>
<Avatar src={this.props.user.thumbnailUrl} />
<Avatar
src={this.props.user.thumbnailUrl}
showAvatarBadge={!!this.props.user.membership_avatar_badge}
/>
</a>
<FlexRow className="compose-comment column">
{this.state.status === ComposeStatus.REJECTED ? (
Expand Down Expand Up @@ -443,7 +446,8 @@ ComposeComment.propTypes = {
id: PropTypes.number,
username: PropTypes.string,
token: PropTypes.string,
thumbnailUrl: PropTypes.string
thumbnailUrl: PropTypes.string,
membership_avatar_badge: PropTypes.number
})
};

Expand Down
1 change: 1 addition & 0 deletions src/views/preview/presentation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ const PreviewPresentation = ({
<Avatar
alt={projectInfo.author.username}
src={thumbnailUrl(projectInfo.author.id, 48)}
showAvatarBadge={!!projectInfo.author.profile.membership_avatar_badge}
/>
</a>
<div className="title">
Expand Down
Loading
Loading