2022-11-22 09:27:01 +00:00
|
|
|
import { capitalize } from '../../utils'
|
2022-11-02 21:43:38 +00:00
|
|
|
import styles from './Card.module.scss'
|
2022-12-01 18:45:35 +00:00
|
|
|
import { createEffect, createMemo, createSignal, Show } from 'solid-js'
|
2022-09-09 11:53:35 +00:00
|
|
|
import type { Topic } from '../../graphql/types.gen'
|
2022-09-13 09:59:04 +00:00
|
|
|
import { FollowingEntity } from '../../graphql/types.gen'
|
2022-09-09 11:53:35 +00:00
|
|
|
import { t } from '../../utils/intl'
|
2022-09-13 09:59:04 +00:00
|
|
|
import { follow, unfollow } from '../../stores/zine/common'
|
2022-09-30 14:22:33 +00:00
|
|
|
import { getLogger } from '../../utils/logger'
|
2022-11-09 19:02:12 +00:00
|
|
|
import { clsx } from 'clsx'
|
2022-11-14 10:02:08 +00:00
|
|
|
import { useSession } from '../../context/session'
|
2022-11-22 09:27:01 +00:00
|
|
|
import { StatMetrics } from '../_shared/StatMetrics'
|
2022-12-01 18:45:35 +00:00
|
|
|
import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient'
|
2022-09-30 14:22:33 +00:00
|
|
|
|
|
|
|
const log = getLogger('TopicCard')
|
2022-09-09 11:53:35 +00:00
|
|
|
|
|
|
|
interface TopicProps {
|
|
|
|
topic: Topic
|
|
|
|
compact?: boolean
|
|
|
|
subscribed?: boolean
|
|
|
|
shortDescription?: boolean
|
|
|
|
subscribeButtonBottom?: boolean
|
2022-10-14 18:33:06 +00:00
|
|
|
additionalClass?: string
|
|
|
|
isTopicInRow?: boolean
|
|
|
|
iconButton?: boolean
|
2022-11-16 21:08:04 +00:00
|
|
|
showPublications?: boolean
|
2022-09-09 11:53:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const TopicCard = (props: TopicProps) => {
|
2022-12-01 18:45:35 +00:00
|
|
|
const {
|
|
|
|
session,
|
|
|
|
actions: { loadSession }
|
|
|
|
} = useSession()
|
|
|
|
|
|
|
|
const [isSubscribing, setIsSubscribing] = createSignal(false)
|
2022-09-30 14:22:33 +00:00
|
|
|
|
2022-09-13 09:59:04 +00:00
|
|
|
const subscribed = createMemo(() => {
|
2022-10-04 12:16:07 +00:00
|
|
|
if (!session()?.user?.slug || !session()?.news?.topics) {
|
2022-09-30 14:22:33 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-10-04 12:16:07 +00:00
|
|
|
return session()?.news.topics.includes(props.topic.slug)
|
2022-09-13 09:59:04 +00:00
|
|
|
})
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2022-09-13 09:59:04 +00:00
|
|
|
const subscribe = async (really = true) => {
|
2022-12-01 18:45:35 +00:00
|
|
|
setIsSubscribing(true)
|
|
|
|
|
|
|
|
await (really
|
|
|
|
? follow({ what: FollowingEntity.Topic, slug: props.topic.slug })
|
|
|
|
: unfollow({ what: FollowingEntity.Topic, slug: props.topic.slug }))
|
|
|
|
|
|
|
|
await loadSession()
|
|
|
|
setIsSubscribing(false)
|
2022-09-13 09:59:04 +00:00
|
|
|
}
|
2022-12-01 18:45:35 +00:00
|
|
|
|
2022-09-09 11:53:35 +00:00
|
|
|
return (
|
2022-10-14 18:33:06 +00:00
|
|
|
<div
|
2022-11-02 21:43:38 +00:00
|
|
|
class={styles.topic}
|
2022-10-14 18:33:06 +00:00
|
|
|
classList={{
|
|
|
|
row: !props.compact && !props.subscribeButtonBottom,
|
2022-11-16 21:08:04 +00:00
|
|
|
[styles.topicCompact]: props.compact,
|
2022-11-02 21:43:38 +00:00
|
|
|
[styles.topicInRow]: props.isTopicInRow
|
2022-10-14 18:33:06 +00:00
|
|
|
}}
|
|
|
|
>
|
2022-11-14 21:17:20 +00:00
|
|
|
<div classList={{ 'col-md-9 col-lg-7 col-xl-6': !props.compact && !props.subscribeButtonBottom }}>
|
2022-09-30 14:22:33 +00:00
|
|
|
<Show when={props.topic.title}>
|
2022-11-09 19:02:12 +00:00
|
|
|
<h3 class={styles.topicTitle}>
|
2022-09-30 14:22:33 +00:00
|
|
|
<a href={`/topic/${props.topic.slug}`}>{capitalize(props.topic.title || '')}</a>
|
2022-11-09 19:02:12 +00:00
|
|
|
</h3>
|
2022-09-09 11:53:35 +00:00
|
|
|
</Show>
|
2022-09-30 14:22:33 +00:00
|
|
|
<Show when={props.topic.pic}>
|
2022-11-02 21:43:38 +00:00
|
|
|
<div class={styles.topicAvatar}>
|
2022-11-15 16:16:31 +00:00
|
|
|
<a href={`/topic/${props.topic.slug}`}>
|
2022-09-30 14:22:33 +00:00
|
|
|
<img src={props.topic.pic} alt={props.topic.title} />
|
2022-09-09 11:53:35 +00:00
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</Show>
|
|
|
|
|
2022-09-30 14:22:33 +00:00
|
|
|
<Show when={!props.compact && props.topic?.body}>
|
2022-10-14 18:33:06 +00:00
|
|
|
<div
|
2022-11-09 19:02:12 +00:00
|
|
|
class={clsx(styles.topicDescription, 'text-truncate')}
|
2022-10-14 18:33:06 +00:00
|
|
|
classList={{ 'topic-description--short': props.shortDescription }}
|
|
|
|
>
|
2022-09-30 14:22:33 +00:00
|
|
|
{props.topic.body}
|
2022-09-09 11:53:35 +00:00
|
|
|
</div>
|
|
|
|
</Show>
|
|
|
|
</div>
|
2022-11-09 19:02:12 +00:00
|
|
|
<div
|
|
|
|
class={styles.controlContainer}
|
|
|
|
classList={{ 'col-md-3': !props.compact && !props.subscribeButtonBottom }}
|
|
|
|
>
|
2022-12-01 18:45:35 +00:00
|
|
|
<ShowOnlyOnClient>
|
|
|
|
<Show when={session.state !== 'pending'}>
|
2022-11-16 21:08:04 +00:00
|
|
|
<button
|
2022-12-01 18:45:35 +00:00
|
|
|
onClick={() => subscribe(!subscribed())}
|
2022-11-16 21:08:04 +00:00
|
|
|
class="button--light button--subscribe-topic"
|
|
|
|
classList={{
|
2022-12-01 18:45:35 +00:00
|
|
|
[styles.buttonCompact]: props.compact,
|
|
|
|
[styles.isSubscribing]: isSubscribing()
|
2022-11-16 21:08:04 +00:00
|
|
|
}}
|
2022-12-01 18:45:35 +00:00
|
|
|
disabled={isSubscribing()}
|
2022-11-16 21:08:04 +00:00
|
|
|
>
|
2022-12-01 18:45:35 +00:00
|
|
|
<Show when={props.iconButton}>
|
|
|
|
<Show when={subscribed()} fallback="+">
|
|
|
|
-
|
|
|
|
</Show>
|
|
|
|
</Show>
|
|
|
|
<Show when={!props.iconButton}>
|
|
|
|
<Show when={subscribed()} fallback={t('Follow')}>
|
|
|
|
{t('Unfollow')}
|
|
|
|
</Show>
|
|
|
|
</Show>
|
2022-09-13 09:59:04 +00:00
|
|
|
</button>
|
2022-12-01 18:45:35 +00:00
|
|
|
</Show>
|
|
|
|
</ShowOnlyOnClient>
|
2022-09-09 11:53:35 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|