2023-08-11 16:42:41 +00:00
|
|
|
import { clsx } from 'clsx'
|
2024-02-04 11:25:21 +00:00
|
|
|
import { Show, createMemo } from 'solid-js'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2024-07-04 07:51:15 +00:00
|
|
|
import { ConditionalWrapper } from '~/components/_shared/ConditionalWrapper'
|
|
|
|
import { Image } from '~/components/_shared/Image'
|
|
|
|
import { Loading } from '~/components/_shared/Loading'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
|
|
|
import styles from './Userpic.module.scss'
|
2023-08-11 16:42:41 +00:00
|
|
|
|
|
|
|
type Props = {
|
|
|
|
name: string
|
|
|
|
userpic: string
|
|
|
|
class?: string
|
|
|
|
slug?: string
|
|
|
|
onClick?: () => void
|
|
|
|
loading?: boolean
|
|
|
|
hasLink?: boolean
|
2023-10-20 16:21:40 +00:00
|
|
|
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' // 20 | 28 | 32 | 40 | 168
|
2023-08-11 16:42:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const Userpic = (props: Props) => {
|
|
|
|
const letters = () => {
|
|
|
|
if (!props.name) return
|
|
|
|
const names = props.name ? props.name.split(' ') : []
|
2024-02-04 09:03:15 +00:00
|
|
|
return `${names[0][0 ?? names[0][0]]}.${names.length > 1 ? `${names[1][0]}.` : ''}`
|
2023-08-11 16:42:41 +00:00
|
|
|
}
|
|
|
|
|
2023-10-27 18:50:13 +00:00
|
|
|
const avatarSize = createMemo(() => {
|
2023-10-20 16:21:40 +00:00
|
|
|
switch (props.size) {
|
|
|
|
case 'XS': {
|
2023-10-27 18:50:13 +00:00
|
|
|
return 40
|
2023-10-20 16:21:40 +00:00
|
|
|
}
|
|
|
|
case 'S': {
|
2023-10-27 18:50:13 +00:00
|
|
|
return 56
|
2023-10-20 16:21:40 +00:00
|
|
|
}
|
|
|
|
case 'L': {
|
2023-10-27 18:50:13 +00:00
|
|
|
return 80
|
2023-10-20 16:21:40 +00:00
|
|
|
}
|
|
|
|
case 'XL': {
|
2023-10-27 18:50:13 +00:00
|
|
|
return 336
|
2023-10-20 16:21:40 +00:00
|
|
|
}
|
|
|
|
default: {
|
2023-10-27 18:50:13 +00:00
|
|
|
return 64
|
2023-10-20 16:21:40 +00:00
|
|
|
}
|
|
|
|
}
|
2023-10-27 18:50:13 +00:00
|
|
|
})
|
2023-10-20 16:21:40 +00:00
|
|
|
|
2023-08-11 16:42:41 +00:00
|
|
|
return (
|
|
|
|
<div
|
2023-10-20 16:21:40 +00:00
|
|
|
class={clsx(styles.Userpic, props.class, styles[props.size ?? 'M'], {
|
2024-06-26 08:22:05 +00:00
|
|
|
cursorPointer: props.onClick
|
2023-08-11 16:42:41 +00:00
|
|
|
})}
|
|
|
|
onClick={props.onClick}
|
|
|
|
>
|
|
|
|
<Show when={!props.loading} fallback={<Loading />}>
|
|
|
|
<ConditionalWrapper
|
2024-06-24 17:50:27 +00:00
|
|
|
condition={Boolean(props.hasLink)}
|
2024-07-15 23:11:01 +00:00
|
|
|
wrapper={(children) => <a href={`/@${props.slug}`}>{children}</a>}
|
2023-08-11 16:42:41 +00:00
|
|
|
>
|
2023-11-01 08:34:59 +00:00
|
|
|
<Show keyed={true} when={props.userpic} fallback={<div class={styles.letters}>{letters()}</div>}>
|
2023-10-27 18:50:13 +00:00
|
|
|
<Image src={props.userpic} width={avatarSize()} height={avatarSize()} alt={props.name} />
|
2023-08-11 16:42:41 +00:00
|
|
|
</Show>
|
|
|
|
</ConditionalWrapper>
|
|
|
|
</Show>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|