layout upgrade
This commit is contained in:
parent
30fe44979e
commit
405fbb4db1
|
@ -1,5 +1,11 @@
|
|||
[0.6.0]
|
||||
[+] editor enabled
|
||||
[+] hybrid routing ssr/spa
|
||||
[+] layout pages
|
||||
[-] nanostores
|
||||
[+] inbox
|
||||
[+] css modules
|
||||
[+] draft editor
|
||||
[+] solid-driven storages
|
||||
|
||||
[0.5.1]
|
||||
[+] nanostores-base global store
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { AllAuthorsView } from '../Views/AllAuthors'
|
||||
import type { PageProps } from '../types'
|
||||
import { createSignal, onMount, Show } from 'solid-js'
|
||||
|
@ -18,11 +18,11 @@ export const AllAuthorsPage = (props: PageProps) => {
|
|||
})
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<Show when={isLoaded()} fallback={<Loading />}>
|
||||
<AllAuthorsView authors={props.allAuthors} />
|
||||
</Show>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { AllTopicsView } from '../Views/AllTopics'
|
||||
import type { PageProps } from '../types'
|
||||
import { createSignal, onMount, Show } from 'solid-js'
|
||||
|
@ -18,11 +18,11 @@ export const AllTopicsPage = (props: PageProps) => {
|
|||
})
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<Show when={isLoaded()} fallback={<Loading />}>
|
||||
<AllTopicsView topics={props.allTopics} />
|
||||
</Show>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { ArticleView } from '../Views/Article'
|
||||
import type { PageProps } from '../types'
|
||||
import { loadArticle, useArticlesStore } from '../../stores/zine/articles'
|
||||
|
@ -37,11 +37,11 @@ export const ArticlePage = (props: PageProps) => {
|
|||
})
|
||||
|
||||
return (
|
||||
<MainLayout headerTitle={article()?.title || ''}>
|
||||
<MainWrap headerTitle={article()?.title || ''}>
|
||||
<Show when={Boolean(article())} fallback={<Loading />}>
|
||||
<ArticleView article={article()} />
|
||||
</Show>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { AuthorView, PRERENDERED_ARTICLES_COUNT } from '../Views/Author'
|
||||
import type { PageProps } from '../types'
|
||||
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
|
@ -36,11 +36,11 @@ export const AuthorPage = (props: PageProps) => {
|
|||
onCleanup(() => resetSortedArticles())
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<Show when={isLoaded()} fallback={<Loading />}>
|
||||
<AuthorView author={props.author} authorArticles={props.authorArticles} authorSlug={slug()} />
|
||||
</Show>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
|
||||
export const ConnectPage = () => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<article class="container container--static-page">
|
||||
<div class="row">
|
||||
<h1 class="col-md-8 offset-md-2">
|
||||
|
@ -38,7 +38,7 @@ export const ConnectPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import { lazy, Suspense } from 'solid-js'
|
||||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { Loading } from '../Loading'
|
||||
|
||||
const CreateView = lazy(() => import('../Views/Create'))
|
||||
|
||||
export const CreatePage = () => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<Suspense fallback={<Loading />}>
|
||||
<CreateView />
|
||||
</Suspense>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { FeedView } from '../Views/Feed'
|
||||
import { onCleanup } from 'solid-js'
|
||||
import { resetSortedArticles } from '../../stores/zine/articles'
|
||||
|
@ -7,9 +7,9 @@ export const FeedPage = () => {
|
|||
onCleanup(() => resetSortedArticles())
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<FeedView />
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { FourOuFourView } from '../Views/FourOuFour'
|
||||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
|
||||
export const FourOuFourPage = () => {
|
||||
return (
|
||||
<MainLayout isHeaderFixed={false} hideFooter={true}>
|
||||
<MainWrap isHeaderFixed={false} hideFooter={true}>
|
||||
<FourOuFourView />
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { HomeView, PRERENDERED_ARTICLES_COUNT } from '../Views/Home'
|
||||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import type { PageProps } from '../types'
|
||||
import { createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
import { loadPublishedArticles, resetSortedArticles } from '../../stores/zine/articles'
|
||||
|
@ -23,11 +23,11 @@ export const HomePage = (props: PageProps) => {
|
|||
onCleanup(() => resetSortedArticles())
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<Show when={isLoaded()} fallback={<Loading />}>
|
||||
<HomeView randomTopics={props.randomTopics} recentPublishedArticles={props.homeArticles || []} />
|
||||
</Show>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
49
src/components/Pages/LayoutShoutsPage.tsx
Normal file
49
src/components/Pages/LayoutShoutsPage.tsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { LayoutView } from '../Views/LayoutView'
|
||||
import type { PageProps } from '../types'
|
||||
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
import { resetSortedArticles } from '../../stores/zine/articles'
|
||||
import { useRouter } from '../../stores/router'
|
||||
import { loadLayoutShouts } from '../../stores/zine/layouts'
|
||||
import { Loading } from '../Loading'
|
||||
|
||||
const PER_PAGE = 50
|
||||
|
||||
export const LayoutShoutsPage = (props: PageProps) => {
|
||||
const [isLoaded, setIsLoaded] = createSignal(Boolean(props.shouts))
|
||||
|
||||
const layout = createMemo(() => {
|
||||
const { page: getPage } = useRouter()
|
||||
|
||||
const page = getPage()
|
||||
|
||||
if (page.route !== 'layout') {
|
||||
throw new Error('ts guard')
|
||||
}
|
||||
|
||||
return page.params.layout
|
||||
})
|
||||
|
||||
onMount(async () => {
|
||||
if (isLoaded()) {
|
||||
return
|
||||
}
|
||||
|
||||
await loadLayoutShouts({ layout: layout(), amount: PER_PAGE, offset: 0 })
|
||||
|
||||
setIsLoaded(true)
|
||||
})
|
||||
|
||||
onCleanup(() => resetSortedArticles())
|
||||
|
||||
return (
|
||||
<MainWrap>
|
||||
<Show when={isLoaded()} fallback={<Loading />}>
|
||||
<LayoutView layout={layout()} shouts={props.shouts} />
|
||||
</Show>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
// for lazy loading
|
||||
export default LayoutShoutsPage
|
|
@ -1,48 +0,0 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { PRERENDERED_ARTICLES_COUNT, TopicView } from '../Views/Topic'
|
||||
import type { PageProps } from '../types'
|
||||
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
import { resetSortedArticles } from '../../stores/zine/articles'
|
||||
import { useRouter } from '../../stores/router'
|
||||
import { loadLayoutShouts, loadLayout } from '../../stores/zine/layouts'
|
||||
import { Loading } from '../Loading'
|
||||
|
||||
export const ReadingPage = (props: PageProps) => {
|
||||
const [isLoaded, setIsLoaded] = createSignal(Boolean(props.authorArticles) && Boolean(props.author))
|
||||
|
||||
const slug = createMemo(() => {
|
||||
const { page: getPage } = useRouter()
|
||||
|
||||
const page = getPage()
|
||||
|
||||
if (page.route !== 'topic') {
|
||||
throw new Error('ts guard')
|
||||
}
|
||||
|
||||
return page.params.slug
|
||||
})
|
||||
|
||||
onMount(async () => {
|
||||
if (isLoaded()) {
|
||||
return
|
||||
}
|
||||
|
||||
await loadLayoutShouts({ topicSlug: slug(), limit: PRERENDERED_ARTICLES_COUNT, offset: 0 })
|
||||
await loadLayout({ slug: slug() })
|
||||
|
||||
setIsLoaded(true)
|
||||
})
|
||||
|
||||
onCleanup(() => resetSortedArticles())
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<Show when={isLoaded()} fallback={<Loading />}>
|
||||
<TopicView topic={props.topic} topicArticles={props.topicArticles} topicSlug={slug()} />
|
||||
</Show>
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
// for lazy loading
|
||||
export default TopicPage
|
|
@ -1,4 +1,4 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { SearchView } from '../Views/Search'
|
||||
import type { PageProps } from '../types'
|
||||
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
|
@ -33,11 +33,11 @@ export const SearchPage = (props: PageProps) => {
|
|||
onCleanup(() => resetSortedArticles())
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<Show when={isLoaded()} fallback={<Loading />}>
|
||||
<SearchView results={props.searchResults || []} query={props.searchQuery} />
|
||||
</Show>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MainLayout } from '../Layouts/MainLayout'
|
||||
import { MainWrap } from '../Wrap/MainWrap'
|
||||
import { PRERENDERED_ARTICLES_COUNT, TopicView } from '../Views/Topic'
|
||||
import type { PageProps } from '../types'
|
||||
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
|
@ -36,11 +36,11 @@ export const TopicPage = (props: PageProps) => {
|
|||
onCleanup(() => resetSortedArticles())
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<Show when={isLoaded()} fallback={<Loading />}>
|
||||
<TopicView topic={props.topic} topicArticles={props.topicArticles} topicSlug={slug()} />
|
||||
</Show>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { t } from '../../../utils/intl'
|
||||
|
||||
export const DiscussionRulesPage = () => {
|
||||
const title = t('Discussion rules')
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<article class="container container--static-page">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-xl-7 shift-content order-md-first">
|
||||
|
@ -114,7 +114,7 @@ export const DiscussionRulesPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
|
||||
// const title = t('Dogma')
|
||||
|
||||
export const DogmaPage = () => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<article class="container container--static-page">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-xl-7 shift-content order-md-first">
|
||||
|
@ -53,7 +53,7 @@ export const DogmaPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createSignal, Show } from 'solid-js'
|
||||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { t } from '../../../utils/intl'
|
||||
import { Icon } from '../../Nav/Icon'
|
||||
|
||||
|
@ -11,7 +11,7 @@ export const GuidePage = () => {
|
|||
const toggleIndexExpanded = () => setIndexExpanded((oldExpanded) => !oldExpanded)
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
{/*<Meta name="description" content={title} />*/}
|
||||
{/*<Meta name="keywords" content={t('Discours') + ',' + title} />*/}
|
||||
{/*<Meta property="og:title" content={title} />*/}
|
||||
|
@ -283,7 +283,7 @@ export const GuidePage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createSignal, Show } from 'solid-js'
|
||||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { Donate } from '../../Discours/Donate'
|
||||
import { Icon } from '../../Nav/Icon'
|
||||
|
||||
|
@ -11,7 +11,7 @@ export const HelpPage = () => {
|
|||
const toggleIndexExpanded = () => setIndexExpanded((oldExpanded) => !oldExpanded)
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
{/*<Meta name="description">Здесь можно поддержать Дискурс материально.</Meta>*/}
|
||||
{/*<Meta name="keywords">Discours.io, помощь, благотворительность</Meta>*/}
|
||||
|
||||
|
@ -161,7 +161,7 @@ export const HelpPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createSignal, Show } from 'solid-js'
|
||||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { Modal } from '../../Nav/Modal'
|
||||
import { Feedback } from '../../Discours/Feedback'
|
||||
import Subscribe from '../../Discours/Subscribe'
|
||||
|
@ -14,7 +14,7 @@ export const ManifestPage = () => {
|
|||
const toggleIndexExpanded = () => setIndexExpanded((oldExpanded) => !oldExpanded)
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<Modal name="feedback">
|
||||
<Feedback />
|
||||
</Modal>
|
||||
|
@ -191,7 +191,7 @@ export const ManifestPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { t } from '../../../utils/intl'
|
||||
|
||||
// const title = t('Partners')
|
||||
|
||||
export const PartnersPage = () => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<article class="container container--static-page">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-xl-7 shift-content order-md-first">
|
||||
|
@ -13,7 +13,7 @@ export const PartnersPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { t } from '../../../utils/intl'
|
||||
|
||||
export const PrinciplesPage = () => {
|
||||
const title = t('Principles')
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<article class="container container--static-page">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-xl-7 shift-content order-md-first">
|
||||
|
@ -172,7 +172,7 @@ export const PrinciplesPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { t } from '../../../utils/intl'
|
||||
|
||||
// title={t('Projects')}>
|
||||
|
||||
export const ProjectsPage = () => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
<article class="container container--static-page">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-xl-7 shift-content order-md-first">
|
||||
|
@ -13,7 +13,7 @@ export const ProjectsPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createSignal, Show } from 'solid-js'
|
||||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { Icon } from '../../Nav/Icon'
|
||||
|
||||
// const title = t('Terms of use')
|
||||
|
@ -10,7 +10,7 @@ export const TermsOfUsePage = () => {
|
|||
const toggleIndexExpanded = () => setIndexExpanded((oldExpanded) => !oldExpanded)
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
{/*<Meta name="description" content={title} />*/}
|
||||
{/*<Meta name="keywords" content={`Discours.io, ${t('Terms of use')}, ${t('Terms of use', 'en')}`} />*/}
|
||||
{/*<Meta property="og:title" content={title} />*/}
|
||||
|
@ -274,7 +274,7 @@ export const TermsOfUsePage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { MainLayout } from '../../Layouts/MainLayout'
|
||||
import { MainWrap } from '../../Wrap/MainWrap'
|
||||
import { t } from '../../../utils/intl'
|
||||
|
||||
export const ThanksPage = () => {
|
||||
const title = t('Thank you')
|
||||
return (
|
||||
<MainLayout>
|
||||
<MainWrap>
|
||||
{/*<Meta name="description" content={title} />*/}
|
||||
{/*<Meta name="keywords" content={`Discours.io, ${title}, ${t('Thank you', 'en')}`} />*/}
|
||||
{/*<Meta property="og:title" content={title} />*/}
|
||||
|
@ -85,7 +85,7 @@ export const ThanksPage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</MainLayout>
|
||||
</MainWrap>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,7 @@ import { ThanksPage } from './Pages/about/ThanksPage'
|
|||
import { CreatePage } from './Pages/CreatePage'
|
||||
import { ConnectPage } from './Pages/ConnectPage'
|
||||
import { renewSession } from '../stores/auth'
|
||||
import { AudioPage } from './Pages/AudioPage'
|
||||
import { VideoPage } from './Pages/VideoPage'
|
||||
import { ReadingPage } from './Pages/ReadingPage'
|
||||
import { ArtworksPage } from './Pages/ArtworksPage'
|
||||
import { LayoutShoutsPage } from './Pages/LayoutShoutsPage'
|
||||
|
||||
// TODO: lazy load
|
||||
// const SomePage = lazy(() => import('./Pages/SomePage'))
|
||||
|
@ -47,10 +44,7 @@ type RootSearchParams = {
|
|||
}
|
||||
|
||||
const pagesMap: Record<keyof Routes, Component<PageProps>> = {
|
||||
audio: AudioPage,
|
||||
video: VideoPage,
|
||||
literature: ReadingPage,
|
||||
artworks: ArtworksPage,
|
||||
layout: LayoutShoutsPage,
|
||||
connect: ConnectPage,
|
||||
create: CreatePage,
|
||||
home: HomePage,
|
||||
|
|
140
src/components/Views/LayoutView.tsx
Normal file
140
src/components/Views/LayoutView.tsx
Normal file
|
@ -0,0 +1,140 @@
|
|||
import { For, Show, createMemo, onMount, createSignal } from 'solid-js'
|
||||
import type { Shout } from '../../graphql/types.gen'
|
||||
import { Row3 } from '../Feed/Row3'
|
||||
import { Row2 } from '../Feed/Row2'
|
||||
import { Beside } from '../Feed/Beside'
|
||||
import styles from '../../styles/Topic.module.scss'
|
||||
import { t } from '../../utils/intl'
|
||||
import { useRouter } from '../../stores/router'
|
||||
import { useArticlesStore } from '../../stores/zine/articles'
|
||||
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
||||
import { splitToPages } from '../../utils/splitToPages'
|
||||
import { clsx } from 'clsx'
|
||||
import Slider from '../Feed/Slider'
|
||||
import { Row1 } from '../Feed/Row1'
|
||||
import { loadLayoutShouts } from '../../stores/zine/layouts'
|
||||
|
||||
type LayoutPageSearchParams = {
|
||||
layout: 'audio' | 'video' | 'artworks' | 'literature'
|
||||
}
|
||||
|
||||
interface LayoutProps {
|
||||
layout: string
|
||||
shouts: Shout[]
|
||||
}
|
||||
|
||||
export const PRERENDERED_ARTICLES_COUNT = 21
|
||||
const LOAD_MORE_PAGE_SIZE = 9 // Row3 + Row3 + Row3
|
||||
|
||||
export const LayoutView = (props: LayoutProps) => {
|
||||
const { searchParams, changeSearchParam } = useRouter<LayoutPageSearchParams>()
|
||||
|
||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||
|
||||
const { sortedArticles } = useArticlesStore({ sortedArticles: props.shouts })
|
||||
const layout = createMemo(() => props.layout)
|
||||
|
||||
const loadMoreLayout = async (layout: string) => {
|
||||
saveScrollPosition()
|
||||
|
||||
const { hasMore } = await loadLayoutShouts({
|
||||
layout,
|
||||
amount: LOAD_MORE_PAGE_SIZE,
|
||||
offset: sortedArticles().length
|
||||
})
|
||||
setIsLoadMoreButtonVisible(hasMore)
|
||||
|
||||
restoreScrollPosition()
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) {
|
||||
loadMoreLayout(searchParams().layout)
|
||||
}
|
||||
})
|
||||
|
||||
const title = createMemo(() => {
|
||||
const l = searchParams().layout
|
||||
if (l === 'audio') return t('Audio')
|
||||
if (l === 'video') return t('Video')
|
||||
if (l === 'artworks') return t('Artworks')
|
||||
return t('Literature')
|
||||
})
|
||||
|
||||
const pages = createMemo<Shout[][]>(() =>
|
||||
splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE)
|
||||
)
|
||||
|
||||
const ModeSwitcher = () => (
|
||||
<div class="container">
|
||||
<div class={clsx(styles.groupControls, 'row group__controls')}>
|
||||
<div class="col-md-8">
|
||||
<ul class="view-switcher">
|
||||
<li classList={{ selected: searchParams().layout === 'audio' }}>
|
||||
<a href="/layout/audio">{t('Audio')}</a>
|
||||
</li>
|
||||
<li classList={{ selected: searchParams().layout === 'video' }}>
|
||||
<a href="/layout/video">{t('Video')}</a>
|
||||
</li>
|
||||
<li classList={{ selected: searchParams().layout === 'artworks' }}>
|
||||
<a href="/layout/artworks">{t('Artworks')}</a>
|
||||
</li>
|
||||
<li classList={{ selected: searchParams().layout === 'literature' || !searchParams().layout }}>
|
||||
<a href="/layout/literature">{t('Literature')}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="mode-switcher">
|
||||
{`${t('Show')} `}
|
||||
<span class="mode-switcher__control">{t('All posts')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<div class={styles.topicPage}>
|
||||
<Show when={layout()}>
|
||||
<h1>{title()}</h1>
|
||||
|
||||
<ModeSwitcher />
|
||||
<Row1 article={sortedArticles()[0]} />
|
||||
<Row2 articles={sortedArticles().slice(1, 3)} />
|
||||
<Slider title={title()} articles={sortedArticles().slice(5, 11)} />
|
||||
<Beside
|
||||
beside={sortedArticles()[12]}
|
||||
title={t('Top viewed')}
|
||||
values={sortedArticles().slice(0, 5)}
|
||||
wrapper={'top-article'}
|
||||
/>
|
||||
<Show when={sortedArticles().length > 5}>
|
||||
<Row3 articles={sortedArticles().slice(13, 16)} />
|
||||
<Row2 articles={sortedArticles().slice(16, 18)} />
|
||||
<Row3 articles={sortedArticles().slice(18, 21)} />
|
||||
<Row3 articles={sortedArticles().slice(21, 24)} />
|
||||
<Row3 articles={sortedArticles().slice(24, 27)} />
|
||||
</Show>
|
||||
|
||||
<For each={pages()}>
|
||||
{(page) => (
|
||||
<>
|
||||
<Row3 articles={page.slice(0, 3)} />
|
||||
<Row3 articles={page.slice(3, 6)} />
|
||||
<Row3 articles={page.slice(6, 9)} />
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
|
||||
<Show when={isLoadMoreButtonVisible()}>
|
||||
<p class="load-more-container">
|
||||
<button class="button" onClick={() => loadMoreLayout(searchParams().layout)}>
|
||||
{t('Load more')}
|
||||
</button>
|
||||
</p>
|
||||
</Show>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -5,14 +5,14 @@ import { Footer } from '../Discours/Footer'
|
|||
import '../../styles/app.scss'
|
||||
import { Show } from 'solid-js'
|
||||
|
||||
type MainLayoutProps = {
|
||||
type MainWrapProps = {
|
||||
headerTitle?: string
|
||||
children: JSX.Element
|
||||
isHeaderFixed?: boolean
|
||||
hideFooter?: boolean
|
||||
}
|
||||
|
||||
export const MainLayout = (props: MainLayoutProps) => {
|
||||
export const MainWrap = (props: MainWrapProps) => {
|
||||
const isHeaderFixed = props.isHeaderFixed !== undefined ? props.isHeaderFixed : true
|
||||
|
||||
return (
|
|
@ -5,14 +5,13 @@ import type { Author, Chat, Shout, Topic } from '../graphql/types.gen'
|
|||
export type PageProps = {
|
||||
randomTopics?: Topic[]
|
||||
article?: Shout
|
||||
authorArticles?: Shout[]
|
||||
topicArticles?: Shout[]
|
||||
homeArticles?: Shout[]
|
||||
shouts?: Shout[]
|
||||
author?: Author
|
||||
allAuthors?: Author[]
|
||||
topic?: Topic
|
||||
allTopics?: Topic[]
|
||||
searchQuery?: string
|
||||
layout?: string
|
||||
// other types?
|
||||
searchResults?: Shout[]
|
||||
chats?: Chat[]
|
||||
|
|
|
@ -12,7 +12,7 @@ const LAYOUTS = ['literature', 'audio', 'video', 'artworks']
|
|||
if (!LAYOUTS.includes(layout)) {
|
||||
return Astro.redirect('/404')
|
||||
}
|
||||
const shouts = await apiClient.getRecentByLayout(layout)
|
||||
const shouts = await apiClient.getLayoutShouts({ layout })
|
||||
const { pathname, search } = Astro.url
|
||||
initRouter(pathname, search)
|
||||
---
|
||||
|
|
|
@ -25,6 +25,7 @@ export interface Routes {
|
|||
projects: void
|
||||
termsOfUse: void
|
||||
thanks: void
|
||||
layout: 'layout'
|
||||
}
|
||||
|
||||
const searchParamsStore = createSearchParams()
|
||||
|
@ -49,7 +50,8 @@ const routerStore = createRouter<Routes>(
|
|||
principles: '/about/principles',
|
||||
projects: '/about/projects',
|
||||
termsOfUse: '/about/terms-of-use',
|
||||
thanks: '/about/thanks'
|
||||
thanks: '/about/thanks',
|
||||
layout: 'layout/:layout'
|
||||
},
|
||||
{
|
||||
search: false,
|
||||
|
|
|
@ -99,22 +99,22 @@ const addSortedArticles = (articles: Shout[]) => {
|
|||
|
||||
export const loadLayoutShouts = async ({
|
||||
layout,
|
||||
limit,
|
||||
amount,
|
||||
offset
|
||||
}: {
|
||||
layout: string
|
||||
limit: number
|
||||
amount: number
|
||||
offset?: number
|
||||
}): Promise<{ hasMore: boolean }> => {
|
||||
const newArticles = await apiClient.getLayoutShouts({ layout, limit: limit + 1, offset })
|
||||
const hasMore = newArticles.length === limit + 1
|
||||
const layoutShouts: Shout[] = await apiClient.getLayoutShouts({ layout, amount, offset })
|
||||
const hasMore = layoutShouts.length > amount
|
||||
|
||||
if (hasMore) {
|
||||
newArticles.splice(-1)
|
||||
layoutShouts.splice(-1)
|
||||
}
|
||||
|
||||
addArticles(newArticles)
|
||||
addSortedArticles(newArticles)
|
||||
addArticles(layoutShouts)
|
||||
addSortedArticles(layoutShouts)
|
||||
|
||||
return { hasMore }
|
||||
}
|
||||
|
|
|
@ -336,7 +336,8 @@ export const apiClient = {
|
|||
const resp = await privateGraphQLClient.query(myChats, payload).toPromise()
|
||||
return resp.data.myChats
|
||||
},
|
||||
getLayoutShouts: async (layout = 'article', amount = 50, offset = 0) => {
|
||||
const resp = await publicGraphQLClient.query(getLayout, { amount, offset, layout })
|
||||
getLayoutShouts: async ({ layout = 'article', amount = 50, offset = 0 }) => {
|
||||
const resp = await publicGraphQLClient.query(getLayout, { amount, offset, layout }).toPromise()
|
||||
return resp.data.shoutsByLayout
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user