Skip to content

Commit f7dc55b

Browse files
authored
[C-2971] Add Avatar (#3902)
1 parent ce441c1 commit f7dc55b

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.root {
2+
display: flex;
3+
}
4+
5+
.image {
6+
border-radius: 50%;
7+
border: 1px solid var(--white);
8+
box-shadow: 0 0 1px 0 rgba(133, 129, 153, 0.5);
9+
10+
text-align: center;
11+
background-size: cover;
12+
background-position: center;
13+
background-repeat: no-repeat;
14+
background-color: var(--default-profile-picture-background);
15+
}
16+
17+
.imageWrapper {
18+
position: relative;
19+
overflow: hidden;
20+
flex: 0 0 48px;
21+
height: 48px;
22+
width: 48px;
23+
}
24+
25+
.skeleton {
26+
border-radius: 50%;
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import {
2+
ID,
3+
Maybe,
4+
SquareSizes,
5+
accountSelectors,
6+
cacheUsersSelectors
7+
} from '@audius/common'
8+
import { Link } from 'react-router-dom'
9+
10+
import DynamicImage from 'components/dynamic-image/DynamicImage'
11+
import { useProfilePicture } from 'hooks/useUserProfilePicture'
12+
import { useSelector } from 'utils/reducer'
13+
import { SIGN_IN_PAGE, profilePage } from 'utils/route'
14+
15+
import styles from './Avatar.module.css'
16+
17+
const { getAccountUser } = accountSelectors
18+
19+
const { getUser } = cacheUsersSelectors
20+
21+
const messages = {
22+
goTo: 'Go to',
23+
your: 'your',
24+
profile: 'profile'
25+
}
26+
27+
type AvatarProps = {
28+
userId: Maybe<ID>
29+
}
30+
31+
export const Avatar = (props: AvatarProps) => {
32+
const { userId } = props
33+
const profileImage = useProfilePicture(
34+
userId ?? null,
35+
SquareSizes.SIZE_150_BY_150
36+
)
37+
38+
const goTo = useSelector((state) => {
39+
const profile = getUser(state, { id: userId })
40+
if (!profile) return SIGN_IN_PAGE
41+
const { handle } = profile
42+
return profilePage(handle)
43+
})
44+
45+
const name = useSelector((state) => {
46+
const user = getUser(state, { id: userId })
47+
const currentUser = getAccountUser(state)
48+
return user?.user_id === currentUser?.user_id ? messages.your : user?.name
49+
})
50+
51+
return (
52+
<Link
53+
to={goTo}
54+
aria-label={`${messages.goTo} ${name} ${messages.profile}`}
55+
className={styles.root}
56+
>
57+
<DynamicImage
58+
className={styles.image}
59+
wrapperClassName={styles.imageWrapper}
60+
skeletonClassName={styles.skeleton}
61+
image={profileImage}
62+
/>
63+
</Link>
64+
)
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Avatar'

packages/web/src/hooks/useUserProfilePicture.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@ import {
33
SquareSizes,
44
useImageSize,
55
cacheUsersActions,
6-
imageProfilePicEmpty as profilePicEmpty
6+
imageProfilePicEmpty as profilePicEmpty,
7+
cacheUsersSelectors
78
} from '@audius/common'
89
import { useDispatch } from 'react-redux'
910

11+
import { useSelector } from 'utils/reducer'
12+
1013
const { fetchProfilePicture } = cacheUsersActions
14+
const { getUser } = cacheUsersSelectors
1115

16+
/**
17+
* @deprecated Use useProfilePicture instead
18+
*/
1219
export const useUserProfilePicture = (
1320
userId: number | null,
1421
profilePictureSizes: ProfilePictureSizes | null,
@@ -28,6 +35,28 @@ export const useUserProfilePicture = (
2835
})
2936
}
3037

38+
export const useProfilePicture = (
39+
userId: number | null,
40+
size: SquareSizes,
41+
defaultImage: string = profilePicEmpty as string,
42+
load = true
43+
) => {
44+
const dispatch = useDispatch()
45+
const profilePictureSizes = useSelector(
46+
(state) => getUser(state, { id: userId })?._profile_picture_sizes
47+
)
48+
return useImageSize({
49+
dispatch,
50+
id: userId,
51+
sizes: profilePictureSizes ?? null
52+
sizes: profilePictureSizes ?? null,
53+
size,
54+
action: fetchProfilePicture,
55+
defaultImage,
56+
load
57+
})
58+
}
59+
3160
/**
3261
* Like useUserProfilePicture, but onDemand is set to true, which
3362
* returns a callback that can be used to fetch the image on demand.

0 commit comments

Comments
 (0)