webapp/src/components/Author/AuthorBadge/AuthorBadge.tsx

177 lines
6.0 KiB
TypeScript
Raw Normal View History

import { openPage } from '@nanostores/router'
import { clsx } from 'clsx'
import { createMemo, createSignal, Match, Show, Switch } from 'solid-js'
import { useLocalize } from '../../../context/localize'
import { useSession } from '../../../context/session'
2023-11-28 13:18:25 +00:00
import { Author, FollowingEntity } from '../../../graphql/schema/core.gen'
import { router, useRouter } from '../../../stores/router'
import { follow, unfollow } from '../../../stores/zine/common'
import { Button } from '../../_shared/Button'
import { CheckButton } from '../../_shared/CheckButton'
import { Icon } from '../../_shared/Icon'
import { Userpic } from '../Userpic'
import styles from './AuthorBadge.module.scss'
import stylesButton from '../../_shared/Button/Button.module.scss'
type Props = {
author: Author
minimizeSubscribeButton?: boolean
showMessageButton?: boolean
iconButtons?: boolean
nameOnly?: boolean
}
export const AuthorBadge = (props: Props) => {
const [isSubscribing, setIsSubscribing] = createSignal(false)
const {
2023-12-13 23:56:44 +00:00
author,
subscriptions,
actions: { loadSubscriptions, requireAuthentication },
} = useSession()
const { changeSearchParams } = useRouter()
const { t, formatDate } = useLocalize()
const subscribed = createMemo(() =>
2023-12-14 00:04:07 +00:00
subscriptions().authors.some((a: Author) => a.slug === props.author.slug),
)
const subscribe = async (really = true) => {
setIsSubscribing(true)
await (really
? follow({ what: FollowingEntity.Author, slug: props.author.slug })
: unfollow({ what: FollowingEntity.Author, slug: props.author.slug }))
await loadSubscriptions()
setIsSubscribing(false)
}
2023-10-05 04:24:01 +00:00
const handleSubscribe = (really: boolean) => {
requireAuthentication(() => {
subscribe(really)
}, 'subscribe')
}
const initChat = () => {
requireAuthentication(() => {
openPage(router, `inbox`)
changeSearchParams({
initChat: props.author.id.toString(),
})
}, 'discussions')
}
2023-11-02 22:02:11 +00:00
return (
<div class={clsx(styles.AuthorBadge, { [styles.nameOnly]: props.nameOnly })}>
2023-11-06 08:00:31 +00:00
<div class={styles.basicInfo}>
<Userpic
hasLink={true}
size={'M'}
name={props.author.name}
2023-11-28 13:18:25 +00:00
userpic={props.author.pic}
2023-11-06 08:00:31 +00:00
slug={props.author.slug}
/>
<a href={`/author/${props.author.slug}`} class={styles.info}>
<div class={styles.name}>
<span>{props.author.name}</span>
</div>
<Show when={!props.nameOnly}>
<Switch
fallback={
<div class={styles.bio}>
2023-11-28 13:18:25 +00:00
{t('Registered since {date}', {
date: formatDate(new Date(props.author.created_at * 1000)),
})}
2023-11-06 08:00:31 +00:00
</div>
}
>
<Match when={props.author.bio}>
<div class={clsx('text-truncate', styles.bio)} innerHTML={props.author.bio} />
</Match>
<Match when={props.author?.stat && props.author?.stat.shouts > 0}>
<div class={styles.bio}>
{t('PublicationsWithCount', { count: props.author.stat?.shouts ?? 0 })}
</div>
</Match>
</Switch>
</Show>
</a>
</div>
2023-12-13 23:56:44 +00:00
<Show when={props.author.slug !== author()?.slug && !props.nameOnly}>
<div class={styles.actions}>
<Show
when={!props.minimizeSubscribeButton}
fallback={
<CheckButton
text={t('Follow')}
checked={subscribed()}
2023-10-05 04:24:01 +00:00
onClick={() => handleSubscribe(!subscribed())}
/>
}
>
<Show
when={subscribed()}
fallback={
<Button
variant={props.iconButtons ? 'secondary' : 'bordered'}
2023-11-02 22:02:11 +00:00
size="M"
value={
<Show
when={props.iconButtons}
fallback={
<Show when={isSubscribing()} fallback={t('Subscribe')}>
{t('subscribing...')}
</Show>
}
>
<Icon name="author-subscribe" class={stylesButton.icon} />
</Show>
}
2023-10-05 04:24:01 +00:00
onClick={() => handleSubscribe(true)}
2023-11-08 20:42:13 +00:00
isSubscribeButton={true}
2023-11-08 20:52:56 +00:00
class={clsx(styles.actionButton, {
[styles.iconed]: props.iconButtons,
[stylesButton.subscribed]: subscribed(),
2023-11-08 20:52:56 +00:00
})}
/>
}
>
<Button
variant={props.iconButtons ? 'secondary' : 'bordered'}
2023-11-02 22:02:11 +00:00
size="M"
value={
<Show
when={props.iconButtons}
fallback={
<>
<span class={styles.actionButtonLabel}>{t('Following')}</span>
<span class={styles.actionButtonLabelHovered}>{t('Unfollow')}</span>
</>
}
>
<Icon name="author-unsubscribe" class={stylesButton.icon} />
</Show>
}
2023-10-05 04:24:01 +00:00
onClick={() => handleSubscribe(false)}
2023-11-08 20:42:13 +00:00
isSubscribeButton={true}
2023-11-08 20:52:56 +00:00
class={clsx(styles.actionButton, {
[styles.iconed]: props.iconButtons,
[stylesButton.subscribed]: subscribed(),
2023-11-08 20:52:56 +00:00
})}
/>
</Show>
</Show>
<Show when={props.showMessageButton}>
<Button
variant={props.iconButtons ? 'secondary' : 'bordered'}
2023-11-02 22:02:11 +00:00
size="M"
value={props.iconButtons ? <Icon name="inbox-white" /> : t('Message')}
onClick={initChat}
class={clsx(styles.actionButton, { [styles.iconed]: props.iconButtons })}
/>
</Show>
</div>
</Show>
</div>
)
}