webapp/src/components/Topic/TopicBadge/TopicBadge.tsx

117 lines
3.9 KiB
TypeScript
Raw Normal View History

import { clsx } from 'clsx'
2024-05-20 11:16:54 +00:00
import { Show, createEffect, createSignal, on } from 'solid-js'
2024-01-31 12:34:15 +00:00
import { useFollowing } from '../../../context/following'
import { useLocalize } from '../../../context/localize'
2024-01-11 17:40:06 +00:00
import { useMediaQuery } from '../../../context/mediaQuery'
import { useSession } from '../../../context/session'
import { FollowingEntity, Topic } from '../../../graphql/schema/core.gen'
2024-01-13 14:26:21 +00:00
import { capitalize } from '../../../utils/capitalize'
import { getImageUrl } from '../../../utils/getImageUrl'
2024-05-20 11:16:54 +00:00
import { FollowingButton } from '../../_shared/FollowingButton'
import styles from './TopicBadge.module.scss'
2024-01-31 12:34:15 +00:00
type Props = {
topic: Topic
2024-05-20 11:16:54 +00:00
minimize?: boolean
2024-02-08 09:11:52 +00:00
showStat?: boolean
2024-04-30 12:26:53 +00:00
subscriptionsMode?: boolean
}
export const TopicBadge = (props: Props) => {
2024-01-11 17:40:06 +00:00
const { t, lang } = useLocalize()
const { mediaMatches } = useMediaQuery()
const [isMobileView, setIsMobileView] = createSignal(false)
2024-02-04 17:40:15 +00:00
const { requireAuthentication } = useSession()
2024-05-20 11:16:54 +00:00
const [isFollowed, setIsFollowed] = createSignal<boolean>()
const { follow, unfollow, follows, following } = useFollowing()
2024-03-15 12:58:22 +00:00
2024-05-20 11:16:54 +00:00
createEffect(
on(
[() => follows, () => props.topic],
([flws, tpc]) => {
if (flws && tpc) {
const followed = follows?.topics?.some((topics) => topics.id === props.topic?.id)
setIsFollowed(followed)
}
},
{ defer: true },
),
)
2024-01-31 12:34:15 +00:00
const handleFollowClick = () => {
requireAuthentication(() => {
2024-05-20 11:16:54 +00:00
isFollowed()
2024-03-15 14:57:03 +00:00
? follow(FollowingEntity.Topic, props.topic.slug)
: unfollow(FollowingEntity.Topic, props.topic.slug)
2024-01-31 12:34:15 +00:00
}, 'subscribe')
}
2024-01-31 12:34:15 +00:00
createEffect(() => {
setIsMobileView(!mediaMatches.sm)
})
const title = () =>
lang() === 'en' ? capitalize(props.topic.slug.replaceAll('-', ' ')) : props.topic.title
return (
2024-04-30 13:56:39 +00:00
<div class={clsx(styles.TopicBadge, { [styles.TopicBadgeSubscriptionsMode]: props.subscriptionsMode })}>
2024-02-08 09:11:52 +00:00
<div class={styles.content}>
<div class={styles.basicInfo}>
2024-04-30 13:56:39 +00:00
<Show when={props.subscriptionsMode}>
<a
href={`/topic/${props.topic.slug}`}
class={clsx(styles.picture, {
[styles.withImage]: props.topic.pic,
[styles.smallSize]: isMobileView(),
})}
style={
props.topic.pic && {
'background-image': `url('${getImageUrl(props.topic.pic, { width: 40, height: 40 })}')`,
}
}
/>
</Show>
2024-02-08 09:11:52 +00:00
<a href={`/topic/${props.topic.slug}`} class={styles.info}>
<span class={styles.title}>{title()}</span>
2024-04-30 12:26:53 +00:00
<Show
when={props.topic.body}
fallback={
<div class={styles.description}>
{t('PublicationsWithCount', { count: props.topic?.stat?.shouts ?? 0 })}
</div>
}
>
<div innerHTML={props.topic.body} class={clsx('text-truncate', styles.description)} />
2024-02-08 09:11:52 +00:00
</Show>
</a>
</div>
<div class={styles.actions}>
2024-05-20 11:16:54 +00:00
<FollowingButton
isFollowed={isFollowed()}
2024-03-15 14:55:37 +00:00
action={handleFollowClick}
2024-05-20 11:16:54 +00:00
actionMessageType={following()?.slug === props.topic.slug ? following().type : undefined}
2024-03-15 14:55:37 +00:00
/>
2024-02-08 09:11:52 +00:00
</div>
</div>
2024-04-30 13:56:39 +00:00
<Show when={!props.subscriptionsMode}>
<div class={styles.stats}>
2024-06-06 08:36:07 +00:00
<span class={styles.statsItem}>{t('some shouts', { count: props.topic?.stat?.shouts })}</span>
<span class={styles.statsItem}>{t('some authors', { count: props.topic?.stat?.authors })}</span>
2024-04-30 13:56:39 +00:00
<span class={styles.statsItem}>
2024-06-05 16:31:31 +00:00
{t('some followers', { count: props.topic?.stat?.followers })}
2024-04-30 13:56:39 +00:00
</span>
<Show when={props.topic?.stat?.comments}>
<span class={styles.statsItem}>
2024-06-06 08:36:07 +00:00
{t('some comments', { count: props.topic?.stat?.comments ?? 0 })}
2024-04-30 13:56:39 +00:00
</span>
</Show>
</div>
</Show>
2024-03-06 12:55:33 +00:00
</div>
)
}