feat: crossbell renovation - site page page

This commit is contained in:
DIYgod 2022-06-29 18:55:43 +01:00
parent e53aa3ea02
commit 0fb54b42fc
No known key found for this signature in database
GPG Key ID: D159328F47A80DCA
3 changed files with 89 additions and 97 deletions

View File

@ -2,33 +2,40 @@ import type { PageType } from "~/lib/db.server"
import { Rendered } from "~/markdown"
import { PageContent } from "../common/PageContent"
import { PostMeta } from "./PostMeta"
import { Profile } from "unidata.js"
export const SitePage: React.FC<{
site: Profile,
page: {
type: PageType
publishedAt: string
title: string
rendered: Rendered | null
authors?: { id: string; name: string; avatar: string | null }[]
tags?: string[]
date_published: string
title?: string
body?: {
content?: string
}
}
}> = ({ page }) => {
}> = ({ site, page }) => {
return (
<>
<div className="">
{page.type === "POST" ? (
{page.tags?.includes("post") ? (
<h2 className="text-4xl font-bold">{page.title}</h2>
) : (
<h2 className="text-xl font-bold page-title">{page.title}</h2>
)}
{page.type === "POST" && (
{page.tags?.includes("post") && (
<PostMeta
publishedAt={page.publishedAt}
authors={page.authors || []}
publishedAt={page.date_published}
authors={[{
id: site.username || "",
name: site.name || "",
avatar: site.avatars?.[0] || null,
}] || []}
/>
)}
</div>
<PageContent
contentHTML={page.rendered?.contentHTML || ""}
contentHTML={page.body?.content || ""}
className="my-8"
/>
</>

View File

@ -195,7 +195,6 @@ export async function deletePage({ site, id }: { site: string, id: string }) {
}
export async function getPage<TRender extends boolean = false>(
gate: Gate,
input: {
/** page slug or id, `site` is needed when `page` is a slug */
page: string
@ -204,57 +203,68 @@ export async function getPage<TRender extends boolean = false>(
includeAuthors?: boolean
},
) {
// const site = input.site ? await getSite(input.site) : null
if (!input.site) {
throw notFound(`site not found`)
}
// if (input.site && !site) {
// throw notFound(`site not found`)
// }
const isPageUUID = isUUID(input.page)
if (!isPageUUID && !input.site) {
throw new Error("input.site is required because input.page is a slug")
}
// const isPageUUID = isUUID(input.page)
// if (!isPageUUID && !input.site) {
// throw new Error("input.site is required because input.page is a slug")
// }
const pages = await unidata.notes.get({
source: 'Crossbell Note',
identity: input.site,
platform: 'Crossbell',
filter: {
id: input.page,
}
})
// const page = isPageUUID
// ? await prismaRead.page.findUnique({
// where: {
// id: input.page,
// },
// include: {
// authors: input.includeAuthors,
// },
// })
// : site
// ? await prismaRead.page.findFirst({
// where: { siteId: site.id, slug: input.page },
// include: {
// authors: input.includeAuthors,
// },
// })
// : null
const page = pages?.list[0]
// if (!page || page.deletedAt) {
// throw notFound(`page ${input.page} not found`)
// }
if (!page) {
throw notFound(`page ${input.page} not found`)
}
// if (!gate.allows({ type: "can-read-page", page })) {
// if (!page.published || page.publishedAt > new Date()) {
// throw notFound()
// } else {
// throw gate.permissionError()
// }
// }
if (new Date(page.date_published) > new Date()) {
throw notFound()
}
// const rendered = (
// input.render
// ? page.rendered || (await renderPageContent(page.content))
// : null
// ) as TRender extends true ? Rendered : null
if (pages?.list) {
pages.list = await Promise.all(pages?.list.map(async (page) => {
if (page.body?.content && page.body?.mime_type === 'text/markdown' && input.render) {
const rendered = await renderPageContent(page.body.content)
page.body = {
content: rendered.contentHTML,
mime_type: 'text/html'
}
if (!page.summary) {
page.summary = {
content: rendered.excerpt,
mime_type: 'text/html'
}
}
}
return page
}))
}
// return {
// ...page,
// rendered,
// }
if (page.body?.content && page.body?.mime_type === 'text/markdown' && input.render) {
const rendered = await renderPageContent(page.body.content)
page.body = {
content: rendered.contentHTML,
mime_type: 'text/html'
}
if (!page.summary) {
page.summary = {
content: rendered.excerpt,
mime_type: 'text/html'
}
}
}
return page
}
export const notifySubscribersForNewPost = async (

View File

@ -9,79 +9,54 @@ import { SitePage } from "~/components/site/SitePage"
import { serverSidePropsHandler } from "~/lib/server-side-props"
import { getViewer } from "~/lib/viewer"
import { Viewer } from "~/lib/types"
import { getUserSites, getSite } from "~/models/site.model"
import { getPage } from "~/models/page.model"
import { Profile, Note } from "unidata.js"
import { PageVisibilityEnum } from "~/lib/types"
export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
async (ctx) => {
const user = await getAuthUser(ctx.req)
const viewer = getViewer(user)
const domainOrSubdomain = ctx.params!.site as string
const pageSlug = ctx.params!.page as string
const trpcContext = await getTRPCContext(ctx)
const ssg = createSSGHelpers({ router: appRouter, ctx: trpcContext })
await Promise.all([
ssg.fetchQuery("site", { site: domainOrSubdomain }),
ssg.fetchQuery("site.page", {
const [site, page] = await Promise.all([
getSite(domainOrSubdomain),
getPage({
site: domainOrSubdomain,
page: pageSlug,
render: true,
includeAuthors: true,
}),
ssg.fetchQuery("site.subscription", { site: domainOrSubdomain }),
])
const trpcState = ssg.dehydrate()
return {
props: {
viewer,
site,
page,
domainOrSubdomain,
pageSlug,
trpcState,
},
}
},
)
function SitePagePage({
viewer,
site,
page,
domainOrSubdomain,
pageSlug,
}: {
viewer: Viewer | null
site: Profile,
page: Note,
domainOrSubdomain: string
pageSlug: string
}) {
const { data: site } = trpc.useQuery(
["site", { site: domainOrSubdomain }],
{},
)
const { data: subscription } = trpc.useQuery([
"site.subscription",
{ site: domainOrSubdomain },
])
const { data: page } = trpc.useQuery([
"site.page",
{
site: domainOrSubdomain,
page: pageSlug,
render: true,
includeAuthors: true,
},
])
const ogDescription = page?.excerpt || page?.rendered?.excerpt
const ogDescription = page.summary?.content || page.body?.content
return (
<SiteLayout
site={site!}
title={page!.title}
viewer={viewer}
subscription={subscription}
ogDescription={ogDescription}
>
<SitePage page={page!} />
<SitePage site={site!} page={page!} />
</SiteLayout>
)
}