import { getPagePath } from '@nanostores/router' import { clsx } from 'clsx' import { createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show } from 'solid-js' import { useLocalize } from '../../../context/localize' import { LoadRandomTopShoutsParams, LoadShoutsFilters, LoadShoutsOptions, Shout, } from '../../../graphql/types.gen' import { LayoutType } from '../../../pages/types' import { router } from '../../../stores/router' import { loadShouts, resetSortedArticles, useArticlesStore } from '../../../stores/zine/articles' import { apiClient } from '../../../utils/apiClient' import { getServerDate } from '../../../utils/getServerDate' import { restoreScrollPosition, saveScrollPosition } from '../../../utils/scroll' import { splitToPages } from '../../../utils/splitToPages' import { Button } from '../../_shared/Button' import { ConditionalWrapper } from '../../_shared/ConditionalWrapper' import { Loading } from '../../_shared/Loading' import { ArticleCardSwiper } from '../../_shared/SolidSwiper/ArticleCardSwiper' import { ArticleCard } from '../../Feed/ArticleCard' import styles from './Expo.module.scss' type Props = { shouts: Shout[] layout: LayoutType } export const PRERENDERED_ARTICLES_COUNT = 24 const LOAD_MORE_PAGE_SIZE = 16 export const Expo = (props: Props) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.shouts)) const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) const [randomTopArticles, setRandomTopArticles] = createSignal([]) const [randomTopMonthArticles, setRandomTopMonthArticles] = createSignal([]) const { t } = useLocalize() const { sortedArticles } = useArticlesStore({ shouts: isLoaded() ? props.shouts : [], }) const getLoadShoutsFilters = (filters: LoadShoutsFilters = {}): LoadShoutsFilters => { const result = { ...filters } if (props.layout) { filters.layout = props.layout } else { filters.excludeLayout = 'article' } return result } const loadMore = async (count: number) => { const options: LoadShoutsOptions = { filters: getLoadShoutsFilters(), limit: count, offset: sortedArticles().length, } const { hasMore } = await loadShouts(options) setIsLoadMoreButtonVisible(hasMore) } const loadMoreWithoutScrolling = async (count: number) => { saveScrollPosition() await loadMore(count) restoreScrollPosition() } const loadRandomTopArticles = async () => { const params: LoadRandomTopShoutsParams = { filters: getLoadShoutsFilters(), limit: 10, fromRandomCount: 100, } const result = await apiClient.getRandomTopShouts(params) setRandomTopArticles(result) } const loadRandomTopMonthArticles = async () => { const now = new Date() const fromDate = getServerDate(new Date(now.setMonth(now.getMonth() - 1))) const params: LoadRandomTopShoutsParams = { filters: getLoadShoutsFilters({ fromDate }), limit: 10, fromRandomCount: 10, } const result = await apiClient.getRandomTopShouts(params) setRandomTopMonthArticles(result) } const pages = createMemo(() => splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE), ) onMount(() => { if (isLoaded()) { return } loadMore(PRERENDERED_ARTICLES_COUNT + LOAD_MORE_PAGE_SIZE) setIsLoaded(true) }) onMount(() => { if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) { loadMore(LOAD_MORE_PAGE_SIZE) } loadRandomTopArticles() loadRandomTopMonthArticles() }) createEffect( on( () => props.layout, () => { resetSortedArticles() setRandomTopArticles([]) setRandomTopMonthArticles([]) loadMore(PRERENDERED_ARTICLES_COUNT + LOAD_MORE_PAGE_SIZE) loadRandomTopArticles() loadRandomTopMonthArticles() }, { defer: true }, ), ) onCleanup(() => { resetSortedArticles() }) const handleLoadMoreClick = () => { loadMoreWithoutScrolling(LOAD_MORE_PAGE_SIZE) } return (
0} fallback={}>
{(shout) => (
)}
0} keyed={true}> {(shout) => (
)}
0} keyed={true}> {(page) => ( {(shout) => (
)}
)}
) }