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