2024-06-24 17:50:27 +00:00
|
|
|
import { For, Show, createEffect, createMemo, createSignal, on } from 'solid-js'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2024-07-03 17:38:43 +00:00
|
|
|
import { Meta } from '@solidjs/meta'
|
2024-07-04 07:51:15 +00:00
|
|
|
import enKeywords from '~/config/locales/en/keywords.json'
|
|
|
|
import ruKeywords from '~/config/locales/ru/keywords.json'
|
2024-06-24 17:50:27 +00:00
|
|
|
import { useAuthors } from '~/context/authors'
|
2024-07-04 07:51:15 +00:00
|
|
|
import { useLocalize } from '~/context/localize'
|
|
|
|
import { useTopics } from '~/context/topics'
|
|
|
|
import { loadShouts } from '~/graphql/api/public'
|
|
|
|
import { Author, Shout, Topic } from '~/graphql/schema/core.gen'
|
2024-07-03 17:38:43 +00:00
|
|
|
import { SHOUTS_PER_PAGE } from '~/routes/(home)'
|
2024-07-04 07:51:15 +00:00
|
|
|
import { capitalize } from '~/utils/capitalize'
|
|
|
|
import { splitToPages } from '~/utils/splitToPages'
|
2023-11-14 15:10:00 +00:00
|
|
|
import Banner from '../Discours/Banner'
|
|
|
|
import Hero from '../Discours/Hero'
|
|
|
|
import { Beside } from '../Feed/Beside'
|
|
|
|
import Group from '../Feed/Group'
|
|
|
|
import { Row1 } from '../Feed/Row1'
|
|
|
|
import { Row2 } from '../Feed/Row2'
|
|
|
|
import { Row3 } from '../Feed/Row3'
|
|
|
|
import { Row5 } from '../Feed/Row5'
|
|
|
|
import RowShort from '../Feed/RowShort'
|
|
|
|
import { Topics } from '../Nav/Topics'
|
2024-02-04 11:25:21 +00:00
|
|
|
import { Icon } from '../_shared/Icon'
|
|
|
|
import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper'
|
2023-12-21 10:39:26 +00:00
|
|
|
import styles from './Home.module.scss'
|
|
|
|
|
2022-11-22 03:02:11 +00:00
|
|
|
export const RANDOM_TOPICS_COUNT = 12
|
2023-12-20 23:59:16 +00:00
|
|
|
export const RANDOM_TOPIC_SHOUTS_COUNT = 7
|
2022-09-29 14:40:11 +00:00
|
|
|
const CLIENT_LOAD_ARTICLES_COUNT = 29
|
|
|
|
const LOAD_MORE_PAGE_SIZE = 16 // Row1 + Row3 + Row2 + Beside (3 + 1) + Row1 + Row 2 + Row3
|
2022-09-13 09:59:04 +00:00
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
export interface HomeViewProps {
|
|
|
|
featuredShouts: Shout[]
|
|
|
|
topRatedShouts: Shout[]
|
|
|
|
topMonthShouts: Shout[]
|
|
|
|
topViewedShouts: Shout[]
|
|
|
|
topCommentedShouts: Shout[]
|
|
|
|
}
|
2023-09-14 11:40:46 +00:00
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
export const HomeView = (props: HomeViewProps) => {
|
2024-07-03 17:38:43 +00:00
|
|
|
const { t, lang } = useLocalize()
|
2024-06-28 07:47:38 +00:00
|
|
|
const { topAuthors, addAuthors } = useAuthors()
|
2024-06-24 17:50:27 +00:00
|
|
|
const { topTopics, randomTopic } = useTopics()
|
|
|
|
const [randomTopicArticles, setRandomTopicArticles] = createSignal<Shout[]>([])
|
|
|
|
createEffect(
|
|
|
|
on(
|
|
|
|
() => randomTopic(),
|
|
|
|
async (topic?: Topic) => {
|
|
|
|
if (topic) {
|
|
|
|
const shoutsByTopicLoader = loadShouts({
|
|
|
|
filters: { topic: topic.slug, featured: true },
|
|
|
|
limit: 5,
|
2024-06-26 08:22:05 +00:00
|
|
|
offset: 0
|
2024-06-24 17:50:27 +00:00
|
|
|
})
|
|
|
|
const shouts = await shoutsByTopicLoader()
|
|
|
|
setRandomTopicArticles(shouts || [])
|
2024-06-28 07:47:38 +00:00
|
|
|
shouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
|
|
|
props.featuredShouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
|
|
|
props.topRatedShouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
2024-06-24 17:50:27 +00:00
|
|
|
}
|
|
|
|
},
|
2024-06-26 08:22:05 +00:00
|
|
|
{ defer: true }
|
|
|
|
)
|
2024-06-24 17:50:27 +00:00
|
|
|
)
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2022-10-28 21:21:47 +00:00
|
|
|
const pages = createMemo<Shout[][]>(() =>
|
|
|
|
splitToPages(
|
2024-06-24 17:50:27 +00:00
|
|
|
props.featuredShouts || [],
|
|
|
|
SHOUTS_PER_PAGE + CLIENT_LOAD_ARTICLES_COUNT,
|
2024-06-26 08:22:05 +00:00
|
|
|
LOAD_MORE_PAGE_SIZE
|
|
|
|
)
|
2022-10-28 21:21:47 +00:00
|
|
|
)
|
2022-09-29 14:40:11 +00:00
|
|
|
|
2022-09-22 09:37:49 +00:00
|
|
|
return (
|
2024-07-03 17:38:43 +00:00
|
|
|
<>
|
|
|
|
<Meta name="keywords" content={`${lang() === 'ru' ? ruKeywords[''] : enKeywords['']}`} />
|
|
|
|
<Show when={(props.featuredShouts || []).length > 0}>
|
|
|
|
<Topics />
|
|
|
|
<Row5 articles={props.featuredShouts.slice(0, 5)} nodate={true} />
|
|
|
|
<Hero />
|
|
|
|
<Show when={props.featuredShouts?.length > SHOUTS_PER_PAGE}>
|
|
|
|
<Beside
|
|
|
|
beside={props.featuredShouts[5]}
|
|
|
|
title={t('Top viewed')}
|
|
|
|
values={props.topViewedShouts.slice(0, 5)}
|
|
|
|
wrapper={'top-article'}
|
|
|
|
nodate={true}
|
|
|
|
/>
|
|
|
|
<Row3 articles={(props.featuredShouts || []).slice(6, 9)} nodate={true} />
|
|
|
|
<Beside
|
|
|
|
beside={props.featuredShouts[9]}
|
|
|
|
title={t('Top authors')}
|
|
|
|
values={topAuthors?.() || []}
|
|
|
|
wrapper={'author'}
|
|
|
|
nodate={true}
|
|
|
|
/>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
2024-07-03 17:38:43 +00:00
|
|
|
<ArticleCardSwiper title={t('Top month')} slides={props.topMonthShouts} />
|
2024-06-24 17:50:27 +00:00
|
|
|
|
2024-07-03 17:38:43 +00:00
|
|
|
<Row2 articles={props.featuredShouts.slice(10, 12)} nodate={true} />
|
|
|
|
<RowShort articles={props.featuredShouts.slice(12, 16)} />
|
|
|
|
<Row1 article={props.featuredShouts[16]} nodate={true} />
|
|
|
|
<Row3 articles={props.featuredShouts.slice(17, 20)} nodate={true} />
|
|
|
|
<Row3
|
|
|
|
articles={props.topCommentedShouts?.slice(0, 3) || []}
|
|
|
|
header={<h2>{t('Top commented')}</h2>}
|
|
|
|
nodate={true}
|
2023-12-21 10:39:26 +00:00
|
|
|
/>
|
2024-07-03 17:38:43 +00:00
|
|
|
<Show when={Boolean(randomTopic())}>
|
|
|
|
<Group
|
|
|
|
articles={randomTopicArticles() || []}
|
|
|
|
header={
|
|
|
|
<div class={styles.randomTopicHeaderContainer}>
|
|
|
|
<div class={styles.randomTopicHeader}>{capitalize(randomTopic()?.title || '', true)}</div>
|
|
|
|
<div>
|
|
|
|
<a class={styles.randomTopicHeaderLink} href={`/topic/${randomTopic()?.slug || ''}`}>
|
|
|
|
{t('All articles')} <Icon class={styles.icon} name="arrow-right" />
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</Show>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
2024-07-03 17:38:43 +00:00
|
|
|
<ArticleCardSwiper title={t('Favorite')} slides={props.topRatedShouts} />
|
2024-06-24 17:50:27 +00:00
|
|
|
|
2024-07-03 17:38:43 +00:00
|
|
|
<Beside
|
|
|
|
beside={props.featuredShouts[20]}
|
|
|
|
title={t('Top topics')}
|
|
|
|
values={topTopics().slice(0, 5)}
|
|
|
|
wrapper={'topic'}
|
|
|
|
isTopicCompact={true}
|
|
|
|
nodate={true}
|
|
|
|
/>
|
|
|
|
<Row3 articles={props.featuredShouts.slice(21, 24)} nodate={true} />
|
|
|
|
<Banner />
|
|
|
|
<Row2 articles={props.featuredShouts.slice(24, 26)} nodate={true} />
|
|
|
|
<Row3 articles={props.featuredShouts.slice(26, 29)} nodate={true} />
|
|
|
|
<Row2 articles={props.featuredShouts.slice(29, 31)} nodate={true} />
|
|
|
|
<Row3 articles={props.featuredShouts.slice(31, 34)} nodate={true} />
|
|
|
|
</Show>
|
|
|
|
<For each={pages()}>
|
|
|
|
{(page) => (
|
|
|
|
<>
|
|
|
|
<Row1 article={page[0]} nodate={true} />
|
|
|
|
<Row3 articles={page.slice(1, 4)} nodate={true} />
|
|
|
|
<Row2 articles={page.slice(4, 6)} nodate={true} />
|
|
|
|
<Beside values={page.slice(6, 9)} beside={page[9]} wrapper="article" nodate={true} />
|
|
|
|
<Row1 article={page[10]} nodate={true} />
|
|
|
|
<Row2 articles={page.slice(11, 13)} nodate={true} />
|
|
|
|
<Row3 articles={page.slice(13, 16)} nodate={true} />
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</For>
|
2022-09-28 20:16:44 +00:00
|
|
|
</Show>
|
2024-07-03 17:38:43 +00:00
|
|
|
</>
|
2022-09-09 11:53:35 +00:00
|
|
|
)
|
|
|
|
}
|