webapp/src/components/Article/FullArticle.tsx
2022-11-27 00:27:54 +03:00

164 lines
5.6 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, formatDate } from '../../utils'
import './Full.scss'
import { Icon } from '../_shared/Icon'
import { AuthorCard } from '../Author/Card'
import { createMemo, createSignal, For, onMount, Show } from 'solid-js'
import type { Author, Reaction, Shout } from '../../graphql/types.gen'
import { t } from '../../utils/intl'
import MD from './MD'
import { SharePopup } from './SharePopup'
import stylesHeader from '../Nav/Header.module.scss'
import styles from '../../styles/Article.module.scss'
import RatingControl from './RatingControl'
import { clsx } from 'clsx'
import { CommentsTree } from './CommentsTree'
interface ArticleProps {
article: Shout
}
export const FullArticle = (props: ArticleProps) => {
const formattedDate = createMemo(() => formatDate(new Date(props.article.createdAt)))
const [isSharePopupVisible, setIsSharePopupVisible] = createSignal(false)
const mainTopic = () =>
(props.article.topics?.find((topic) => topic?.slug === props.article.mainTopic)?.title || '').replace(
' ',
' '
)
onMount(() => {
const windowHash = window.location.hash
if (windowHash?.length > 0) {
const comments = document.querySelector(windowHash)
if (comments) {
window.scrollTo({
top: comments.getBoundingClientRect().top,
behavior: 'smooth'
})
}
}
})
return (
<div class="shout wide-container">
<article class="col-md-6 shift-content">
<div class={styles.shoutHeader}>
<div class={styles.shoutTopic}>
<a href={`/topic/${props.article.mainTopic}`} innerHTML={mainTopic() || ''} />
</div>
<h1>{props.article.title}</h1>
<Show when={props.article.subtitle}>
<h4>{capitalize(props.article.subtitle, false)}</h4>
</Show>
<div class={styles.shoutAuthor}>
<For each={props.article.authors}>
{(a: Author, index) => (
<>
<Show when={index() > 0}>, </Show>
<a href={`/author/${a.slug}`}>{a.name}</a>
</>
)}
</For>
</div>
<div class={styles.shoutCover} style={{ 'background-image': `url('${props.article.cover}')` }} />
</div>
<Show when={Boolean(props.article.body)}>
<div class={styles.shoutBody}>
<Show
when={!props.article.body.startsWith('<')}
fallback={<div innerHTML={props.article.body} />}
>
<MD body={props.article.body} />
</Show>
</div>
</Show>
</article>
<div class="col-md-8 shift-content">
<div class={styles.shoutStats}>
<div class={styles.shoutStatsItem}>
<RatingControl rating={props.article.stat?.rating} class={styles.ratingControl} />
</div>
<div class={styles.shoutStatsItem}>
<Icon name="comment" class={styles.icon} />
{props.article.stat?.commented || ''}
</div>
{/*FIXME*/}
{/*<div class={styles.shoutStatsItem}>*/}
{/* <a href="#bookmark" onClick={() => console.log(props.article.slug, 'articles')}>*/}
{/* <Icon name={'bookmark' + (bookmarked() ? '' : '-x')} />*/}
{/* </a>*/}
{/*</div>*/}
<div class={styles.shoutStatsItem}>
<SharePopup
onVisibilityChange={(isVisible) => {
setIsSharePopupVisible(isVisible)
}}
containerCssClass={stylesHeader.control}
trigger={<Icon name="share" class={styles.icon} />}
/>
</div>
<div class={styles.shoutStatsItem}>
<Icon name="bookmark" class={styles.icon} />
</div>
{/*FIXME*/}
{/*<Show when={canEdit()}>*/}
{/* <div class={styles.shoutStatsItem}>*/}
{/* <a href="/edit">*/}
{/* <Icon name="edit" />*/}
{/* {t('Edit')}*/}
{/* </a>*/}
{/* </div>*/}
{/*</Show>*/}
<div class={clsx(styles.shoutStatsItem, styles.shoutStatsItemAdditionalData)}>
<div class={clsx(styles.shoutStatsItem, styles.shoutStatsItemAdditionalDataItem)}>
{formattedDate()}
</div>
<Show when={props.article.stat?.viewed}>
<div class={clsx(styles.shoutStatsItem, styles.shoutStatsItemAdditionalDataItem)}>
<Icon name="view" class={styles.icon} />
{props.article.stat?.viewed}
</div>
</Show>
</div>
</div>
<div class={styles.help}>
<button class="button">Соучаствовать</button>
<button class="button button--light">Пригласить к участию</button>
</div>
<div class={styles.topicsList}>
<For each={props.article.topics}>
{(topic) => (
<div class={styles.shoutTopic}>
<a href={`/topic/${topic.slug}`}>{topic.title}</a>
</div>
)}
</For>
</div>
<div class={styles.shoutAuthorsList}>
<Show when={props.article?.authors?.length > 1}>
<h4>{t('Authors')}</h4>
</Show>
<For each={props.article?.authors}>
{(a: Author) => (
<div class="col-xl-6">
<AuthorCard author={a} compact={false} hasLink={true} liteButtons={true} />
</div>
)}
</For>
</div>
<CommentsTree shout={props.article?.slug} />
</div>
</div>
)
}