From 0fb54b42fcf1180fb9d787dba53b31a79eaec39b Mon Sep 17 00:00:00 2001 From: DIYgod Date: Wed, 29 Jun 2022 18:55:43 +0100 Subject: [PATCH] feat: crossbell renovation - site page page --- src/components/site/SitePage.tsx | 29 +++++---- src/models/page.model.ts | 100 ++++++++++++++++-------------- src/pages/_site/[site]/[page].tsx | 57 +++++------------ 3 files changed, 89 insertions(+), 97 deletions(-) diff --git a/src/components/site/SitePage.tsx b/src/components/site/SitePage.tsx index db6166ed..87f80a26 100644 --- a/src/components/site/SitePage.tsx +++ b/src/components/site/SitePage.tsx @@ -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 ( <>
- {page.type === "POST" ? ( + {page.tags?.includes("post") ? (

{page.title}

) : (

{page.title}

)} - {page.type === "POST" && ( + {page.tags?.includes("post") && ( )}
diff --git a/src/models/page.model.ts b/src/models/page.model.ts index 8b8eea43..a8a69f68 100644 --- a/src/models/page.model.ts +++ b/src/models/page.model.ts @@ -195,7 +195,6 @@ export async function deletePage({ site, id }: { site: string, id: string }) { } export async function getPage( - 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( 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 ( diff --git a/src/pages/_site/[site]/[page].tsx b/src/pages/_site/[site]/[page].tsx index e77259a9..68cd67b1 100644 --- a/src/pages/_site/[site]/[page].tsx +++ b/src/pages/_site/[site]/[page].tsx @@ -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 ( - + ) }