import { createMemo, For, Show } from 'solid-js' import type { Shout } from '../../graphql/types.gen' import { capitalize } from '../../utils' import { translit } from '../../utils/ru2en' import { Icon } from '../_shared/Icon' import styles from './Card.module.scss' import { clsx } from 'clsx' import { CardTopic } from './CardTopic' import { RatingControl } from '../Article/RatingControl' import { getShareUrl, SharePopup } from '../Article/SharePopup' import stylesHeader from '../Nav/Header.module.scss' import { getDescription } from '../../utils/meta' import { FeedArticlePopup } from './FeedArticlePopup' import { useLocalize } from '../../context/localize' import { ReactionKind } from '../../graphql/types.gen' import { loadShout } from '../../stores/zine/articles' import { useReactions } from '../../context/reactions' import { checkReaction } from '../../utils/checkReaction' import { useSession } from '../../context/session' interface ArticleCardProps { settings?: { noicon?: boolean noimage?: boolean nosubtitle?: boolean noauthor?: boolean nodate?: boolean isGroup?: boolean photoBottom?: boolean additionalClass?: string isFeedMode?: boolean isFloorImportant?: boolean isWithCover?: boolean isBigTitle?: boolean isVertical?: boolean isShort?: boolean withBorder?: boolean isCompact?: boolean isSingle?: boolean isBeside?: boolean } article: Shout } const getTitleAndSubtitle = (article: Shout): { title: string; subtitle: string } => { let title = article.title let subtitle = article.subtitle if (!subtitle) { let tt = article.title?.split('. ') || [] if (tt?.length === 1) { tt = article.title?.split(/{!|\?|:|;}\s/) || [] } if (tt && tt.length > 1) { const sep = article.title?.replace(tt[0], '').split(' ', 1)[0] title = tt[0] + (sep === '.' || sep === ':' ? '' : sep) subtitle = capitalize(article.title?.replace(tt[0] + sep, ''), true) } } return { title, subtitle } } export const ArticleCard = (props: ArticleCardProps) => { const { t, lang } = useLocalize() const { userSlug } = useSession() const { reactionEntities, actions: { createReaction, deleteReaction, loadReactionsBy } } = useReactions() const mainTopic = props.article.topics.find((articleTopic) => articleTopic.slug === props.article.mainTopic) || props.article.topics[0] const formattedDate = createMemo(() => { return new Date(props.article.createdAt) .toLocaleDateString(lang(), { month: 'long', day: 'numeric', year: 'numeric' }) .replace(' г.', '') }) const { title, subtitle } = getTitleAndSubtitle(props.article) const { cover, layout, slug, authors, stat, body, id } = props.article const updateReactions = () => { loadReactionsBy({ by: { shout: slug } }) } const isUpvoted = createMemo(() => checkReaction(Object.values(reactionEntities), ReactionKind.Like, userSlug(), id) ) const isDownvoted = createMemo(() => checkReaction(Object.values(reactionEntities), ReactionKind.Dislike, userSlug(), id) ) const deleteShoutReaction = async (reactionKind: ReactionKind) => { const reactionToDelete = Object.values(reactionEntities).find( (r) => r.kind === reactionKind && r.createdBy.slug === userSlug() && r.shout.id === id && !r.replyTo ) return deleteReaction(reactionToDelete.id) } const handleRatingChange = async (isUpvote: boolean) => { if (isUpvote) { if (isUpvoted()) { await deleteShoutReaction(ReactionKind.Like) } else if (isDownvoted()) { await deleteShoutReaction(ReactionKind.Dislike) } else { await createReaction({ kind: ReactionKind.Like, shout: id }) } } else { if (isDownvoted()) { await deleteShoutReaction(ReactionKind.Dislike) } else if (isUpvoted()) { await deleteShoutReaction(ReactionKind.Like) } else { await createReaction({ kind: ReactionKind.Dislike, shout: id }) } } loadShout(slug) updateReactions() } return (
{title
{(author, index) => { let name = author.name if (lang() !== 'ru') { name = name === 'Дискурс' ? 'Discours' : translit(name) } return ( <> 0}>, {name} ) }}
{formattedDate()}
handleRatingChange(true)} onDownvote={() => handleRatingChange(false)} isUpvoted={isUpvoted()} isDownvoted={isDownvoted()} />
{stat?.viewed}
} />
} />
) }