import { Author, AuthorsBy, LoadShoutsOptions, Shout, Topic } from '../../graphql/schema/core.gen' import { clsx } from 'clsx' import { For, Show, createEffect, createMemo, createSignal, on, onMount } from 'solid-js' import { Meta } from '../../context/meta' import { useLocalize } from '../../context/localize' import { useTopics } from '../../context/topics' import { useRouter } from '../../stores/router' import { loadShouts, useArticlesStore } from '../../stores/zine/articles' import { useAuthorsStore } from '../../stores/zine/authors' import { capitalize } from '../../utils/capitalize' import { getImageUrl } from '../../utils/getImageUrl' import { getDescription } from '../../utils/meta' import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll' import { splitToPages } from '../../utils/splitToPages' import { Beside } from '../Feed/Beside' import { Row1 } from '../Feed/Row1' import { Row2 } from '../Feed/Row2' import { Row3 } from '../Feed/Row3' import { FullTopic } from '../Topic/Full' import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper' import { apiClient } from '../../graphql/client/core' import styles from '../../styles/Topic.module.scss' import { getUnixtime } from '../../utils/getServerDate' type TopicsPageSearchParams = { by: 'comments' | '' | 'recent' | 'viewed' | 'rating' | 'commented' } interface Props { topic: Topic shouts: Shout[] topicSlug: string followers?: Author[] } export const PRERENDERED_ARTICLES_COUNT = 28 const LOAD_MORE_PAGE_SIZE = 9 // Row3 + Row3 + Row3 export const TopicView = (props: Props) => { const { t, lang } = useLocalize() const { searchParams, changeSearchParams } = useRouter() const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) const { sortedArticles } = useArticlesStore({ shouts: props.shouts }) const { topicEntities } = useTopics() const { authorsByTopic } = useAuthorsStore() const [favoriteTopArticles, setFavoriteTopArticles] = createSignal([]) const [reactedTopMonthArticles, setReactedTopMonthArticles] = createSignal([]) const [topic, setTopic] = createSignal() createEffect( on([() => props.topicSlug, topic, topicEntities], ([slug, t, ttt]) => { if (slug && !t && ttt) { console.debug(`${ttt.length} topics preloaded`) const current = ttt[slug] console.debug(current) setTopic(current) loadTopicFollowers() loadTopicAuthors() loadRandom() } }), ) const [followers, setFollowers] = createSignal(props.followers || []) const loadTopicFollowers = async () => { const result = await apiClient.getTopicFollowers({ slug: props.topicSlug }) setFollowers(result) } const loadFavoriteTopArticles = async (topic: string) => { const options: LoadShoutsOptions = { filters: { featured: true, topic: topic }, limit: 10, random_limit: 100, } const result = await apiClient.getRandomTopShouts({ options }) setFavoriteTopArticles(result) } const loadReactedTopMonthArticles = async (topic: string) => { const now = new Date() const after = getUnixtime(new Date(now.setMonth(now.getMonth() - 1))) const options: LoadShoutsOptions = { filters: { after: after, featured: true, topic: topic }, limit: 10, random_limit: 10, } const result = await apiClient.getRandomTopShouts({ options }) setReactedTopMonthArticles(result) } const [topicAuthors, setTopicAuthors] = createSignal([]) const loadTopicAuthors = async () => { const by: AuthorsBy = { topic: props.topicSlug } const result = await apiClient.loadAuthorsBy({ by }) setTopicAuthors(result) } const loadRandom = () => { loadFavoriteTopArticles(topic()?.slug) loadReactedTopMonthArticles(topic()?.slug) } const title = createMemo( () => `#${capitalize( lang() === 'en' ? topic()?.slug.replace(/-/, ' ') : topic()?.title || topic()?.slug.replace(/-/, ' '), true, )}`, ) const loadMore = async () => { saveScrollPosition() const { hasMore } = await loadShouts({ filters: { topic: topic()?.slug }, limit: LOAD_MORE_PAGE_SIZE, offset: sortedArticles().length, }) setIsLoadMoreButtonVisible(hasMore) restoreScrollPosition() } onMount(() => { loadRandom() if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) { loadMore() } }) /* const selectionTitle = createMemo(() => { const m = searchParams().by if (m === 'viewed') return t('Top viewed') if (m === 'rating') return t('Top rated') if (m === 'commented') return t('Top discussed') return t('Top recent') }) */ const pages = createMemo(() => splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE), ) const ogImage = () => topic()?.pic ? getImageUrl(topic().pic, { width: 1200 }) : getImageUrl('production/image/logo_image.png') const description = () => topic()?.body ? getDescription(topic().body) : t('The most interesting publications on the topic', { topicName: title() }) return (
  • {/*TODO: server sort*/} {/*
  • */} {/* */} {/*
  • */} {/*
  • */} {/* */} {/*
  • */} {/*
  • */} {/* */} {/*
  • */}
{`${t('Show')} `} {t('All posts')}
0} keyed={true}> 0} keyed={true}> 15}> {(page) => ( <> )}

) }