2023-10-04 19:04:09 +00:00
|
|
|
import { clsx } from 'clsx'
|
2024-02-08 09:11:52 +00:00
|
|
|
import { Show, createEffect, createSignal, on } from 'solid-js'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
import { useFollowing } from '../../../context/following'
|
2024-01-11 15:56:32 +00:00
|
|
|
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'
|
2023-10-27 18:50:13 +00:00
|
|
|
import { getImageUrl } from '../../../utils/getImageUrl'
|
2024-03-15 14:57:03 +00:00
|
|
|
import { BadgeSubscribeButton } from '../../_shared/BadgeSubscribeButton'
|
2023-11-14 15:10:00 +00:00
|
|
|
import styles from './TopicBadge.module.scss'
|
2024-01-31 12:34:15 +00:00
|
|
|
|
2023-10-04 19:04:09 +00:00
|
|
|
type Props = {
|
|
|
|
topic: Topic
|
|
|
|
minimizeSubscribeButton?: boolean
|
2024-02-08 09:11:52 +00:00
|
|
|
showStat?: boolean
|
2023-10-04 19:04:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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-03-15 12:58:22 +00:00
|
|
|
const [isSubscribed, setIsSubscribed] = createSignal<boolean>()
|
|
|
|
const { follow, unfollow, subscriptions, subscribeInAction } = useFollowing()
|
|
|
|
|
|
|
|
createEffect(() => {
|
2024-03-15 14:57:03 +00:00
|
|
|
if (!subscriptions || !props.topic) return
|
2024-03-15 15:24:33 +00:00
|
|
|
const subscribed = subscriptions.topics?.some((topics) => topics.id === props.topic?.id)
|
2024-03-15 12:58:22 +00:00
|
|
|
setIsSubscribed(subscribed)
|
|
|
|
})
|
2023-10-04 19:04:09 +00:00
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
const handleFollowClick = () => {
|
|
|
|
requireAuthentication(() => {
|
2024-03-15 14:57:03 +00:00
|
|
|
isSubscribed()
|
|
|
|
? follow(FollowingEntity.Topic, props.topic.slug)
|
|
|
|
: unfollow(FollowingEntity.Topic, props.topic.slug)
|
2024-01-31 12:34:15 +00:00
|
|
|
}, 'subscribe')
|
2023-10-04 19:04:09 +00:00
|
|
|
}
|
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
createEffect(() => {
|
|
|
|
setIsMobileView(!mediaMatches.sm)
|
|
|
|
})
|
|
|
|
|
2024-01-04 07:14:57 +00:00
|
|
|
const title = () =>
|
|
|
|
lang() === 'en' ? capitalize(props.topic.slug.replaceAll('-', ' ')) : props.topic.title
|
|
|
|
|
2023-10-04 19:04:09 +00:00
|
|
|
return (
|
|
|
|
<div class={styles.TopicBadge}>
|
2024-02-08 09:11:52 +00:00
|
|
|
<div class={styles.content}>
|
|
|
|
<div class={styles.basicInfo}>
|
|
|
|
<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 })}')`,
|
|
|
|
}
|
2024-01-11 17:40:06 +00:00
|
|
|
}
|
2024-02-08 09:11:52 +00:00
|
|
|
/>
|
|
|
|
<a href={`/topic/${props.topic.slug}`} class={styles.info}>
|
|
|
|
<span class={styles.title}>{title()}</span>
|
|
|
|
<Show
|
|
|
|
when={props.topic.body}
|
|
|
|
fallback={
|
|
|
|
<div class={styles.description}>
|
2024-02-21 14:25:28 +00:00
|
|
|
{t('PublicationsWithCount', { count: props.topic?.stat?.shouts ?? 0 })}
|
2024-02-08 09:11:52 +00:00
|
|
|
</div>
|
|
|
|
}
|
|
|
|
>
|
2024-03-26 13:57:24 +00:00
|
|
|
<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-03-15 14:55:37 +00:00
|
|
|
<BadgeSubscribeButton
|
|
|
|
isSubscribed={isSubscribed()}
|
|
|
|
action={handleFollowClick}
|
2024-03-15 14:57:03 +00:00
|
|
|
actionMessageType={
|
|
|
|
subscribeInAction()?.slug === props.topic.slug ? subscribeInAction().type : undefined
|
|
|
|
}
|
2024-03-15 14:55:37 +00:00
|
|
|
/>
|
2024-02-08 09:11:52 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class={styles.stats}>
|
2024-03-06 12:55:33 +00:00
|
|
|
<span class={styles.statsItem}>{t('shoutsWithCount', { count: props.topic?.stat?.shouts })}</span>
|
|
|
|
<span class={styles.statsItem}>{t('authorsWithCount', { count: props.topic?.stat?.authors })}</span>
|
2024-02-08 09:11:52 +00:00
|
|
|
<span class={styles.statsItem}>
|
2024-03-06 12:55:33 +00:00
|
|
|
{t('FollowersWithCount', { count: props.topic?.stat?.followers })}
|
2024-02-08 09:11:52 +00:00
|
|
|
</span>
|
2024-03-06 12:36:12 +00:00
|
|
|
<Show when={props.topic?.stat?.comments}>
|
2024-03-06 12:55:33 +00:00
|
|
|
<span class={styles.statsItem}>
|
|
|
|
{t('CommentsWithCount', { count: props.topic?.stat?.comments ?? 0 })}
|
|
|
|
</span>
|
2024-03-06 12:36:12 +00:00
|
|
|
</Show>
|
2024-01-11 17:40:06 +00:00
|
|
|
</div>
|
2024-03-06 12:55:33 +00:00
|
|
|
</div>
|
2023-10-04 19:04:09 +00:00
|
|
|
)
|
|
|
|
}
|