client routing fix (#139)

* client routing fix

* lint
This commit is contained in:
Igor Lobanov 2023-07-19 21:48:24 +02:00 committed by GitHub
parent 664adfc2dc
commit a607a30b28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 45 deletions

View File

@ -118,7 +118,6 @@ export const FullArticle = (props: ArticleProps) => {
actions: { loadReactionsBy } actions: { loadReactionsBy }
} = useReactions() } = useReactions()
console.log('!!! props.s:', props.article.layout === 'literature')
return ( return (
<> <>
<Title>{props.article.title}</Title> <Title>{props.article.title}</Title>

View File

@ -52,7 +52,9 @@ export const AuthorView = (props: AuthorProps) => {
const { sortedArticles } = useArticlesStore({ shouts: props.shouts }) const { sortedArticles } = useArticlesStore({ shouts: props.shouts })
const { searchParams, changeSearchParam } = useRouter<AuthorPageSearchParams>() const { searchParams, changeSearchParam } = useRouter<AuthorPageSearchParams>()
const { authorEntities } = useAuthorsStore({ authors: [props.author] }) const { authorEntities } = useAuthorsStore({ authors: [props.author] })
const author = authorEntities()[props.authorSlug]
const author = createMemo(() => authorEntities()[props.authorSlug])
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
const [followers, setFollowers] = createSignal<Author[]>([]) const [followers, setFollowers] = createSignal<Author[]>([])
const [subscriptions, setSubscriptions] = createSignal<Array<Author | Topic>>([]) const [subscriptions, setSubscriptions] = createSignal<Array<Author | Topic>>([])
@ -78,7 +80,7 @@ export const AuthorView = (props: AuthorProps) => {
const userSubscribers = await apiClient.getAuthorFollowers({ slug: props.authorSlug }) const userSubscribers = await apiClient.getAuthorFollowers({ slug: props.authorSlug })
setFollowers(userSubscribers) setFollowers(userSubscribers)
} catch (error) { } catch (error) {
console.log('[getAuthorFollowers]', error) console.error('[getAuthorFollowers]', error)
} }
if (!searchParams().by) { if (!searchParams().by) {
changeSearchParam('by', 'rating') changeSearchParam('by', 'rating')
@ -136,7 +138,9 @@ export const AuthorView = (props: AuthorProps) => {
return ( return (
<div class="author-page"> <div class="author-page">
<div class="wide-container"> <div class="wide-container">
<AuthorFull author={author} /> <Show when={author()}>
<AuthorFull author={author()} />
</Show>
<div class="row group__controls"> <div class="row group__controls">
<div class="col-md-16"> <div class="col-md-16">
<ul class="view-switcher"> <ul class="view-switcher">
@ -218,7 +222,7 @@ export const AuthorView = (props: AuthorProps) => {
<Switch> <Switch>
<Match when={searchParams().by === 'about'}> <Match when={searchParams().by === 'about'}>
<div class="wide-container"> <div class="wide-container">
<p>{author.about}</p> <p>{author().about}</p>
</div> </div>
</Match> </Match>
<Match when={searchParams().by === 'commented'}> <Match when={searchParams().by === 'commented'}>

View File

@ -48,7 +48,7 @@ export const TopicView = (props: TopicProps) => {
saveScrollPosition() saveScrollPosition()
const { hasMore } = await loadShouts({ const { hasMore } = await loadShouts({
filters: { topic: topic().slug }, filters: { topic: props.topicSlug },
limit: LOAD_MORE_PAGE_SIZE, limit: LOAD_MORE_PAGE_SIZE,
offset: sortedArticles().length offset: sortedArticles().length
}) })

View File

@ -1,7 +1,7 @@
import { PageLayout } from '../components/_shared/PageLayout' import { PageLayout } from '../components/_shared/PageLayout'
import { AuthorView, PRERENDERED_ARTICLES_COUNT } from '../components/Views/Author' import { AuthorView, PRERENDERED_ARTICLES_COUNT } from '../components/Views/Author'
import type { PageProps } from './types' import type { PageProps } from './types'
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' import { createEffect, createMemo, createSignal, on, onCleanup, onMount, Show } from 'solid-js'
import { loadShouts, resetSortedArticles } from '../stores/zine/articles' import { loadShouts, resetSortedArticles } from '../stores/zine/articles'
import { useRouter } from '../stores/router' import { useRouter } from '../stores/router'
import { loadAuthor } from '../stores/zine/authors' import { loadAuthor } from '../stores/zine/authors'
@ -9,41 +9,58 @@ import { Loading } from '../components/_shared/Loading'
import { ReactionsProvider } from '../context/reactions' import { ReactionsProvider } from '../context/reactions'
export const AuthorPage = (props: PageProps) => { export const AuthorPage = (props: PageProps) => {
const [isLoaded, setIsLoaded] = createSignal(Boolean(props.authorShouts) && Boolean(props.author)) const { page } = useRouter()
const slug = createMemo(() => { const slug = createMemo(() => page().params['slug'] as string)
const { page: getPage } = useRouter()
const page = getPage() const [isLoaded, setIsLoaded] = createSignal(
Boolean(props.authorShouts) && Boolean(props.author) && props.author.slug === slug()
)
if (page.route !== 'author') { const preload = () =>
throw new Error('ts guard') Promise.all([
} loadShouts({
filters: { author: slug(), visibility: 'community' },
return page.params.slug limit: PRERENDERED_ARTICLES_COUNT
}) }),
loadAuthor({ slug: slug() })
])
onMount(async () => { onMount(async () => {
if (isLoaded()) { if (isLoaded()) {
return return
} }
await loadShouts({ await preload()
filters: { author: slug(), visibility: 'community' },
limit: PRERENDERED_ARTICLES_COUNT
})
await loadAuthor({ slug: slug() })
setIsLoaded(true) setIsLoaded(true)
}) })
createEffect(
on(
() => slug(),
async () => {
setIsLoaded(false)
resetSortedArticles()
await preload()
setIsLoaded(true)
}
)
)
onCleanup(() => resetSortedArticles()) onCleanup(() => resetSortedArticles())
const usePrerenderedData = props.author?.slug === slug()
return ( return (
<PageLayout> <PageLayout>
<ReactionsProvider> <ReactionsProvider>
<Show when={isLoaded()} fallback={<Loading />}> <Show when={isLoaded()} fallback={<Loading />}>
<AuthorView author={props.author} shouts={props.authorShouts} authorSlug={slug()} /> <AuthorView
author={usePrerenderedData ? props.author : null}
shouts={usePrerenderedData ? props.authorShouts : null}
authorSlug={slug()}
/>
</Show> </Show>
</ReactionsProvider> </ReactionsProvider>
</PageLayout> </PageLayout>

View File

@ -27,13 +27,16 @@ export const LayoutShoutsPage = (props: PageProps) => {
const { t } = useLocalize() const { t } = useLocalize()
const { page: getPage } = useRouter() const { page: getPage } = useRouter()
const getLayout = createMemo<LayoutType>(() => { const getLayout = createMemo<LayoutType>(() => getPage().params['layout'] as LayoutType)
const layout = getPage().params['layout']
return layout as LayoutType const [isLoaded, setIsLoaded] = createSignal(
}) Boolean(props.layoutShouts) &&
props.layoutShouts.length > 0 &&
props.layoutShouts[0].layout === getLayout()
)
const { sortedArticles } = useArticlesStore({ const { sortedArticles } = useArticlesStore({
shouts: props.layoutShouts shouts: isLoaded() ? props.layoutShouts : []
}) })
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
@ -61,14 +64,13 @@ export const LayoutShoutsPage = (props: PageProps) => {
splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE) splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE)
) )
const isLoaded = createMemo(() => Boolean(props.layoutShouts))
onMount(() => { onMount(() => {
if (isLoaded()) { if (isLoaded()) {
return return
} }
loadMore(PRERENDERED_ARTICLES_COUNT + LOAD_MORE_PAGE_SIZE) loadMore(PRERENDERED_ARTICLES_COUNT + LOAD_MORE_PAGE_SIZE)
setIsLoaded(true)
}) })
onMount(() => { onMount(() => {

View File

@ -1,7 +1,7 @@
import { PageLayout } from '../components/_shared/PageLayout' import { PageLayout } from '../components/_shared/PageLayout'
import { PRERENDERED_ARTICLES_COUNT, TopicView } from '../components/Views/Topic' import { PRERENDERED_ARTICLES_COUNT, TopicView } from '../components/Views/Topic'
import type { PageProps } from './types' import type { PageProps } from './types'
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' import { createEffect, createMemo, createSignal, on, onCleanup, onMount, Show } from 'solid-js'
import { loadShouts, resetSortedArticles } from '../stores/zine/articles' import { loadShouts, resetSortedArticles } from '../stores/zine/articles'
import { useRouter } from '../stores/router' import { useRouter } from '../stores/router'
import { loadTopic } from '../stores/zine/topics' import { loadTopic } from '../stores/zine/topics'
@ -9,38 +9,55 @@ import { Loading } from '../components/_shared/Loading'
import { ReactionsProvider } from '../context/reactions' import { ReactionsProvider } from '../context/reactions'
export const TopicPage = (props: PageProps) => { export const TopicPage = (props: PageProps) => {
const [isLoaded, setIsLoaded] = createSignal(Boolean(props.topicShouts) && Boolean(props.topic)) const { page } = useRouter()
const slug = createMemo(() => { const slug = createMemo(() => page().params['slug'] as string)
const { page: getPage } = useRouter()
const page = getPage() const [isLoaded, setIsLoaded] = createSignal(
Boolean(props.topicShouts) && Boolean(props.topic) && props.topic.slug === slug()
)
if (page.route !== 'topic') { const preload = () =>
throw new Error('ts guard') Promise.all([
} loadShouts({ filters: { topic: slug() }, limit: PRERENDERED_ARTICLES_COUNT, offset: 0 }),
loadTopic({ slug: slug() })
return page.params.slug ])
})
onMount(async () => { onMount(async () => {
if (isLoaded()) { if (isLoaded()) {
return return
} }
await loadShouts({ filters: { topic: slug() }, limit: PRERENDERED_ARTICLES_COUNT, offset: 0 }) await preload()
await loadTopic({ slug: slug() })
setIsLoaded(true) setIsLoaded(true)
}) })
createEffect(
on(
() => slug(),
async () => {
setIsLoaded(false)
resetSortedArticles()
await preload()
setIsLoaded(true)
}
)
)
onCleanup(() => resetSortedArticles()) onCleanup(() => resetSortedArticles())
const usePrerenderedData = props.topic?.slug === slug()
return ( return (
<PageLayout> <PageLayout>
<ReactionsProvider> <ReactionsProvider>
<Show when={isLoaded()} fallback={<Loading />}> <Show when={isLoaded()} fallback={<Loading />}>
<TopicView topic={props.topic} shouts={props.topicShouts} topicSlug={slug()} /> <TopicView
topic={usePrerenderedData ? props.topic : null}
shouts={usePrerenderedData ? props.topicShouts : null}
topicSlug={slug()}
/>
</Show> </Show>
</ReactionsProvider> </ReactionsProvider>
</PageLayout> </PageLayout>

View File

@ -3,7 +3,7 @@ import solidPlugin from 'vite-plugin-solid'
import ssrPlugin from 'vite-plugin-ssr/plugin' import ssrPlugin from 'vite-plugin-ssr/plugin'
import sassDts from 'vite-plugin-sass-dts' import sassDts from 'vite-plugin-sass-dts'
export default defineConfig(({ mode }) => { export default defineConfig(() => {
return { return {
envPrefix: 'PUBLIC_', envPrefix: 'PUBLIC_',
plugins: [solidPlugin({ ssr: true }), ssrPlugin({ includeAssetsImportedByServer: true }), sassDts()], plugins: [solidPlugin({ ssr: true }), ssrPlugin({ includeAssetsImportedByServer: true }), sassDts()],