@-routing-fix
This commit is contained in:
parent
ef1408327f
commit
fde2335a02
|
@ -1,4 +1,4 @@
|
|||
import { A, useLocation, useParams } from '@solidjs/router'
|
||||
import { A, useLocation } from '@solidjs/router'
|
||||
import { clsx } from 'clsx'
|
||||
import { For, Match, Show, Switch, createEffect, createMemo, createSignal, on, onMount } from 'solid-js'
|
||||
import { Loading } from '~/components/_shared/Loading'
|
||||
|
@ -26,7 +26,7 @@ import { Row2 } from '../../Feed/Row2'
|
|||
import { Row3 } from '../../Feed/Row3'
|
||||
import styles from './Author.module.scss'
|
||||
|
||||
type Props = {
|
||||
type AuthorViewProps = {
|
||||
authorSlug: string
|
||||
selectedTab: string
|
||||
shouts?: Shout[]
|
||||
|
@ -37,11 +37,10 @@ type Props = {
|
|||
export const PRERENDERED_ARTICLES_COUNT = 12
|
||||
const LOAD_MORE_PAGE_SIZE = 9
|
||||
|
||||
export const AuthorView = (props: Props) => {
|
||||
export const AuthorView = (props: AuthorViewProps) => {
|
||||
// contexts
|
||||
const { t } = useLocalize()
|
||||
const loc = useLocation()
|
||||
const params = useParams()
|
||||
const { session } = useSession()
|
||||
const { query } = useGraphQL()
|
||||
const { sortedFeed } = useFeed()
|
||||
|
@ -173,19 +172,19 @@ export const AuthorView = (props: Props) => {
|
|||
<div class={clsx(styles.groupControls, 'row')}>
|
||||
<div class="col-md-16">
|
||||
<ul class="view-switcher">
|
||||
<li classList={{ 'view-switcher__item--selected': params.tab === '' }}>
|
||||
<li classList={{ 'view-switcher__item--selected': !props.selectedTab }}>
|
||||
<A href={`/author/${props.authorSlug}`}>{t('Publications')}</A>
|
||||
<Show when={author()?.stat}>
|
||||
<span class="view-switcher__counter">{author()?.stat?.shouts || 0}</span>
|
||||
</Show>
|
||||
</li>
|
||||
<li classList={{ 'view-switcher__item--selected': params.tab === 'comment' }}>
|
||||
<li classList={{ 'view-switcher__item--selected': props.selectedTab === 'comment' }}>
|
||||
<A href={`/author/${props.authorSlug}/comments`}>{t('Comments')}</A>
|
||||
<Show when={author()?.stat}>
|
||||
<span class="view-switcher__counter">{author()?.stat?.comments || 0}</span>
|
||||
</Show>
|
||||
</li>
|
||||
<li classList={{ 'view-switcher__item--selected': params.tab === 'about' }}>
|
||||
<li classList={{ 'view-switcher__item--selected': props.selectedTab === 'about' }}>
|
||||
<A onClick={() => checkBioHeight()} href={`/author/${props.authorSlug}/about`}>
|
||||
{t('About the author')}
|
||||
</A>
|
||||
|
@ -206,7 +205,7 @@ export const AuthorView = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<Switch>
|
||||
<Match when={params.tab === 'about'}>
|
||||
<Match when={props.selectedTab === 'about'}>
|
||||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<div class="col-md-20 col-lg-18">
|
||||
|
@ -230,7 +229,7 @@ export const AuthorView = (props: Props) => {
|
|||
</div>
|
||||
</div>
|
||||
</Match>
|
||||
<Match when={params.tab === 'comments'}>
|
||||
<Match when={props.selectedTab === 'comments'}>
|
||||
<Show when={me()?.slug === props.authorSlug && !me().stat?.comments}>
|
||||
<div class="wide-container">
|
||||
<Placeholder type={loc?.pathname} mode="profile" />
|
||||
|
@ -256,7 +255,7 @@ export const AuthorView = (props: Props) => {
|
|||
</div>
|
||||
</div>
|
||||
</Match>
|
||||
<Match when={params.tab === ''}>
|
||||
<Match when={!props.selectedTab}>
|
||||
<Show when={me()?.slug === props.authorSlug && !me().stat?.shouts}>
|
||||
<div class="wide-container">
|
||||
<Placeholder type={loc?.pathname} mode="profile" />
|
||||
|
|
|
@ -16,6 +16,7 @@ import styles from './PageLayout.module.scss'
|
|||
type PageLayoutProps = {
|
||||
title: string
|
||||
desc?: string
|
||||
keywords?: string
|
||||
headerTitle?: string
|
||||
slug?: string
|
||||
article?: Shout
|
||||
|
@ -46,12 +47,10 @@ export const PageLayout = (props: PageLayoutProps) => {
|
|||
})
|
||||
: imageUrl
|
||||
)
|
||||
const description = createMemo(() => (props.desc ? t(props.desc) : ''))
|
||||
const description = createMemo(() => props.desc || (props.article && descFromBody(props.article.body)))
|
||||
const keypath = createMemo(() => (props.key || loc?.pathname.split('/')[0]) as keyof typeof ruKeywords)
|
||||
const keywords = createMemo(
|
||||
() =>
|
||||
(props.article && descFromBody(props.article.body)) ||
|
||||
(lang() === 'ru' ? ruKeywords[keypath()] : enKeywords[keypath()])
|
||||
() => props.keywords || (lang() === 'ru' ? ruKeywords[keypath()] : enKeywords[keypath()])
|
||||
)
|
||||
const [scrollToComments, setScrollToComments] = createSignal<boolean>(false)
|
||||
createEffect(() => props.scrollToComments?.(scrollToComments()))
|
||||
|
|
|
@ -92,12 +92,13 @@ export const AuthorsProvider = (props: { children: JSX.Element }) => {
|
|||
|
||||
const loadAuthor = async (opts: QueryGet_AuthorArgs): Promise<void> => {
|
||||
try {
|
||||
console.debug('[context.authors] load author', opts)
|
||||
const fetcher = await getAuthor(opts)
|
||||
const author = await fetcher()
|
||||
if (author) addAuthor(author as Author)
|
||||
console.debug('Loaded author:', author)
|
||||
console.debug('[context.authors]', author)
|
||||
} catch (error) {
|
||||
console.error('Error loading author:', error)
|
||||
console.error('[context.authors] Error loading author:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { RouteDefinition, RouteSectionProps, createAsync, useLocation, useParams } from '@solidjs/router'
|
||||
import { RouteDefinition, RouteSectionProps, createAsync, useLocation } from '@solidjs/router'
|
||||
import { HttpStatusCode } from '@solidjs/start'
|
||||
import {
|
||||
ErrorBoundary,
|
||||
|
@ -14,7 +14,7 @@ import { FourOuFourView } from '~/components/Views/FourOuFour'
|
|||
import { Loading } from '~/components/_shared/Loading'
|
||||
import { gaIdentity } from '~/config'
|
||||
import { useLocalize } from '~/context/localize'
|
||||
import { getAuthor, getShout } from '~/graphql/api/public'
|
||||
import { getShout } from '~/graphql/api/public'
|
||||
import type { Author, Reaction, Shout } from '~/graphql/schema/core.gen'
|
||||
import { initGA, loadGAScript } from '~/utils/ga'
|
||||
import { descFromBody, keywordsFromTopics } from '~/utils/meta'
|
||||
|
@ -29,12 +29,6 @@ const fetchShout = async (slug: string): Promise<Shout | undefined> => {
|
|||
return result
|
||||
}
|
||||
|
||||
const fetchAuthor = async (slug: string): Promise<Author | undefined> => {
|
||||
const authorLoader = getAuthor({ slug })
|
||||
const result = await authorLoader()
|
||||
return result
|
||||
}
|
||||
|
||||
export const route: RouteDefinition = {
|
||||
load: async ({ params }) => ({
|
||||
article: await fetchShout(params.slug)
|
||||
|
@ -44,21 +38,23 @@ export const route: RouteDefinition = {
|
|||
type SlugPageProps = { article?: Shout; comments?: Reaction[]; votes?: Reaction[]; author?: Author }
|
||||
|
||||
export default (props: RouteSectionProps<SlugPageProps>) => {
|
||||
const params = useParams()
|
||||
if (params.slug.startsWith('@')) return AuthorPage(props as RouteSectionProps<AuthorPageProps>)
|
||||
if (props.params.slug.startsWith('@')) {
|
||||
console.debug('[slug] @ found, render as author page')
|
||||
const patchedProps = {
|
||||
...props,
|
||||
params: {
|
||||
...props.params,
|
||||
slug: props.params.slug.slice(1, props.params.slug.length)
|
||||
}
|
||||
} as RouteSectionProps<AuthorPageProps>
|
||||
return AuthorPage(patchedProps)
|
||||
}
|
||||
|
||||
const loc = useLocation()
|
||||
const { t } = useLocalize()
|
||||
const [scrollToComments, setScrollToComments] = createSignal<boolean>(false)
|
||||
const article = createAsync(async () => props.data.article || (await fetchShout(params.slug)))
|
||||
const author = createAsync(async () =>
|
||||
params.slug.startsWith('@')
|
||||
? props.data.author || (await fetchAuthor(params.slug))
|
||||
: article()?.authors?.[0]
|
||||
)
|
||||
const titleSuffix = createMemo(
|
||||
() => (article()?.title || author()?.name) ?? ` :: ${article()?.title || author()?.name || ''}`
|
||||
)
|
||||
const article = createAsync(async () => props.data.article || (await fetchShout(props.params.slug)))
|
||||
const titleSuffix = createMemo(() => (article()?.title ? ` :: ${article()?.title || ''}` : ''))
|
||||
|
||||
onMount(async () => {
|
||||
if (gaIdentity && article()?.id) {
|
||||
|
@ -98,35 +94,19 @@ export default (props: RouteSectionProps<SlugPageProps>) => {
|
|||
</PageLayout>
|
||||
}
|
||||
>
|
||||
<Show
|
||||
when={params.slug.startsWith('@')}
|
||||
fallback={
|
||||
<PageLayout
|
||||
title={`${t('Discours')}${titleSuffix() || ''}`}
|
||||
desc={keywordsFromTopics(article()?.topics as { title: string }[])}
|
||||
headerTitle={article()?.title || ''}
|
||||
slug={article()?.slug}
|
||||
cover={article()?.cover || ''}
|
||||
scrollToComments={(value) => setScrollToComments(value)}
|
||||
>
|
||||
<ReactionsProvider>
|
||||
<FullArticle article={article() as Shout} scrollToComments={scrollToComments()} />
|
||||
</ReactionsProvider>
|
||||
</PageLayout>
|
||||
}
|
||||
<PageLayout
|
||||
title={`${t('Discours')}${titleSuffix()}`}
|
||||
desc={descFromBody(article()?.body || '')}
|
||||
keywords={keywordsFromTopics(article()?.topics as { title: string }[])}
|
||||
headerTitle={article()?.title || ''}
|
||||
slug={article()?.slug}
|
||||
cover={article()?.cover || ''}
|
||||
scrollToComments={(value) => setScrollToComments(value)}
|
||||
>
|
||||
<PageLayout
|
||||
title={`${t('Discours')}${titleSuffix() || ''}`}
|
||||
desc={descFromBody(author()?.about || author()?.bio || '')}
|
||||
headerTitle={author()?.name || ''}
|
||||
slug={author()?.slug}
|
||||
cover={author()?.pic || ''}
|
||||
>
|
||||
<ReactionsProvider>
|
||||
<FullArticle article={article() as Shout} scrollToComments={scrollToComments()} />
|
||||
</ReactionsProvider>
|
||||
</PageLayout>
|
||||
</Show>
|
||||
<ReactionsProvider>
|
||||
<FullArticle article={article() as Shout} scrollToComments={scrollToComments()} />
|
||||
</ReactionsProvider>
|
||||
</PageLayout>
|
||||
</Show>
|
||||
</Suspense>
|
||||
</ErrorBoundary>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { RouteSectionProps, createAsync, useParams } from '@solidjs/router'
|
||||
import { RouteSectionProps, createAsync } from '@solidjs/router'
|
||||
import { ErrorBoundary, Suspense, createEffect, createMemo } from 'solid-js'
|
||||
import { AuthorView } from '~/components/Views/Author'
|
||||
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
||||
|
@ -50,13 +50,12 @@ export const route = {
|
|||
export type AuthorPageProps = { articles?: Shout[]; author?: Author; topics?: Topic[] }
|
||||
|
||||
export const AuthorPage = (props: RouteSectionProps<AuthorPageProps>) => {
|
||||
const params = useParams()
|
||||
const { addAuthor } = useAuthors()
|
||||
const articles = createAsync(
|
||||
async () => props.data.articles || (await fetchAuthorShouts(params.slug)) || []
|
||||
async () => props.data.articles || (await fetchAuthorShouts(props.params.slug)) || []
|
||||
)
|
||||
const author = createAsync(async () => {
|
||||
const a = props.data.author || (await fetchAuthor(params.slug))
|
||||
const a = props.data.author || (await fetchAuthor(props.params.slug))
|
||||
a && addAuthor(a)
|
||||
return a
|
||||
})
|
||||
|
@ -81,7 +80,9 @@ export const AuthorPage = (props: RouteSectionProps<AuthorPageProps>) => {
|
|||
: getImageUrl('production/image/logo_image.png')
|
||||
)
|
||||
|
||||
const selectedTab = createMemo(() => (params.tab in ['followers', 'shouts'] ? params.tab : 'name'))
|
||||
const selectedTab = createMemo(() =>
|
||||
props.params.tab in ['followers', 'shouts'] ? props.params.tab : 'name'
|
||||
)
|
||||
return (
|
||||
<ErrorBoundary fallback={(_err) => <FourOuFourView />}>
|
||||
<Suspense fallback={<Loading />}>
|
||||
|
@ -96,7 +97,7 @@ export const AuthorPage = (props: RouteSectionProps<AuthorPageProps>) => {
|
|||
<AuthorView
|
||||
author={author() as Author}
|
||||
selectedTab={selectedTab()}
|
||||
authorSlug={params.slug}
|
||||
authorSlug={props.params.slug}
|
||||
shouts={articles() as Shout[]}
|
||||
topics={topics()}
|
||||
/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { redirect, useParams } from '@solidjs/router'
|
||||
import { RouteSectionProps, redirect } from '@solidjs/router'
|
||||
import { createEffect, createMemo, createSignal, lazy, on } from 'solid-js'
|
||||
import { AuthGuard } from '~/components/AuthGuard'
|
||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||
|
@ -27,7 +27,7 @@ export const getContentTypeTitle = (layout: LayoutType) => {
|
|||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
export default (props: RouteSectionProps) => {
|
||||
const { t } = useLocalize()
|
||||
const { session } = useSession()
|
||||
const snackbar = useSnackbar()
|
||||
|
@ -38,13 +38,12 @@ export default () => {
|
|||
redirect('/edit') // all drafts page
|
||||
}
|
||||
const [shout, setShout] = createSignal<Shout>()
|
||||
const params = useParams()
|
||||
const client = useGraphQL()
|
||||
|
||||
createEffect(on(session, (s) => s?.access_token && loadDraft(), { defer: true }))
|
||||
|
||||
const loadDraft = async () => {
|
||||
const result = await client.query(getShoutDraft, { shout_id: params.id }).toPromise()
|
||||
const result = await client.query(getShoutDraft, { shout_id: props.params.id }).toPromise()
|
||||
if (result) {
|
||||
const { shout: loadedShout, error } = result.data.get_my_shout
|
||||
if (error) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useParams } from '@solidjs/router'
|
||||
import { RouteSectionProps } from '@solidjs/router'
|
||||
import { createEffect, createSignal, on } from 'solid-js'
|
||||
import { AuthGuard } from '~/components/AuthGuard'
|
||||
import EditSettingsView from '~/components/Views/EditView/EditSettingsView'
|
||||
|
@ -9,15 +9,14 @@ import { useSession } from '~/context/session'
|
|||
import getShoutDraft from '~/graphql/query/core/article-my'
|
||||
import { Shout } from '~/graphql/schema/core.gen'
|
||||
|
||||
export default () => {
|
||||
export default (props: RouteSectionProps) => {
|
||||
const { t } = useLocalize()
|
||||
const params = useParams()
|
||||
const client = useGraphQL()
|
||||
const { session } = useSession()
|
||||
createEffect(on(session, (s) => s?.access_token && loadDraft(), { defer: true }))
|
||||
const [shout, setShout] = createSignal<Shout>()
|
||||
const loadDraft = async () => {
|
||||
const result = await client.query(getShoutDraft, { shout_id: params.id }).toPromise()
|
||||
const result = await client.query(getShoutDraft, { shout_id: props.params.id }).toPromise()
|
||||
if (result) {
|
||||
const { shout: loadedShout, error } = result.data.get_my_shout
|
||||
if (error) throw new Error(error)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Params, RouteSectionProps, createAsync, useParams } from '@solidjs/router'
|
||||
import { Params, RouteSectionProps, createAsync } from '@solidjs/router'
|
||||
import { createEffect, createMemo, on } from 'solid-js'
|
||||
import { TopicsNav } from '~/components/Nav/TopicsNav'
|
||||
import { Expo } from '~/components/Views/Expo'
|
||||
|
@ -28,15 +28,14 @@ export const route = {
|
|||
|
||||
export default (props: RouteSectionProps<Shout[]>) => {
|
||||
const { t } = useLocalize()
|
||||
const params = useParams()
|
||||
const shouts = createAsync(
|
||||
async () =>
|
||||
props.data ||
|
||||
(await fetchExpoShouts(
|
||||
params.layout ? [params.layout] : ['audio', 'literature', 'article', 'video', 'image']
|
||||
props.params.layout ? [props.params.layout] : ['audio', 'literature', 'article', 'video', 'image']
|
||||
))
|
||||
)
|
||||
const layout = createMemo(() => params.layout)
|
||||
const layout = createMemo(() => props.params.layout)
|
||||
const title = createMemo(() => {
|
||||
switch (layout()) {
|
||||
case 'audio': {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { RouteSectionProps, createAsync, useParams } from '@solidjs/router'
|
||||
import { RouteSectionProps, createAsync } from '@solidjs/router'
|
||||
import { HttpStatusCode } from '@solidjs/start'
|
||||
import { Show, Suspense, createEffect, createMemo, createSignal } from 'solid-js'
|
||||
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
||||
|
@ -37,7 +37,6 @@ export const route = {
|
|||
|
||||
export default (props: RouteSectionProps<{ articles: Shout[]; topics: Topic[] }>) => {
|
||||
const { t } = useLocalize()
|
||||
const params = useParams()
|
||||
const { addTopics } = useTopics()
|
||||
const [loadingError, setLoadingError] = createSignal(false)
|
||||
|
||||
|
@ -46,7 +45,7 @@ export default (props: RouteSectionProps<{ articles: Shout[]; topics: Topic[] }>
|
|||
const ttt: Topic[] = props.data.topics || (await fetchAllTopics()) || []
|
||||
addTopics(ttt)
|
||||
console.debug('[route.topic] all topics loaded')
|
||||
const t = ttt.find((x) => x.slug === params.slug)
|
||||
const t = ttt.find((x) => x.slug === props.params.slug)
|
||||
return t
|
||||
} catch (_error) {
|
||||
setLoadingError(true)
|
||||
|
@ -55,7 +54,7 @@ export default (props: RouteSectionProps<{ articles: Shout[]; topics: Topic[] }>
|
|||
})
|
||||
|
||||
const articles = createAsync(
|
||||
async () => props.data.articles || (await fetchTopicShouts(params.slug)) || []
|
||||
async () => props.data.articles || (await fetchTopicShouts(props.params.slug)) || []
|
||||
)
|
||||
|
||||
const title = createMemo(() => `${t('Discours')} :: ${topic()?.title || ''}`)
|
||||
|
|
Loading…
Reference in New Issue
Block a user