feat: home optimization - reuse layout
This commit is contained in:
parent
a14d04edbe
commit
051690f764
|
|
@ -1,38 +1,90 @@
|
|||
import clsx from "clsx"
|
||||
import React, { useEffect } from "react"
|
||||
import { getUserContentsUrl } from "~/lib/user-contents"
|
||||
import { SEOHead } from "../common/SEOHead"
|
||||
import { SiteNavigationItem, Viewer, Profile, Note } from "~/lib/types"
|
||||
import { SiteFooter } from "./SiteFooter"
|
||||
import { SiteHeader } from "./SiteHeader"
|
||||
import { useRouter } from "next/router"
|
||||
import { useStore } from "~/lib/store"
|
||||
import { BlockchainInfo } from "~/components/common/BlockchainInfo"
|
||||
import type { Links } from "unidata.js"
|
||||
import { GetServerSideProps } from "next"
|
||||
import {
|
||||
prefetchGetSite,
|
||||
prefetchGetSiteSubscriptions,
|
||||
} from "~/queries/site.server"
|
||||
import { prefetchGetPagesBySite } from "~/queries/page.server"
|
||||
import { PageVisibilityEnum } from "~/lib/types"
|
||||
import { useGetSiteSubscriptions } from "~/queries/site"
|
||||
import { dehydrate } from "@tanstack/react-query"
|
||||
import { queryClientServer } from "~/lib/query-client.server"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
import { fetchGetPage } from "~/queries/page.server"
|
||||
import { notFound } from "~/lib/server-side-props"
|
||||
import { useGetPage } from "~/queries/page"
|
||||
|
||||
export type SiteLayoutProps = {
|
||||
site?: Profile
|
||||
viewer?: Profile | null
|
||||
children: React.ReactNode
|
||||
title?: string | null
|
||||
ogDescription?: string | null
|
||||
page?: Note
|
||||
subscriptions?: Links | null
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const domainOrSubdomain = ctx.params!.site as string
|
||||
const pageSlug = ctx.params!.page as string
|
||||
const tag = ctx.params!.tag as string
|
||||
|
||||
await prefetchGetSite(domainOrSubdomain)
|
||||
await prefetchGetSiteSubscriptions({
|
||||
siteId: domainOrSubdomain,
|
||||
})
|
||||
|
||||
if (pageSlug) {
|
||||
const page = await fetchGetPage({
|
||||
site: domainOrSubdomain,
|
||||
page: pageSlug,
|
||||
render: true,
|
||||
includeAuthors: true,
|
||||
})
|
||||
|
||||
if (new Date(page!.date_published) > new Date()) {
|
||||
throw notFound()
|
||||
}
|
||||
} else {
|
||||
await prefetchGetPagesBySite({
|
||||
site: domainOrSubdomain,
|
||||
take: 1000,
|
||||
type: "post",
|
||||
visibility: PageVisibilityEnum.Published,
|
||||
render: true,
|
||||
...(tag && { tags: [tag] }),
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
dehydratedState: dehydrate(queryClientServer),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const SiteLayout: React.FC<SiteLayoutProps> = ({
|
||||
site,
|
||||
viewer,
|
||||
children,
|
||||
title,
|
||||
ogDescription,
|
||||
page,
|
||||
subscriptions,
|
||||
}) => {
|
||||
export type SiteLayoutProps = {
|
||||
children: React.ReactNode
|
||||
title?: string | null
|
||||
}
|
||||
|
||||
export const SiteLayout: React.FC<SiteLayoutProps> = ({ children, title }) => {
|
||||
const router = useRouter()
|
||||
const domainOrSubdomain = router.query.site as string
|
||||
const pageSlug = router.query.page as string
|
||||
const tag = router.query.tag as string
|
||||
|
||||
const page = useGetPage({
|
||||
site: domainOrSubdomain,
|
||||
page: pageSlug,
|
||||
render: true,
|
||||
includeAuthors: true,
|
||||
})
|
||||
|
||||
const setSubscribeModalOpened = useStore(
|
||||
(store) => store.setSubscribeModalOpened,
|
||||
)
|
||||
const site = useGetSite(domainOrSubdomain)
|
||||
const subscriptions = useGetSiteSubscriptions({
|
||||
siteId: domainOrSubdomain,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if ("subscription" in router.query) {
|
||||
|
|
@ -43,25 +95,26 @@ export const SiteLayout: React.FC<SiteLayoutProps> = ({
|
|||
return (
|
||||
<>
|
||||
<SEOHead
|
||||
title={title || page?.title || ""}
|
||||
siteName={site?.name || ""}
|
||||
title={title || tag || page.data?.title || ""}
|
||||
siteName={site.data?.name || ""}
|
||||
description={
|
||||
ogDescription ?? site?.description?.replace(/<[^>]*>/g, "")
|
||||
(page.data?.summary?.content || page.data?.body?.content) ??
|
||||
site.data?.description?.replace(/<[^>]*>/g, "")
|
||||
}
|
||||
image={page?.cover || getUserContentsUrl(site?.avatars?.[0])}
|
||||
icon={getUserContentsUrl(site?.avatars?.[0])}
|
||||
image={page.data?.cover || getUserContentsUrl(site.data?.avatars?.[0])}
|
||||
icon={getUserContentsUrl(site.data?.avatars?.[0])}
|
||||
/>
|
||||
<SiteHeader site={site} subscriptions={subscriptions} />
|
||||
<style>{site?.css}</style>
|
||||
<SiteHeader site={site.data} subscriptions={subscriptions.data} />
|
||||
<style>{site.data?.css}</style>
|
||||
<div
|
||||
className={`xlog-post-id-${page?.id} max-w-screen-md mx-auto px-5 pt-12`}
|
||||
className={`xlog-post-id-${page.data?.id} max-w-screen-md mx-auto px-5 pt-12`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<div className="max-w-screen-md mx-auto pt-12 pb-10">
|
||||
<BlockchainInfo site={site} page={page} />
|
||||
<BlockchainInfo site={site.data} page={page.data} />
|
||||
</div>
|
||||
<SiteFooter site={site} page={page} />
|
||||
<SiteFooter site={site.data} page={page.data} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
import type { PageType } from "~/lib/db.server"
|
||||
import { Rendered } from "~/markdown"
|
||||
import { PageContent } from "../common/PageContent"
|
||||
import { PostMeta } from "./PostMeta"
|
||||
import { PostFooter } from "./PostFooter"
|
||||
import { Profile, Note } from "~/lib/types"
|
||||
import { Note } from "~/lib/types"
|
||||
|
||||
export const SitePage: React.FC<{
|
||||
site?: Profile
|
||||
page?: Note
|
||||
}> = ({ site, page }) => {
|
||||
}> = ({ page }) => {
|
||||
return (
|
||||
<>
|
||||
<div className="">
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ const queryClient = new QueryClient({
|
|||
const persister = createIDBPersister()
|
||||
|
||||
function MyApp({ Component, pageProps }: any) {
|
||||
const getLayout = Component.getLayout ?? ((page: any) => page)
|
||||
|
||||
return (
|
||||
<WagmiConfig client={wagmiClient}>
|
||||
<RainbowKitProvider chains={chains}>
|
||||
|
|
@ -82,7 +84,7 @@ function MyApp({ Component, pageProps }: any) {
|
|||
<Hydrate state={pageProps.dehydratedState}>
|
||||
<ReactQueryDevtools />
|
||||
<IpfsGatewayContext.Provider value={ipfsGateway}>
|
||||
<Component {...pageProps} />
|
||||
{getLayout(<Component {...pageProps} />)}
|
||||
</IpfsGatewayContext.Provider>
|
||||
<Toaster />
|
||||
</Hydrate>
|
||||
|
|
|
|||
|
|
@ -1,31 +1,21 @@
|
|||
import { GetServerSideProps } from "next"
|
||||
import { SiteLayout } from "~/components/site/SiteLayout"
|
||||
import {
|
||||
SiteLayout,
|
||||
getServerSideProps as getLayoutServerSideProps,
|
||||
} from "~/components/site/SiteLayout"
|
||||
import { SitePage } from "~/components/site/SitePage"
|
||||
import { serverSidePropsHandler } from "~/lib/server-side-props"
|
||||
import { queryClientServer } from "~/lib/query-client.server"
|
||||
import { prefetchGetSite } from "~/queries/site.server"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
import { dehydrate, QueryClient } from "@tanstack/react-query"
|
||||
import { fetchGetPage } from "~/queries/page.server"
|
||||
import { dehydrate } from "@tanstack/react-query"
|
||||
import { useGetPage } from "~/queries/page"
|
||||
import { notFound } from "~/lib/server-side-props"
|
||||
import type { ReactElement } from "react"
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
|
||||
async (ctx) => {
|
||||
const domainOrSubdomain = ctx.params!.site as string
|
||||
const pageSlug = ctx.params!.page as string
|
||||
|
||||
await prefetchGetSite(domainOrSubdomain)
|
||||
const page = await fetchGetPage({
|
||||
site: domainOrSubdomain,
|
||||
page: pageSlug,
|
||||
render: true,
|
||||
includeAuthors: true,
|
||||
})
|
||||
|
||||
if (new Date(page!.date_published) > new Date()) {
|
||||
throw notFound()
|
||||
}
|
||||
await getLayoutServerSideProps(ctx)
|
||||
|
||||
return {
|
||||
props: {
|
||||
|
|
@ -50,15 +40,12 @@ function SitePagePage({
|
|||
render: true,
|
||||
includeAuthors: true,
|
||||
})
|
||||
const ogDescription = page.data?.summary?.content || page.data?.body?.content
|
||||
|
||||
const site = useGetSite(domainOrSubdomain)
|
||||
return <SitePage page={page.data} />
|
||||
}
|
||||
|
||||
return (
|
||||
<SiteLayout site={site.data} ogDescription={ogDescription} page={page.data}>
|
||||
<SitePage site={site.data} page={page.data} />
|
||||
</SiteLayout>
|
||||
)
|
||||
SitePagePage.getLayout = (page: ReactElement) => {
|
||||
return <SiteLayout>{page}</SiteLayout>
|
||||
}
|
||||
|
||||
export default SitePagePage
|
||||
|
|
|
|||
|
|
@ -1,27 +1,21 @@
|
|||
import { GetServerSideProps } from "next"
|
||||
import { SiteLayout } from "~/components/site/SiteLayout"
|
||||
import {
|
||||
SiteLayout,
|
||||
getServerSideProps as getLayoutServerSideProps,
|
||||
} from "~/components/site/SiteLayout"
|
||||
import { serverSidePropsHandler } from "~/lib/server-side-props"
|
||||
import { SiteArchives } from "~/components/site/SiteArchives"
|
||||
import { Viewer, Profile, Notes } from "~/lib/types"
|
||||
import { Profile, Notes } from "~/lib/types"
|
||||
import { queryClientServer } from "~/lib/query-client.server"
|
||||
import { prefetchGetSite } from "~/queries/site.server"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
import { dehydrate, QueryClient } from "@tanstack/react-query"
|
||||
import { dehydrate } from "@tanstack/react-query"
|
||||
import { useGetPagesBySite } from "~/queries/page"
|
||||
import { prefetchGetPagesBySite } from "~/queries/page.server"
|
||||
import { PageVisibilityEnum } from "~/lib/types"
|
||||
import type { ReactElement } from "react"
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
|
||||
async (ctx) => {
|
||||
const domainOrSubdomain = ctx.params!.site as string
|
||||
|
||||
await prefetchGetSite(domainOrSubdomain)
|
||||
await prefetchGetPagesBySite({
|
||||
site: domainOrSubdomain,
|
||||
take: 1000,
|
||||
type: "post",
|
||||
visibility: PageVisibilityEnum.Published,
|
||||
})
|
||||
await getLayoutServerSideProps(ctx)
|
||||
|
||||
return {
|
||||
props: {
|
||||
|
|
@ -39,19 +33,19 @@ function SiteArchivesPage({
|
|||
posts: Notes
|
||||
domainOrSubdomain: string
|
||||
}) {
|
||||
const site = useGetSite(domainOrSubdomain)
|
||||
const posts = useGetPagesBySite({
|
||||
site: domainOrSubdomain,
|
||||
take: 1000,
|
||||
type: "post",
|
||||
visibility: PageVisibilityEnum.Published,
|
||||
render: true,
|
||||
})
|
||||
|
||||
return (
|
||||
<SiteLayout site={site.data} title="Archives">
|
||||
<SiteArchives posts={posts.data} />
|
||||
</SiteLayout>
|
||||
)
|
||||
return <SiteArchives posts={posts.data} />
|
||||
}
|
||||
|
||||
SiteArchivesPage.getLayout = (page: ReactElement) => {
|
||||
return <SiteLayout title="Archives">{page}</SiteLayout>
|
||||
}
|
||||
|
||||
export default SiteArchivesPage
|
||||
|
|
|
|||
|
|
@ -1,32 +1,18 @@
|
|||
import { GetServerSideProps } from "next"
|
||||
import { SiteHome } from "~/components/site/SiteHome"
|
||||
import { SiteLayout } from "~/components/site/SiteLayout"
|
||||
import { queryClientServer } from "~/lib/query-client.server"
|
||||
import {
|
||||
prefetchGetSite,
|
||||
prefetchGetSiteSubscriptions,
|
||||
} from "~/queries/site.server"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
import { dehydrate, QueryClient } from "@tanstack/react-query"
|
||||
SiteLayout,
|
||||
getServerSideProps as getLayoutServerSideProps,
|
||||
} from "~/components/site/SiteLayout"
|
||||
import { queryClientServer } from "~/lib/query-client.server"
|
||||
import { dehydrate } from "@tanstack/react-query"
|
||||
import { useGetPagesBySite } from "~/queries/page"
|
||||
import { prefetchGetPagesBySite } from "~/queries/page.server"
|
||||
import { PageVisibilityEnum } from "~/lib/types"
|
||||
import { useGetSiteSubscriptions } from "~/queries/site"
|
||||
import type { ReactElement } from "react"
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const domainOrSubdomain = ctx.params!.site as string
|
||||
|
||||
await prefetchGetSite(domainOrSubdomain)
|
||||
await prefetchGetPagesBySite({
|
||||
site: domainOrSubdomain,
|
||||
take: 1000,
|
||||
type: "post",
|
||||
visibility: PageVisibilityEnum.Published,
|
||||
render: true,
|
||||
})
|
||||
await prefetchGetSiteSubscriptions({
|
||||
siteId: domainOrSubdomain,
|
||||
})
|
||||
await getLayoutServerSideProps(ctx)
|
||||
|
||||
return {
|
||||
props: {
|
||||
|
|
@ -37,7 +23,6 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
|||
}
|
||||
|
||||
function SiteIndexPage({ domainOrSubdomain }: { domainOrSubdomain: string }) {
|
||||
const site = useGetSite(domainOrSubdomain)
|
||||
const posts = useGetPagesBySite({
|
||||
site: domainOrSubdomain,
|
||||
take: 1000,
|
||||
|
|
@ -45,15 +30,12 @@ function SiteIndexPage({ domainOrSubdomain }: { domainOrSubdomain: string }) {
|
|||
visibility: PageVisibilityEnum.Published,
|
||||
render: true,
|
||||
})
|
||||
const subscriptions = useGetSiteSubscriptions({
|
||||
siteId: domainOrSubdomain,
|
||||
})
|
||||
|
||||
return (
|
||||
<SiteLayout site={site.data} subscriptions={subscriptions.data}>
|
||||
<SiteHome posts={posts.data} />
|
||||
</SiteLayout>
|
||||
)
|
||||
return <SiteHome posts={posts.data} />
|
||||
}
|
||||
|
||||
SiteIndexPage.getLayout = (page: ReactElement) => {
|
||||
return <SiteLayout>{page}</SiteLayout>
|
||||
}
|
||||
|
||||
export default SiteIndexPage
|
||||
|
|
|
|||
|
|
@ -1,29 +1,23 @@
|
|||
import { GetServerSideProps } from "next"
|
||||
import { SiteLayout } from "~/components/site/SiteLayout"
|
||||
import {
|
||||
SiteLayout,
|
||||
getServerSideProps as getLayoutServerSideProps,
|
||||
} from "~/components/site/SiteLayout"
|
||||
import { serverSidePropsHandler } from "~/lib/server-side-props"
|
||||
import { SiteArchives } from "~/components/site/SiteArchives"
|
||||
import { Viewer, Profile, Notes } from "~/lib/types"
|
||||
import { Profile, Notes } from "~/lib/types"
|
||||
import { queryClientServer } from "~/lib/query-client.server"
|
||||
import { prefetchGetSite } from "~/queries/site.server"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
import { dehydrate, QueryClient } from "@tanstack/react-query"
|
||||
import { dehydrate } from "@tanstack/react-query"
|
||||
import { useGetPagesBySite } from "~/queries/page"
|
||||
import { prefetchGetPagesBySite } from "~/queries/page.server"
|
||||
import { PageVisibilityEnum } from "~/lib/types"
|
||||
import type { ReactElement } from "react"
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
|
||||
async (ctx) => {
|
||||
const domainOrSubdomain = ctx.params!.site as string
|
||||
const tag = ctx.params!.tag as string
|
||||
|
||||
await prefetchGetSite(domainOrSubdomain)
|
||||
await prefetchGetPagesBySite({
|
||||
site: domainOrSubdomain,
|
||||
take: 1000,
|
||||
type: "post",
|
||||
visibility: PageVisibilityEnum.Published,
|
||||
tags: [tag],
|
||||
})
|
||||
await getLayoutServerSideProps(ctx)
|
||||
|
||||
return {
|
||||
props: {
|
||||
|
|
@ -35,7 +29,7 @@ export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
|
|||
},
|
||||
)
|
||||
|
||||
function SiteArchivesPage({
|
||||
function SiteTagPage({
|
||||
domainOrSubdomain,
|
||||
tag,
|
||||
}: {
|
||||
|
|
@ -44,20 +38,20 @@ function SiteArchivesPage({
|
|||
domainOrSubdomain: string
|
||||
tag: string
|
||||
}) {
|
||||
const site = useGetSite(domainOrSubdomain)
|
||||
const posts = useGetPagesBySite({
|
||||
site: domainOrSubdomain,
|
||||
take: 1000,
|
||||
type: "post",
|
||||
visibility: PageVisibilityEnum.Published,
|
||||
render: true,
|
||||
tags: [tag],
|
||||
})
|
||||
|
||||
return (
|
||||
<SiteLayout site={site.data} title={tag}>
|
||||
<SiteArchives posts={posts.data} title={tag} />
|
||||
</SiteLayout>
|
||||
)
|
||||
return <SiteArchives posts={posts.data} title={tag} />
|
||||
}
|
||||
|
||||
export default SiteArchivesPage
|
||||
SiteTagPage.getLayout = (page: ReactElement) => {
|
||||
return <SiteLayout>{page}</SiteLayout>
|
||||
}
|
||||
|
||||
export default SiteTagPage
|
||||
|
|
|
|||
Loading…
Reference in New Issue