page-titles
This commit is contained in:
parent
6354bb8d47
commit
3433ba0aac
|
@ -9,6 +9,7 @@
|
||||||
"build": "vinxi build",
|
"build": "vinxi build",
|
||||||
"start": "vinxi start",
|
"start": "vinxi start",
|
||||||
"codegen": "graphql-codegen",
|
"codegen": "graphql-codegen",
|
||||||
|
"e2e": "npm run e2e:tests",
|
||||||
"e2e:tests": "npx playwright test --project=webkit",
|
"e2e:tests": "npx playwright test --project=webkit",
|
||||||
"e2e:tests:ci": "CI=true npx playwright test --project=webkit",
|
"e2e:tests:ci": "CI=true npx playwright test --project=webkit",
|
||||||
"e2e:install": "npx playwright install webkit && npx playwright install-deps ",
|
"e2e:install": "npx playwright install webkit && npx playwright install-deps ",
|
||||||
|
|
|
@ -56,7 +56,7 @@ export const AllAuthors = (props: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const sortedKeys = createMemo<string[]>(() => {
|
const sortedKeys = createMemo<string[]>(() => {
|
||||||
const keys = Object.keys(byLetterFiltered())
|
const keys = Object.keys(byLetterFiltered()||{})
|
||||||
keys.sort()
|
keys.sort()
|
||||||
const fk = keys.shift() || ''
|
const fk = keys.shift() || ''
|
||||||
fk && keys.push(fk)
|
fk && keys.push(fk)
|
||||||
|
@ -69,16 +69,16 @@ export const AllAuthors = (props: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={clsx(styles.allAuthorsPage, 'wide-container')}>
|
<div class={clsx(styles.allAuthorsPage, 'wide-container')}>
|
||||||
<Meta name="descprition" content={description()} />
|
<Meta name="descprition" content={description() || ''} />
|
||||||
<Meta name="keywords" content={lang() === 'ru' ? ruKeywords[''] : enKeywords['']} />
|
<Meta name="keywords" content={lang() === 'ru' ? ruKeywords[''] : enKeywords['']} />
|
||||||
<Meta name="og:type" content="article" />
|
<Meta name="og:type" content="article" />
|
||||||
<Meta name="og:title" content={ogTitle()} />
|
<Meta name="og:title" content={ogTitle() || ''} />
|
||||||
<Meta name="og:image" content={ogImage()} />
|
<Meta name="og:image" content={ogImage() || ''} />
|
||||||
<Meta name="twitter:image" content={ogImage()} />
|
<Meta name="twitter:image" content={ogImage() || ''} />
|
||||||
<Meta name="og:description" content={description()} />
|
<Meta name="og:description" content={description() || ''} />
|
||||||
<Meta name="twitter:card" content="summary_large_image" />
|
<Meta name="twitter:card" content="summary_large_image" />
|
||||||
<Meta name="twitter:title" content={ogTitle()} />
|
<Meta name="twitter:title" content={ogTitle() || ''} />
|
||||||
<Meta name="twitter:description" content={description()} />
|
<Meta name="twitter:description" content={description() || ''} />
|
||||||
<Show when={props.isLoaded} fallback={<Loading />}>
|
<Show when={props.isLoaded} fallback={<Loading />}>
|
||||||
<div class="offset-md-5">
|
<div class="offset-md-5">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -83,7 +83,13 @@ export const LocalizeProvider = (props: { children: JSX.Element }) => {
|
||||||
const formatTimeAgo = (date: Date) => timeAgo().format(date)
|
const formatTimeAgo = (date: Date) => timeAgo().format(date)
|
||||||
|
|
||||||
const value: LocalizeContextType = {
|
const value: LocalizeContextType = {
|
||||||
t: i18next.t,
|
t: ((s: string) => {
|
||||||
|
try {
|
||||||
|
return i18next.t(s)
|
||||||
|
} catch(_) {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}) as i18n['t'],
|
||||||
lang,
|
lang,
|
||||||
setLang,
|
setLang,
|
||||||
formatTime,
|
formatTime,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { RouteSectionProps, createAsync, useParams } from '@solidjs/router'
|
import { RouteSectionProps, createAsync, useLocation, useParams } from '@solidjs/router'
|
||||||
import { ErrorBoundary, Suspense, createMemo, createReaction, createSignal, onMount } from 'solid-js'
|
import { ErrorBoundary, Suspense, createMemo, createReaction, createSignal, onMount } from 'solid-js'
|
||||||
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
||||||
import { Loading } from '~/components/_shared/Loading'
|
import { Loading } from '~/components/_shared/Loading'
|
||||||
|
@ -22,11 +22,12 @@ export const route = {
|
||||||
|
|
||||||
export const ArticlePage = (props: RouteSectionProps<{ article: Shout }>) => {
|
export const ArticlePage = (props: RouteSectionProps<{ article: Shout }>) => {
|
||||||
const params = useParams()
|
const params = useParams()
|
||||||
|
const loc = useLocation()
|
||||||
const article = createAsync(async () => props.data.article || (await fetchShout(params.slug)))
|
const article = createAsync(async () => props.data.article || (await fetchShout(params.slug)))
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const [scrollToComments, setScrollToComments] = createSignal<boolean>(false)
|
const [scrollToComments, setScrollToComments] = createSignal<boolean>(false)
|
||||||
const title = createMemo(
|
const title = createMemo(
|
||||||
() => `${article()?.authors?.[0]?.name || t('Discours')}: ${article()?.title || ''}`
|
() => `${article()?.authors?.[0]?.name || t('Discours')} :: ${article()?.title || ''}`
|
||||||
)
|
)
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if (gaIdentity) {
|
if (gaIdentity) {
|
||||||
|
@ -49,7 +50,7 @@ export const ArticlePage = (props: RouteSectionProps<{ article: Shout }>) => {
|
||||||
window.gtag?.('event', 'page_view', {
|
window.gtag?.('event', 'page_view', {
|
||||||
page_title: article()?.title,
|
page_title: article()?.title,
|
||||||
page_location: window.location.href,
|
page_location: window.location.href,
|
||||||
page_path: window.location.pathname
|
page_path: loc.pathname
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -46,13 +46,13 @@ export const route = {
|
||||||
}
|
}
|
||||||
} satisfies RouteDefinition
|
} satisfies RouteDefinition
|
||||||
|
|
||||||
export default function AllTopicsPage(props: RouteSectionProps<{ authors: Author[] }>) {
|
export default function AllAuthorsPage(props: RouteSectionProps<{ authors: Author[] }>) {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const authors = createAsync<Author[]>(async () => props.data.authors || (await fetchData()) || [])
|
const authors = createAsync<Author[]>(async () => props.data.authors || (await fetchData()) || [])
|
||||||
const { addAuthors } = useAuthors()
|
const { addAuthors } = useAuthors()
|
||||||
createEffect(() => addAuthors(authors() || []))
|
createEffect(() => addAuthors(authors() || []))
|
||||||
return (
|
return (
|
||||||
<PageLayout withPadding={true} title={`${t('Discours')}:${t('All topics')}`}>
|
<PageLayout withPadding={true} title={`${t('Discours')} :: ${t('All authors')}`}>
|
||||||
<ReactionsProvider>
|
<ReactionsProvider>
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<AllAuthors authors={authors() || []} isLoaded={Boolean(authors())} />
|
<AllAuthors authors={authors() || []} isLoaded={Boolean(authors())} />
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const TopicPage = (props: RouteSectionProps<{ articles: Shout[] }>) => {
|
||||||
const { authorsEntities } = useAuthors()
|
const { authorsEntities } = useAuthors()
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const author = createMemo(() => authorsEntities?.()[params.slug])
|
const author = createMemo(() => authorsEntities?.()[params.slug])
|
||||||
const title = createMemo(() => `${t('Discours')}: ${author()?.name || ''}`)
|
const title = createMemo(() => `${author()?.name || ''}`)
|
||||||
|
|
||||||
// docs: `a side effect that is run the first time the expression
|
// docs: `a side effect that is run the first time the expression
|
||||||
// wrapped by the returned tracking function is notified of a change`
|
// wrapped by the returned tracking function is notified of a change`
|
||||||
|
@ -51,7 +51,7 @@ export const TopicPage = (props: RouteSectionProps<{ articles: Shout[] }>) => {
|
||||||
<ErrorBoundary fallback={(_err) => <FourOuFourView />}>
|
<ErrorBoundary fallback={(_err) => <FourOuFourView />}>
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<PageLayout
|
<PageLayout
|
||||||
title={title()}
|
title={`${t('Discours')} :: ${title()}`}
|
||||||
headerTitle={author()?.name || ''}
|
headerTitle={author()?.name || ''}
|
||||||
slug={author()?.slug}
|
slug={author()?.slug}
|
||||||
articleBody={author()?.about || author()?.bio || ''}
|
articleBody={author()?.about || author()?.bio || ''}
|
||||||
|
|
|
@ -20,7 +20,7 @@ export const DraftsPage = () => {
|
||||||
const drafts = createAsync(async () => await fetchDrafts(client))
|
const drafts = createAsync(async () => await fetchDrafts(client))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={t('Drafts')}>
|
<PageLayout title={`${t('Discours')} :: ${t('Drafts')}`}>
|
||||||
<AuthGuard>
|
<AuthGuard>
|
||||||
<DraftsView drafts={drafts() || []} />
|
<DraftsView drafts={drafts() || []} />
|
||||||
</AuthGuard>
|
</AuthGuard>
|
|
@ -64,7 +64,7 @@ export const EditPage = () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={title()}>
|
<PageLayout title={`${t('Discours')} :: ${title()}`}>
|
||||||
<AuthGuard>
|
<AuthGuard>
|
||||||
<EditView shout={shout() as Shout} />
|
<EditView shout={shout() as Shout} />
|
||||||
</AuthGuard>
|
</AuthGuard>
|
||||||
|
|
|
@ -25,7 +25,8 @@ export const EditSettingsPage = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<PageLayout title={t('Publication settings')}>
|
|
||||||
|
<PageLayout title={`${t('Discours')} :: ${t('Publication settings')}`}>
|
||||||
<AuthGuard>
|
<AuthGuard>
|
||||||
<EditSettingsView shout={shout() as Shout} />
|
<EditSettingsView shout={shout() as Shout} />
|
||||||
</AuthGuard>
|
</AuthGuard>
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<PageLayout title={ogTitle()}>
|
<PageLayout title={`${t('Discours')} :: ${ogTitle()}`}>
|
||||||
<Meta name="descprition" content={description()} />
|
<Meta name="descprition" content={description()} />
|
||||||
<Meta name="keywords" content={lang() === 'ru' ? ruKeywords[''] : enKeywords['']} />
|
<Meta name="keywords" content={lang() === 'ru' ? ruKeywords[''] : enKeywords['']} />
|
||||||
<Meta name="og:type" content="article" />
|
<Meta name="og:type" content="article" />
|
||||||
|
|
|
@ -60,7 +60,7 @@ export const ExpoPage = (props: RouteSectionProps<Shout[]>) => {
|
||||||
createEffect(on(title, (ttl) => (document.title = ttl), { defer: true }))
|
createEffect(on(title, (ttl) => (document.title = ttl), { defer: true }))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout withPadding={true} zeroBottomPadding={true} title={title()}>
|
<PageLayout withPadding={true} zeroBottomPadding={true} title={`${t('Discours')} :: ${title()}`}>
|
||||||
<Topics />
|
<Topics />
|
||||||
<Expo shouts={shouts() || []} layout={layout() as LayoutType} />
|
<Expo shouts={shouts() || []} layout={layout() as LayoutType} />
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
|
|
|
@ -125,7 +125,7 @@ export const FeedPage = (props: RouteSectionProps<Shout[]>) => {
|
||||||
}
|
}
|
||||||
createEffect(() => setIsLoadMoreButtonVisible(offset() < (shouts()?.length || 0)))
|
createEffect(() => setIsLoadMoreButtonVisible(offset() < (shouts()?.length || 0)))
|
||||||
return (
|
return (
|
||||||
<PageLayout title={t('Feed')}>
|
<PageLayout withPadding={true} title={`${t('Discours')} :: ${t('Feed')}`}>
|
||||||
<ReactionsProvider>
|
<ReactionsProvider>
|
||||||
<Feed shouts={shouts() || []} />
|
<Feed shouts={shouts() || []} />
|
||||||
</ReactionsProvider>
|
</ReactionsProvider>
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const ProfileSettingsPage = () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={t('Profile')}>
|
<PageLayout withPadding={true} title={`${t('Discours')} :: ${t('Profile')}`}>
|
||||||
<AuthGuard>
|
<AuthGuard>
|
||||||
<ProfileProvider>
|
<ProfileProvider>
|
||||||
<ProfileSettings />
|
<ProfileSettings />
|
||||||
|
|
|
@ -135,7 +135,7 @@ export const ProfileSecurityPage = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={t('Profile')}>
|
<PageLayout withPadding={true} title={`${t('Discours')} :: ${t('Security')}`}>
|
||||||
<AuthGuard>
|
<AuthGuard>
|
||||||
<Show when={isSessionLoaded()} fallback={<Loading />}>
|
<Show when={isSessionLoaded()} fallback={<Loading />}>
|
||||||
<div class="wide-container">
|
<div class="wide-container">
|
||||||
|
|
|
@ -7,7 +7,7 @@ export const ProfileSubscriptionsPage = () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={t('Profile')}>
|
<PageLayout withPadding={true} title={`${t('Discours')} :: ${t('Subscriptions')}`}>
|
||||||
<AuthGuard>
|
<AuthGuard>
|
||||||
<ProfileSubscriptions />
|
<ProfileSubscriptions />
|
||||||
</AuthGuard>
|
</AuthGuard>
|
||||||
|
|
|
@ -48,7 +48,7 @@ export const SearchPage = () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={t('Search')}>
|
<PageLayout withPadding={true} title={`${t('Discours')} :: ${t('Search')}`}>
|
||||||
<ReactionsProvider>
|
<ReactionsProvider>
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<Show when={isLoaded()} fallback={<Loading />}>
|
<Show when={isLoaded()} fallback={<Loading />}>
|
||||||
|
|
|
@ -22,7 +22,7 @@ export default function AllTopicsPage(props: RouteSectionProps<{ topics: Topic[]
|
||||||
const { addTopics } = useTopics()
|
const { addTopics } = useTopics()
|
||||||
createEffect(() => addTopics(topics() || []))
|
createEffect(() => addTopics(topics() || []))
|
||||||
return (
|
return (
|
||||||
<PageLayout withPadding={true} title={`${t('Discours')}:${t('All topics')}`}>
|
<PageLayout withPadding={true} title={`${t('Discours')} :: ${t('All topics')}`}>
|
||||||
<ReactionsProvider>
|
<ReactionsProvider>
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<AllTopics topics={topics() as Topic[]} />
|
<AllTopics topics={topics() as Topic[]} />
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const TopicPage = (props: RouteSectionProps<{ articles: Shout[] }>) => {
|
||||||
const { topicEntities } = useTopics()
|
const { topicEntities } = useTopics()
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const topic = createMemo(() => topicEntities?.()[params.slug])
|
const topic = createMemo(() => topicEntities?.()[params.slug])
|
||||||
const title = createMemo(() => `${t('Discours')}: ${topic()?.title || ''}`)
|
const title = createMemo(() => `${t('Discours')} :: ${topic()?.title || ''}`)
|
||||||
|
|
||||||
// docs: `a side effect that is run the first time the expression
|
// docs: `a side effect that is run the first time the expression
|
||||||
// wrapped by the returned tracking function is notified of a change`
|
// wrapped by the returned tracking function is notified of a change`
|
||||||
|
|
|
@ -69,7 +69,7 @@ test.describe('Pages open', () => {
|
||||||
Object.keys(pagesTitles).forEach((res: string) => {
|
Object.keys(pagesTitles).forEach((res: string) => {
|
||||||
test(`Open Page ${res}`, async ({ page }) => {
|
test(`Open Page ${res}`, async ({ page }) => {
|
||||||
await page.goto(`${res}`)
|
await page.goto(`${res}`)
|
||||||
const title = pagesTitles[res as keyof typeof pagesTitles] || ''
|
const title = pagesTitles[res as keyof typeof pagesTitles] || '00000000000'
|
||||||
await expect(page).toHaveTitle(title)
|
await expect(page).toHaveTitle(title)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user