This repository has been archived by the owner on Jul 17, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathUserCard.tsx
141 lines (127 loc) · 4.98 KB
/
UserCard.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import React, { useMemo } from 'react'
import { SynapseConstants } from '../utils/'
import { useGetProfileImage } from '../utils/hooks/SynapseAPI/file/useFiles'
import {
useGetPrincipalIdForAlias,
useGetUserProfile,
} from '../utils/hooks/SynapseAPI/user/useUserBundle'
import usePreFetchResource, {
useCreateUrlForData,
} from '../utils/hooks/usePreFetchResource'
import { UserProfile } from '../utils/synapseTypes/'
import { Avatar, AvatarSize } from './Avatar'
import { MenuAction } from './UserCardContextMenu'
import UserCardMedium from './UserCardMedium'
import { UserCardSmall } from './UserCardSmall'
import { AliasType } from '../utils/synapseTypes/Principal/PrincipalServices'
export type UserCardSize =
| 'AVATAR'
| 'SMALL USER CARD'
| 'MEDIUM USER CARD'
| 'LARGE USER CARD'
export type UserCardProps = {
/** A UserProfile may be used for data for the card. You must supply one of `userProfile`, `alias`, `ownerId` */
userProfile?: UserProfile
/** An alias that resolves the ownerId for the UserProfile. You must supply one of `userProfile`, `alias`, `ownerId` */
alias?: string
/** The unique ownerId of the UserProfile. You must supply one of `userProfile`, `alias`, `ownerId` */
ownerId?: string
/** Whether to hide the user's Synapse email address */
hideEmail?: boolean
/** If set, the corresponding image will be shown for the user. */
preSignedURL?: string
/** Specifies the card size */
size: UserCardSize
/** For the small user card or avatar, shows the medium user card on mouseover */
showCardOnHover?: boolean
/** For the small user card, hides the tooltip observed when hovering over the profile image. */
hideTooltip?: boolean
/** Specifies the dropdown menu functionality for the ellipsis on medium/large cards. If field === 'SEPERATOR' then a break will occur in the menu. If left undefined, the menu will not render to the screen. */
menuActions?: MenuAction[]
/** The link to point to on the username, defaults to https://www.synapse.org/#!Profile:${userProfile.ownerId} */
link?: string
openLinkInNewTab?: boolean
/** Disables the `@username` link for the small user card (if `showCardOnHover` is false). For the medium user card, disables linking the user's name to their profile (or other specified destination) */
disableLink?: boolean
isCertified?: boolean
isValidated?: boolean
/** Determines the size of the avatar when size === 'AVATAR' or (size === 'SMALL' and withAvatar is true) */
avatarSize?: AvatarSize
/** Whether to show the avatar with the name for the small user card */
withAvatar?: boolean
/** Whether to show the full name in the small user card */
showFullName?: boolean
className?: string
}
export const UserCard: React.FunctionComponent<UserCardProps> = (
props: UserCardProps,
) => {
const {
userProfile: initialProfile,
preSignedURL: initialPreSignedURL,
size,
ownerId,
alias,
...rest
} = props
// If we were given an alias, fetch the principal ID
const { data: fetchedPrincipalId, isLoading: isLoadingAliasLookup } =
useGetPrincipalIdForAlias(
{
alias: alias!,
type: AliasType.USER_NAME,
},
{ enabled: !!alias },
)
const principalId = (
ownerId ??
initialProfile?.ownerId ??
fetchedPrincipalId
)?.toString()
// If we weren't provided an initialProfile, fetch from Synapse
const { data: fetchedProfile, isLoading: isLoadingProfile } =
useGetUserProfile(principalId!, {
enabled: !!principalId && !initialProfile,
})
const userProfile = initialProfile ?? fetchedProfile
const { data: avatarData, isLoading: isLoadingAvatar } = useGetProfileImage(
principalId!,
{
// Don't fetch the avatar if `initialPresignedURL` is provided.
// Also, wait until we have a value for `principalId`
enabled: !!(!initialPreSignedURL && principalId),
},
)
// If a URL was provided, fetch it and create a local data URL
const providedAvatarURL = usePreFetchResource(initialPreSignedURL)
// If we fetched the avatar from Synapse, we already have the blob. Create a local data URL
const fetchedAvatarUrl = useCreateUrlForData(avatarData)
const imageURL = providedAvatarURL ?? fetchedAvatarUrl
const isLoading = isLoadingAliasLookup || isLoadingProfile
const propsForChild = useMemo(
() => ({
userProfile: userProfile!,
imageURL,
isLoadingAvatar,
...rest,
}),
[imageURL, isLoadingAvatar, rest, userProfile],
)
if (isLoading || userProfile == null) {
return <></>
}
switch (size) {
case SynapseConstants.AVATAR:
return <Avatar {...propsForChild} />
case SynapseConstants.SMALL_USER_CARD:
return <UserCardSmall {...propsForChild} />
case SynapseConstants.MEDIUM_USER_CARD:
return <UserCardMedium {...propsForChild} />
case SynapseConstants.LARGE_USER_CARD:
return <UserCardMedium isLarge={true} {...propsForChild} />
default:
console.warn('No size specified for UserCard')
return <span />
}
}
export default UserCard