Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Replace dcl-gatsby Avatar component #1041

Merged
merged 3 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
138 changes: 138 additions & 0 deletions src/components/Common/Avatar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
@keyframes Avatar--loading-animation {
to {
background-position-x: -200%;
}
}

.Avatar {
height: auto;
border-radius: 100%;
background-color: #7a7a7a;
vertical-align: middle;
max-width: 256px;
margin: 0;
}

.Avatar.Avatar--loading {
opacity: 0.6;
background-size: 200% 100%;
animation: 1.5s Avatar--loading-animation linear infinite;
background-image: linear-gradient(110deg, #7a7a7a 18%, #949494 28%, #7a7a7a 43%);
}

.Avatar.Avatar--0,
.Avatar.Avatar--1 {
background-color: #4e79a7;
}

.Avatar.Avatar--0.Avatar--loading,
.Avatar.Avatar--1.Avatar--loading {
background-image: linear-gradient(110deg, #4e79a7 18%, #6e93bb 28%, #4e79a7 43%);
}

.Avatar.Avatar--2,
.Avatar.Avatar--3 {
background-color: #f28e2c;
}

.Avatar.Avatar--2.Avatar--loading,
.Avatar.Avatar--3.Avatar--loading {
background-image: linear-gradient(110deg, #f28e2c 18%, #f4a456 28%, #f28e2c 43%);
}

.Avatar.Avatar--4,
.Avatar.Avatar--5 {
background-color: #e15759;
}

.Avatar.Avatar--4.Avatar--loading,
.Avatar.Avatar--5.Avatar--loading {
background-image: linear-gradient(110deg, #e15759 18%, #e6787a 28%, #e15759 43%);
}

.Avatar.Avatar--6,
.Avatar.Avatar--7 {
background-color: #76b7b2;
}

.Avatar.Avatar--6.Avatar--loading,
.Avatar.Avatar--7.Avatar--loading {
background-image: linear-gradient(110deg, #76b7b2 18%, #91c5c1 28%, #76b7b2 43%);
}

.Avatar.Avatar--8,
.Avatar.Avatar--9 {
background-color: #59a14f;
}

.Avatar.Avatar--8.Avatar--loading,
.Avatar.Avatar--9.Avatar--loading {
background-image: linear-gradient(110deg, #59a14f 18%, #77b76e 28%, #59a14f 43%);
}

.Avatar.Avatar--a,
.Avatar.Avatar--b {
background-color: #edc949;
}

.Avatar.Avatar--a.Avatar--loading,
.Avatar.Avatar--b.Avatar--loading {
background-image: linear-gradient(110deg, #edc949 18%, #f0d36d 28%, #edc949 43%);
}

.Avatar.Avatar--c,
.Avatar.Avatar--d {
background-color: #af7aa1;
}

.Avatar.Avatar--c.Avatar--loading,
.Avatar.Avatar--d.Avatar--loading {
background-image: linear-gradient(110deg, #af7aa1 18%, #bf94b3 28%, #af7aa1 43%);
}

.Avatar.Avatar--e,
.Avatar.Avatar--f {
background-color: #ff9da7;
}

.Avatar.Avatar--e.Avatar--loading,
.Avatar.Avatar--f.Avatar--loading {
background-image: linear-gradient(110deg, #ff9da7 18%, #feb0b8 28%, #ff9da7 43%);
}

.Avatar.Avatar--mini {
width: 20px;
}

.Avatar.Avatar--tiny {
width: 24px;
}

.Avatar.Avatar--small {
width: 32px;
}

.Avatar,
.Avatar.Avatar--medium {
width: 44px;
}

.Avatar.Avatar--large {
width: 52px;
}

.Avatar.Avatar--big {
width: 66px;
}

.Avatar.Avatar--huge {
width: 90px;
}

.Avatar.Avatar--massive {
width: 122px;
}

.Avatar.Avatar--full {
width: 100%;
}
68 changes: 68 additions & 0 deletions src/components/Common/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useState } from 'react'

import classNames from 'classnames'

import useProfile from '../../hooks/useProfile'

import './Avatar.css'

export enum AvatarSize {
Mini = 'mini',
Tiny = 'tiny',
Small = 'small',
Medium = 'medium',
Large = 'large',
Big = 'big',
Huge = 'huge',
Massive = 'massive',
Full = 'full',
}

const DEFAULT_AVATAR = 'https://decentraland.org/images/male.png'
type Props = {
size?: `${AvatarSize}`
src?: string
address?: string
loading?: boolean
}

type AvatarProps = Omit<
React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>,
'size' | 'src'
> &
Props

export default function Avatar({ address, size, src, loading, ...props }: AvatarProps) {
ncomerci marked this conversation as resolved.
Show resolved Hide resolved
const [failed, setFailed] = useState(false)

const { profile, isLoadingProfile } = useProfile(address)

const getTarget = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change this to

  const getTarget = () => {
    if (src) {
      return src
    }

    const avatar = profile?.avatar?.snapshots?.face256 || profile?.avatar?.snapshots?.face
    
    if (failed || !avatar) {
      return DEFAULT_AVATAR
    }

    return avatar
  }

const avatar = profile?.avatar?.snapshots?.face256 || profile?.avatar?.snapshots?.face
if (src) {
return src
} else if (failed || !avatar) {
return DEFAULT_AVATAR
}

return avatar
}

return (
<img
loading="lazy"
{...props}
src={!loading ? getTarget() : undefined}
onError={() => setFailed(true)}
width={props.width ?? '128'}
height={props.height ?? '128'}
className={classNames(
'Avatar',
`Avatar--${size || AvatarSize.Mini}`,
`Avatar--${((address || '')[2] || '').toLowerCase()}`,
(loading || (!src && isLoadingProfile)) && `Avatar--loading`,
props.className
)}
/>
)
}
4 changes: 2 additions & 2 deletions src/components/Grants/GrantCard/GrantCardHeadline.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
margin-right: 0 !important;
}

.GrantCardHeadline__Avatar .dg.dcl-avatar,
.dg.dcl-avatar.dcl-avatar--medium {
.GrantCardHeadline__Avatar .Avatar,
.Avatar.Avatar--medium {
width: 44px;
margin-right: 0;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'

import Markdown from 'decentraland-gatsby/dist/components/Text/Markdown'
import Avatar from 'decentraland-gatsby/dist/components/User/Avatar'
import useFormatMessage from 'decentraland-gatsby/dist/hooks/useFormatMessage'
import { Button } from 'decentraland-ui/dist/components/Button/Button'
import { Modal } from 'decentraland-ui/dist/components/Modal/Modal'

import Avatar from '../../Common/Avatar'
import ForumBlue from '../../Icon/ForumBlue'
import LinkFailed from '../../Icon/LinkFailed'
import LinkSucceded from '../../Icon/LinkSucceded'
Expand Down
4 changes: 2 additions & 2 deletions src/components/Modal/Votes/VotesList.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
border-bottom: none;
}

.VotesList .dg.dcl-avatar {
.VotesList .Avatar {
margin: 0 0.25em 0 0;
}

Expand Down Expand Up @@ -129,7 +129,7 @@
font-size: 13px;
}

.VotesList .dg.dcl-avatar {
.VotesList .Avatar {
margin: 0 0.25em 0 0;
width: 20px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
margin-left: 5px;
}

.VotingPowerDelegationCandidatesList .dg.dcl-avatar {
.VotingPowerDelegationCandidatesList .Avatar {
margin-right: 11px;
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/Proposal/Comments/ProposalComment.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react'

import Avatar from 'decentraland-gatsby/dist/components/User/Avatar'
import { Link } from 'decentraland-gatsby/dist/plugins/intl'
import DOMPurify from 'dompurify'
import isEthereumAddress from 'validator/lib/isEthereumAddress'

import { getUserProfileUrl } from '../../../entities/User/utils'
import useProfile from '../../../hooks/useProfile'
import Time from '../../../utils/date/Time'
import Avatar from '../../Common/Avatar'
import Text from '../../Common/Text/Text'
import ValidatedProfile from '../../Icon/ValidatedProfile'

Expand Down
2 changes: 1 addition & 1 deletion src/components/Proposal/ProposalItem.css
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
color: var(--black-600);
}

.ProposalItem__Details > span.Username > img.dg.dcl-avatar {
.ProposalItem__Details > span.Username > img.Avatar {
margin: 0 !important;
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/Transparency/MemberCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo } from 'react'

import Avatar from 'decentraland-gatsby/dist/components/User/Avatar'
import Avatar from '../Common/Avatar'

import './MemberCard.css'

Expand Down
2 changes: 1 addition & 1 deletion src/components/User/Username.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ a.Username span.address {
color: inherit;
}

.Username img.dcl-avatar {
.Username img.Avatar {
margin-right: 0.5rem;
}

Expand Down
26 changes: 13 additions & 13 deletions src/components/User/Username.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import React from 'react'

import classNames from 'classnames'
import { Size, SizeProps } from 'decentraland-gatsby/dist/components/Props/types'
import Avatar from 'decentraland-gatsby/dist/components/User/Avatar'
import { Link } from 'decentraland-gatsby/dist/plugins/intl'
import { Address } from 'decentraland-ui/dist/components/Address/Address'
import { Blockie } from 'decentraland-ui/dist/components/Blockie/Blockie'

import { getChecksumAddress } from '../../entities/Snapshot/utils'
import useProfile from '../../hooks/useProfile'
import locations from '../../utils/locations'
import Avatar, { AvatarSize } from '../Common/Avatar'

import './Username.css'

Expand All @@ -19,7 +18,8 @@ enum UsernameVariant {
Full = 'full',
}

type Props = SizeProps & {
type Props = {
size?: `${AvatarSize}`
address: string
linked?: boolean
className?: string
Expand All @@ -30,23 +30,23 @@ type Props = SizeProps & {
function getBlockieScale(size?: string) {
const DEFAULT_BLOCKIE_SCALE = 3.35
switch (size) {
case Size.Mini:
case AvatarSize.Mini:
return 3
case Size.Tiny:
case AvatarSize.Tiny:
return DEFAULT_BLOCKIE_SCALE
case Size.Small:
case AvatarSize.Small:
return 4.9
case Size.Medium:
case AvatarSize.Medium:
return 7
case Size.Large:
case AvatarSize.Large:
return 8.4
case Size.Big:
case AvatarSize.Big:
return 10.5
case Size.Huge:
case AvatarSize.Huge:
return 14.5
case Size.Massive:
case AvatarSize.Massive:
return 20
case Size.Full:
case AvatarSize.Full:
return 42.5
default:
return DEFAULT_BLOCKIE_SCALE
Expand Down Expand Up @@ -74,7 +74,7 @@ const Username = ({ address, size, linked, variant = UsernameVariant.Full, stron
<>
{hasDclProfile && (
<>
<Avatar size={size || 'mini'} address={address} />
<Avatar size={size} address={address} />
{profileHasName && !isAvatarVariant && <span>{profile!.name}</span>}
{!profileHasName && !isAvatarVariant && <Address value={checksumAddress} strong={strong} />}
</>
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function useProfile(address?: string | null) {
if (!address) return null
return profiles.load(address)
}
const { data: profile } = useQuery({
const { data: profile, isLoading: isLoadingProfile } = useQuery({
queryKey: [`userProfile#${address?.toLowerCase()}`],
queryFn: () => fetchProfile(),
staleTime: DEFAULT_QUERY_STALE_TIME,
Expand All @@ -18,5 +18,5 @@ export default function useProfile(address?: string | null) {
const profileHasName = hasDclProfile && profile!.name && profile!.name.length > 0
const displayableAddress = profileHasName ? profile.name : address

return { profile, hasDclProfile, displayableAddress }
return { profile, hasDclProfile, displayableAddress, isLoadingProfile }
}