webapp/src/components/Topic/Card.tsx
2023-10-16 12:54:14 +03:00

166 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { capitalize } from '../../utils'
import styles from './Card.module.scss'
import { createMemo, createSignal, Show } from 'solid-js'
import type { Topic } from '../../graphql/types.gen'
import { FollowingEntity } from '../../graphql/types.gen'
import { follow, unfollow } from '../../stores/zine/common'
import { clsx } from 'clsx'
import { useSession } from '../../context/session'
import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient'
import { Icon } from '../_shared/Icon'
import { useLocalize } from '../../context/localize'
import { CardTopic } from '../Feed/CardTopic'
import { CheckButton } from '../_shared/CheckButton'
interface TopicProps {
topic: Topic
compact?: boolean
subscribed?: boolean
shortDescription?: boolean
subscribeButtonBottom?: boolean
additionalClass?: string
isTopicInRow?: boolean
iconButton?: boolean
showPublications?: boolean
showDescription?: boolean
isCardMode?: boolean
minimizeSubscribeButton?: boolean
isNarrow?: boolean
withIcon?: boolean
}
export const TopicCard = (props: TopicProps) => {
const { t } = useLocalize()
const {
session,
isSessionLoaded,
actions: { loadSession, requireAuthentication }
} = useSession()
const [isSubscribing, setIsSubscribing] = createSignal(false)
const subscribed = createMemo(() => {
if (!session()?.user?.slug || !session()?.news?.topics) {
return false
}
return session()?.news.topics.includes(props.topic.slug)
})
const subscribe = async (really = true) => {
setIsSubscribing(true)
await (really
? follow({ what: FollowingEntity.Topic, slug: props.topic.slug })
: unfollow({ what: FollowingEntity.Topic, slug: props.topic.slug }))
await loadSession()
setIsSubscribing(false)
}
const handleSubscribe = () => {
requireAuthentication(() => {
subscribe(!subscribed())
}, 'subscribe')
}
return (
<div class={styles.topicContainer}>
<div
class={styles.topic}
classList={{
row: !props.subscribeButtonBottom,
[styles.topicCompact]: props.compact,
[styles.topicInRow]: props.isTopicInRow
}}
>
<div
classList={{
[clsx('col-sm-18 col-md-24 col-lg-14 col-xl-15', styles.topicDetails)]: props.isNarrow,
[clsx('col-24 col-sm-17 col-md-18', styles.topicDetails)]: props.compact,
[clsx('col-sm-17 col-md-18', styles.topicDetails)]:
!props.subscribeButtonBottom && !props.isNarrow && !props.compact
}}
>
<Show when={props.topic.title && !props.isCardMode}>
<h3 class={styles.topicTitle}>
<a href={`/topic/${props.topic.slug}`}>{capitalize(props.topic.title || '')}</a>
</h3>
</Show>
<Show when={props.isCardMode}>
<CardTopic title={props.topic.title} slug={props.topic.slug} class={styles.cardMode} />
</Show>
<Show when={props.topic.pic}>
<div class={styles.topicAvatar}>
<a href={`/topic/${props.topic.slug}`}>
<img src={props.topic.pic} alt={props.topic.title} />
</a>
</div>
</Show>
<Show when={props.showDescription && props.topic?.body}>
<div
class={clsx(styles.topicDescription, 'text-truncate')}
classList={{ [styles.topicDescriptionShort]: props.shortDescription }}
>
{props.topic.body}
</div>
</Show>
<Show when={props.showDescription && !props.topic?.body && props.topic.stat?.shouts > 0}>
<div
class={clsx(styles.topicDescription)}
classList={{ [styles.topicDescriptionShort]: props.shortDescription }}
>
{props.topic.stat?.shouts} публикаций
</div>
</Show>
</div>
<div
class={styles.controlContainer}
classList={{
'col-sm-6 col-md-24 col-lg-10 col-xl-9': props.isNarrow,
'col-24 col-sm-7 col-md-6': props.compact,
'col-sm-7 col-md-6': !props.subscribeButtonBottom && !props.isNarrow && !props.compact
}}
>
<ShowOnlyOnClient>
<Show when={isSessionLoaded()}>
<Show
when={!props.minimizeSubscribeButton}
fallback={
<CheckButton text={t('Follow')} checked={subscribed()} onClick={handleSubscribe} />
}
>
<button
onClick={handleSubscribe}
class="button--light button--subscribe-topic"
classList={{
[styles.isSubscribing]: isSubscribing(),
[styles.isSubscribed]: subscribed()
}}
disabled={isSubscribing()}
>
<Show when={props.iconButton}>
<Show when={subscribed()} fallback="+">
<Icon name="check-subscribed" />
</Show>
</Show>
<Show when={!props.iconButton}>
<Show when={subscribed()} fallback={t('Follow')}>
<span class={styles.buttonUnfollowLabel}>{t('Unfollow')}</span>
<span class={styles.buttonSubscribedLabel}>{t('Following')}</span>
</Show>
</Show>
</button>
</Show>
</Show>
</ShowOnlyOnClient>
</div>
</div>
</div>
)
}