2022-11-09 19:02:12 +00:00
|
|
|
import { clsx } from 'clsx'
|
2024-03-15 15:24:33 +00:00
|
|
|
import { Show, createEffect, createMemo, createSignal } from 'solid-js'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
import { useFollowing } from '../../context/following'
|
2023-11-14 15:10:00 +00:00
|
|
|
import { useLocalize } from '../../context/localize'
|
2022-11-14 10:02:08 +00:00
|
|
|
import { useSession } from '../../context/session'
|
2024-01-31 12:34:15 +00:00
|
|
|
import { FollowingEntity, type Topic } from '../../graphql/schema/core.gen'
|
2023-11-14 15:10:00 +00:00
|
|
|
import { capitalize } from '../../utils/capitalize'
|
2024-02-04 11:25:21 +00:00
|
|
|
import { CardTopic } from '../Feed/CardTopic'
|
2023-11-14 15:10:00 +00:00
|
|
|
import { Button } from '../_shared/Button'
|
|
|
|
import { CheckButton } from '../_shared/CheckButton'
|
2022-12-15 20:13:57 +00:00
|
|
|
import { Icon } from '../_shared/Icon'
|
2023-11-14 15:10:00 +00:00
|
|
|
import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient'
|
2023-10-18 10:56:41 +00:00
|
|
|
|
2023-11-08 20:52:56 +00:00
|
|
|
import stylesButton from '../_shared/Button/Button.module.scss'
|
2024-02-04 11:25:21 +00:00
|
|
|
import styles from './Card.module.scss'
|
2022-09-30 14:22:33 +00:00
|
|
|
|
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
|
2023-05-17 20:27:24 +00:00
|
|
|
showDescription?: boolean
|
2023-06-05 20:46:55 +00:00
|
|
|
isCardMode?: boolean
|
2023-09-18 16:33:22 +00:00
|
|
|
minimizeSubscribeButton?: boolean
|
2023-09-27 21:28:32 +00:00
|
|
|
isNarrow?: boolean
|
2023-10-03 23:06:41 +00:00
|
|
|
withIcon?: boolean
|
2022-09-09 11:53:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const TopicCard = (props: TopicProps) => {
|
2023-12-08 11:49:50 +00:00
|
|
|
const { t, lang } = useLocalize()
|
2024-01-31 12:34:15 +00:00
|
|
|
const title = createMemo(() =>
|
|
|
|
capitalize(lang() === 'en' ? props.topic.slug.replaceAll('-', ' ') : props.topic.title || ''),
|
|
|
|
)
|
2024-02-04 17:40:15 +00:00
|
|
|
const { author, requireAuthentication } = useSession()
|
2024-03-15 15:24:33 +00:00
|
|
|
const [isSubscribed, setIsSubscribed] = createSignal()
|
|
|
|
const { follow, unfollow, subscriptions, subscribeInAction } = useFollowing()
|
|
|
|
|
|
|
|
createEffect(() => {
|
2024-05-01 14:33:37 +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)
|
|
|
|
setIsSubscribed(subscribed)
|
|
|
|
})
|
2022-12-01 18:45:35 +00:00
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
const handleFollowClick = () => {
|
2023-06-14 17:19:30 +00:00
|
|
|
requireAuthentication(() => {
|
2024-05-01 14:33:37 +00:00
|
|
|
isSubscribed()
|
|
|
|
? unfollow(FollowingEntity.Topic, props.topic.slug)
|
|
|
|
: follow(FollowingEntity.Topic, props.topic.slug)
|
2023-06-14 17:19:30 +00:00
|
|
|
}, 'subscribe')
|
|
|
|
}
|
|
|
|
|
2023-11-02 22:02:11 +00:00
|
|
|
const subscribeValue = () => {
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Show when={props.iconButton}>
|
2024-03-15 15:24:33 +00:00
|
|
|
<Show when={isSubscribed()} fallback="+">
|
2023-11-02 22:02:11 +00:00
|
|
|
<Icon name="check-subscribed" />
|
|
|
|
</Show>
|
|
|
|
</Show>
|
|
|
|
<Show when={!props.iconButton}>
|
2024-03-15 15:24:33 +00:00
|
|
|
<Show when={isSubscribed()} fallback={t('Follow')}>
|
2023-11-08 20:52:56 +00:00
|
|
|
<span class={stylesButton.buttonSubscribeLabelHovered}>{t('Unfollow')}</span>
|
|
|
|
<span class={stylesButton.buttonSubscribeLabel}>{t('Following')}</span>
|
2023-11-02 22:02:11 +00:00
|
|
|
</Show>
|
|
|
|
</Show>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-09-09 11:53:35 +00:00
|
|
|
return (
|
2023-06-05 20:46:55 +00:00
|
|
|
<div class={styles.topicContainer}>
|
|
|
|
<div
|
|
|
|
class={styles.topic}
|
|
|
|
classList={{
|
|
|
|
row: !props.subscribeButtonBottom,
|
|
|
|
[styles.topicCompact]: props.compact,
|
2023-11-14 15:10:00 +00:00
|
|
|
[styles.topicInRow]: props.isTopicInRow,
|
2023-06-05 20:46:55 +00:00
|
|
|
}}
|
|
|
|
>
|
2023-09-27 21:28:32 +00:00
|
|
|
<div
|
|
|
|
classList={{
|
|
|
|
[clsx('col-sm-18 col-md-24 col-lg-14 col-xl-15', styles.topicDetails)]: props.isNarrow,
|
2023-10-09 21:22:06 +00:00
|
|
|
[clsx('col-24 col-sm-17 col-md-18', styles.topicDetails)]: props.compact,
|
2024-02-04 17:40:15 +00:00
|
|
|
[clsx('col-sm-17 col-md-18', styles.topicDetails)]: !(
|
|
|
|
props.subscribeButtonBottom ||
|
|
|
|
props.isNarrow ||
|
|
|
|
props.compact
|
|
|
|
),
|
2023-09-27 21:28:32 +00:00
|
|
|
}}
|
|
|
|
>
|
2023-12-08 11:49:50 +00:00
|
|
|
<Show when={title() && !props.isCardMode}>
|
2023-06-05 20:46:55 +00:00
|
|
|
<h3 class={styles.topicTitle}>
|
2023-12-08 11:49:50 +00:00
|
|
|
<a href={`/topic/${props.topic.slug}`}>{title()}</a>
|
2023-06-05 20:46:55 +00:00
|
|
|
</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}`}>
|
2023-12-08 11:49:50 +00:00
|
|
|
<img src={props.topic.pic} alt={title()} />
|
2023-06-05 20:46:55 +00:00
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</Show>
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2023-06-05 20:46:55 +00:00
|
|
|
<Show when={props.showDescription && props.topic?.body}>
|
|
|
|
<div
|
|
|
|
class={clsx(styles.topicDescription, 'text-truncate')}
|
|
|
|
classList={{ [styles.topicDescriptionShort]: props.shortDescription }}
|
2022-11-16 21:08:04 +00:00
|
|
|
>
|
2023-06-05 20:46:55 +00:00
|
|
|
{props.topic.body}
|
|
|
|
</div>
|
|
|
|
</Show>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
class={styles.controlContainer}
|
2023-09-27 21:28:32 +00:00
|
|
|
classList={{
|
|
|
|
'col-sm-6 col-md-24 col-lg-10 col-xl-9': props.isNarrow,
|
2023-10-09 21:22:06 +00:00
|
|
|
'col-24 col-sm-7 col-md-6': props.compact,
|
2024-02-04 17:40:15 +00:00
|
|
|
'col-sm-7 col-md-6': !(props.subscribeButtonBottom || props.isNarrow || props.compact),
|
2023-09-27 21:28:32 +00:00
|
|
|
}}
|
2023-06-05 20:46:55 +00:00
|
|
|
>
|
|
|
|
<ShowOnlyOnClient>
|
2024-01-31 12:34:15 +00:00
|
|
|
<Show when={author()}>
|
2023-09-18 16:33:22 +00:00
|
|
|
<Show
|
|
|
|
when={!props.minimizeSubscribeButton}
|
|
|
|
fallback={
|
2024-01-31 12:34:15 +00:00
|
|
|
<CheckButton
|
|
|
|
text={t('Follow')}
|
2024-03-15 15:24:33 +00:00
|
|
|
checked={Boolean(isSubscribed())}
|
2024-01-31 12:34:15 +00:00
|
|
|
onClick={handleFollowClick}
|
|
|
|
/>
|
2023-09-18 16:33:22 +00:00
|
|
|
}
|
2023-06-05 20:46:55 +00:00
|
|
|
>
|
2023-11-02 22:02:11 +00:00
|
|
|
<Button
|
|
|
|
variant="bordered"
|
|
|
|
size="M"
|
|
|
|
value={subscribeValue()}
|
2024-01-31 12:34:15 +00:00
|
|
|
onClick={handleFollowClick}
|
2023-11-08 20:42:13 +00:00
|
|
|
isSubscribeButton={true}
|
2023-11-02 22:02:11 +00:00
|
|
|
class={clsx(styles.actionButton, {
|
2024-03-15 15:24:33 +00:00
|
|
|
[styles.isSubscribing]:
|
|
|
|
subscribeInAction()?.slug === props.topic.slug ? subscribeInAction().type : undefined,
|
|
|
|
[stylesButton.subscribed]: isSubscribed(),
|
2023-11-02 22:02:11 +00:00
|
|
|
})}
|
|
|
|
/>
|
2023-09-18 16:33:22 +00:00
|
|
|
</Show>
|
2023-06-05 20:46:55 +00:00
|
|
|
</Show>
|
|
|
|
</ShowOnlyOnClient>
|
|
|
|
</div>
|
2022-09-09 11:53:35 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|