2022-10-25 16:25:42 +00:00
|
|
|
import { createMemo, For, onMount, Show } from 'solid-js'
|
2022-09-09 11:53:35 +00:00
|
|
|
import Banner from '../Discours/Banner'
|
2022-09-22 09:37:49 +00:00
|
|
|
import { NavTopics } from '../Nav/Topics'
|
|
|
|
import { Row5 } from '../Feed/Row5'
|
2022-09-09 11:53:35 +00:00
|
|
|
import Row3 from '../Feed/Row3'
|
|
|
|
import Row2 from '../Feed/Row2'
|
|
|
|
import Row1 from '../Feed/Row1'
|
|
|
|
import Hero from '../Discours/Hero'
|
|
|
|
import Beside from '../Feed/Beside'
|
|
|
|
import RowShort from '../Feed/RowShort'
|
|
|
|
import Slider from '../Feed/Slider'
|
|
|
|
import Group from '../Feed/Group'
|
2022-09-22 09:37:49 +00:00
|
|
|
import { getLogger } from '../../utils/logger'
|
2022-09-09 11:53:35 +00:00
|
|
|
import type { Shout, Topic } from '../../graphql/types.gen'
|
2022-09-22 09:37:49 +00:00
|
|
|
import { Icon } from '../Nav/Icon'
|
2022-09-09 11:53:35 +00:00
|
|
|
import { t } from '../../utils/intl'
|
|
|
|
import { useTopicsStore } from '../../stores/zine/topics'
|
2022-09-22 09:37:49 +00:00
|
|
|
import {
|
|
|
|
loadPublishedArticles,
|
|
|
|
loadTopArticles,
|
|
|
|
loadTopMonthArticles,
|
|
|
|
useArticlesStore
|
|
|
|
} from '../../stores/zine/articles'
|
|
|
|
import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
|
2022-09-23 23:42:19 +00:00
|
|
|
import { locale } from '../../stores/ui'
|
2022-09-29 14:40:11 +00:00
|
|
|
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
2022-09-22 09:37:49 +00:00
|
|
|
|
|
|
|
const log = getLogger('home view')
|
2022-09-09 11:53:35 +00:00
|
|
|
|
|
|
|
type HomeProps = {
|
|
|
|
randomTopics: Topic[]
|
|
|
|
recentPublishedArticles: Shout[]
|
|
|
|
}
|
2022-09-29 14:40:11 +00:00
|
|
|
const PRERENDERED_ARTICLES_COUNT = 5
|
|
|
|
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
|
|
|
|
2022-09-22 09:37:49 +00:00
|
|
|
export const HomeView = (props: HomeProps) => {
|
2022-09-13 09:59:04 +00:00
|
|
|
const {
|
2022-09-28 20:16:44 +00:00
|
|
|
sortedArticles,
|
|
|
|
topArticles,
|
|
|
|
topMonthArticles,
|
|
|
|
topViewedArticles,
|
|
|
|
topCommentedArticles,
|
|
|
|
articlesByLayout
|
2022-09-13 09:59:04 +00:00
|
|
|
} = useArticlesStore({
|
2022-09-22 09:37:49 +00:00
|
|
|
sortedArticles: props.recentPublishedArticles
|
2022-09-13 08:05:11 +00:00
|
|
|
})
|
2022-09-28 20:16:44 +00:00
|
|
|
const { randomTopics, topTopics } = useTopicsStore({
|
2022-09-13 09:59:04 +00:00
|
|
|
randomTopics: props.randomTopics
|
|
|
|
})
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
const { topAuthors } = useTopAuthorsStore()
|
2022-09-13 09:59:04 +00:00
|
|
|
|
2022-09-22 09:37:49 +00:00
|
|
|
onMount(() => {
|
|
|
|
loadTopArticles()
|
|
|
|
loadTopMonthArticles()
|
2022-09-29 14:40:11 +00:00
|
|
|
if (sortedArticles().length < PRERENDERED_ARTICLES_COUNT + CLIENT_LOAD_ARTICLES_COUNT) {
|
|
|
|
loadPublishedArticles({ limit: CLIENT_LOAD_ARTICLES_COUNT, offset: sortedArticles().length })
|
|
|
|
}
|
2022-09-22 09:37:49 +00:00
|
|
|
})
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2022-09-22 09:37:49 +00:00
|
|
|
const randomLayout = createMemo(() => {
|
2022-09-28 20:16:44 +00:00
|
|
|
const filledLayouts = Object.keys(articlesByLayout()).filter(
|
2022-09-22 09:37:49 +00:00
|
|
|
// FIXME: is 7 ok? or more complex logic needed?
|
2022-09-28 20:16:44 +00:00
|
|
|
(layout) => articlesByLayout()[layout].length > 7
|
2022-09-22 09:37:49 +00:00
|
|
|
)
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
const selectedRandomLayout =
|
2022-09-22 09:37:49 +00:00
|
|
|
filledLayouts.length > 0 ? filledLayouts[Math.floor(Math.random() * filledLayouts.length)] : ''
|
|
|
|
|
|
|
|
return (
|
2022-09-28 20:16:44 +00:00
|
|
|
<Show when={Boolean(selectedRandomLayout)}>
|
2022-09-09 11:53:35 +00:00
|
|
|
<Group
|
2022-09-28 20:16:44 +00:00
|
|
|
articles={articlesByLayout()[selectedRandomLayout]}
|
2022-09-09 11:53:35 +00:00
|
|
|
header={
|
|
|
|
<div class="layout-icon">
|
2022-09-28 20:16:44 +00:00
|
|
|
<Icon name={selectedRandomLayout} />
|
2022-09-09 11:53:35 +00:00
|
|
|
</div>
|
|
|
|
}
|
|
|
|
/>
|
2022-09-22 09:37:49 +00:00
|
|
|
</Show>
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2022-09-29 14:40:11 +00:00
|
|
|
const loadMore = async () => {
|
|
|
|
saveScrollPosition()
|
|
|
|
await loadPublishedArticles({ limit: LOAD_MORE_PAGE_SIZE, offset: sortedArticles().length })
|
|
|
|
restoreScrollPosition()
|
2022-09-22 09:37:49 +00:00
|
|
|
}
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2022-09-29 14:40:11 +00:00
|
|
|
const pages = createMemo<Shout[][]>(() => {
|
|
|
|
return sortedArticles()
|
|
|
|
.slice(PRERENDERED_ARTICLES_COUNT + CLIENT_LOAD_ARTICLES_COUNT)
|
|
|
|
.reduce((acc, article, index) => {
|
|
|
|
if (index % LOAD_MORE_PAGE_SIZE === 0) {
|
|
|
|
acc.push([])
|
|
|
|
}
|
|
|
|
|
|
|
|
acc[acc.length - 1].push(article)
|
|
|
|
return acc
|
|
|
|
}, [] as Shout[][])
|
|
|
|
})
|
|
|
|
|
2022-09-22 09:37:49 +00:00
|
|
|
return (
|
2022-10-05 15:11:14 +00:00
|
|
|
<Show when={locale() && sortedArticles().length > 0}>
|
2022-09-28 20:16:44 +00:00
|
|
|
<NavTopics topics={randomTopics()} />
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<Row5 articles={sortedArticles().slice(0, 5)} />
|
2022-09-22 09:37:49 +00:00
|
|
|
|
|
|
|
<Hero />
|
|
|
|
|
2022-10-05 11:42:13 +00:00
|
|
|
<Show when={sortedArticles().length > PRERENDERED_ARTICLES_COUNT}>
|
2022-09-09 11:53:35 +00:00
|
|
|
<Beside
|
2022-09-28 20:16:44 +00:00
|
|
|
beside={sortedArticles()[5]}
|
|
|
|
title={t('Top viewed')}
|
|
|
|
values={topViewedArticles().slice(0, 5)}
|
|
|
|
wrapper={'top-article'}
|
2022-09-09 11:53:35 +00:00
|
|
|
/>
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<Row3 articles={sortedArticles().slice(6, 9)} />
|
|
|
|
|
2022-09-29 14:40:11 +00:00
|
|
|
<Beside
|
|
|
|
beside={sortedArticles()[9]}
|
|
|
|
title={t('Top authors')}
|
|
|
|
values={topAuthors()}
|
|
|
|
wrapper={'author'}
|
|
|
|
/>
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<Slider title={t('Top month articles')} articles={topMonthArticles()} />
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<Row2 articles={sortedArticles().slice(10, 12)} />
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<RowShort articles={sortedArticles().slice(12, 16)} />
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-29 14:40:11 +00:00
|
|
|
<Row1 article={sortedArticles()[16]} />
|
2022-09-28 20:16:44 +00:00
|
|
|
<Row3 articles={sortedArticles().slice(17, 20)} />
|
2022-09-29 14:40:11 +00:00
|
|
|
<Row3 articles={topCommentedArticles().slice(0, 3)} header={<h2>{t('Top commented')}</h2>} />
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
{randomLayout()}
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<Slider title={t('Favorite')} articles={topArticles()} />
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<Beside
|
|
|
|
beside={sortedArticles()[20]}
|
|
|
|
title={t('Top topics')}
|
|
|
|
values={topTopics().slice(0, 5)}
|
|
|
|
wrapper={'topic'}
|
|
|
|
isTopicCompact={true}
|
|
|
|
/>
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<Row3 articles={sortedArticles().slice(21, 24)} />
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-28 20:16:44 +00:00
|
|
|
<Banner />
|
|
|
|
|
|
|
|
<Row2 articles={sortedArticles().slice(24, 26)} />
|
|
|
|
<Row3 articles={sortedArticles().slice(26, 29)} />
|
|
|
|
<Row2 articles={sortedArticles().slice(29, 31)} />
|
|
|
|
<Row3 articles={sortedArticles().slice(31, 34)} />
|
|
|
|
</Show>
|
2022-09-22 09:37:49 +00:00
|
|
|
|
2022-09-29 14:40:11 +00:00
|
|
|
<For each={pages()}>
|
|
|
|
{(page) => (
|
|
|
|
<>
|
|
|
|
<Row1 article={page[0]} />
|
|
|
|
<Row3 articles={page.slice(1, 4)} />
|
|
|
|
<Row2 articles={page.slice(4, 6)} />
|
|
|
|
<Beside values={page.slice(6, 9)} beside={page[9]} wrapper="article" />
|
|
|
|
<Row1 article={page[10]} />
|
|
|
|
<Row2 articles={page.slice(11, 13)} />
|
|
|
|
<Row3 articles={page.slice(13, 16)} />
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</For>
|
2022-09-22 09:37:49 +00:00
|
|
|
|
|
|
|
<p class="load-more-container">
|
|
|
|
<button class="button" onClick={loadMore}>
|
|
|
|
{t('Load more')}
|
|
|
|
</button>
|
|
|
|
</p>
|
2022-09-23 23:42:19 +00:00
|
|
|
</Show>
|
2022-09-09 11:53:35 +00:00
|
|
|
)
|
|
|
|
}
|