Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
11 changes: 8 additions & 3 deletions src/components/grid/grid.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,20 @@
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