From 02307010421f047eca9aabdc0d0009a0695198e3 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Fri, 21 Oct 2022 00:23:15 +0100 Subject: [PATCH] feat: new window preview --- src/components/site/SitePage.tsx | 10 ++- src/lib/page-helpers.ts | 8 +- src/lib/types.ts | 2 + src/models/page.model.ts | 89 +++++++++++++++------- src/pages/_site/[site]/preview/[page].tsx | 26 +++++++ src/pages/dashboard/[subdomain]/editor.tsx | 81 +++++++++++--------- 6 files changed, 148 insertions(+), 68 deletions(-) create mode 100644 src/pages/_site/[site]/preview/[page].tsx diff --git a/src/components/site/SitePage.tsx b/src/components/site/SitePage.tsx index d5eccf59..2448c4cd 100644 --- a/src/components/site/SitePage.tsx +++ b/src/components/site/SitePage.tsx @@ -8,7 +8,13 @@ export const SitePage: React.FC<{ }> = ({ page }) => { return ( <> -
+ {page?.preview && ( +
+ Currently in private preview mode, the content is different from the + public +
+ )} +
{page?.tags?.includes("post") ? (

{page.title}

) : ( @@ -23,7 +29,7 @@ export const SitePage: React.FC<{ content={page?.body?.content} toc={true} > - + {page?.metadata && } ) } diff --git a/src/lib/page-helpers.ts b/src/lib/page-helpers.ts index f16c8253..d87b3df7 100644 --- a/src/lib/page-helpers.ts +++ b/src/lib/page-helpers.ts @@ -4,14 +4,20 @@ import { PageVisibilityEnum } from "./types" export const getPageVisibility = ({ date_published, metadata, + preview, }: { date_published?: string metadata?: Object + preview?: boolean }) => { if (!metadata) { return PageVisibilityEnum.Draft } else if (dayjs(date_published).isBefore(new Date())) { - return PageVisibilityEnum.Published + if (preview) { + return PageVisibilityEnum.Modified + } else { + return PageVisibilityEnum.Published + } } else { return PageVisibilityEnum.Scheduled } diff --git a/src/lib/types.ts b/src/lib/types.ts index 0254f0a3..cb97bbd3 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -26,6 +26,7 @@ export enum PageVisibilityEnum { Scheduled = "scheduled", Draft = "draft", Crossbell = "crossbell", + Modified = "published and modified", } export type PostOnSiteHome = { @@ -83,6 +84,7 @@ export type Note = UniNote & { mime_type?: string element?: ReactElement } + preview?: boolean } export type Notes = { diff --git a/src/models/page.model.ts b/src/models/page.model.ts index 467b486e..4187131d 100644 --- a/src/models/page.model.ts +++ b/src/models/page.model.ts @@ -130,7 +130,7 @@ const expandPage = (page: Note, render: boolean) => { const getLocalPages = (input: { site: string; isPost?: boolean }) => { const pages: Note[] = [] - getKeys(`draft-${input.site}-local`).forEach((key) => { + getKeys(`draft-${input.site}`).forEach((key) => { const page = getStorage(key) if (input.isPost === undefined || page.isPost === input.isPost) { pages.push({ @@ -140,6 +140,7 @@ const getLocalPages = (input: { site: string; isPost?: boolean }) => { content: page.values?.content, mime_type: "text/markdown", }, + date_updated: new Date(page.date).toISOString(), date_published: page.values?.publishedAt, summary: { content: page.values?.excerpt, @@ -161,6 +162,7 @@ const getLocalPages = (input: { site: string; isPost?: boolean }) => { }, ], }), + preview: true, }) } }) @@ -225,8 +227,20 @@ export async function getPagesBySite( site: input.site, isPost: input.type === "post", }) - pages.list = pages.list.concat(local) - pages.total += local.length + local.forEach((localPage) => { + const index = pages.list.findIndex((page) => page.id === localPage.id) + if ( + index >= 0 && + new Date(localPage.date_updated) > + new Date(pages.list[index].date_updated) + ) { + localPage.metadata = pages.list[index].metadata + pages.list[index] = localPage + } else { + pages.list.push(localPage) + pages.total++ + } + }) } if (pages?.list) { @@ -285,43 +299,60 @@ export async function getPage( const local = getLocalPages({ site: input.site, }) - const localPage = local.find((page) => page.id === input.pageId) + const localPage = local.find( + (page) => page.id === input.page || page.id === input.pageId, + ) + + const mustLocal = input.pageId?.startsWith("local-") + + const pages: Notes | null = mustLocal + ? null + : await (customUnidata || unidata).notes.get({ + source: "Crossbell Note", + identity: input.site, + platform: "Crossbell", + limit: 1000, + ...(input.pageId && { + filter: { + id: input.pageId, + }, + }), + }) let page - if (localPage) { - page = localPage - } else { - const pages: Notes | null = await (customUnidata || unidata).notes.get({ - source: "Crossbell Note", - identity: input.site, - platform: "Crossbell", - limit: 1000, - ...(input.pageId && { - filter: { - id: input.pageId, - }, - }), + if (input.page) { + page = pages?.list.find((item) => { + item.slug = + item.attributes?.find((a) => a.trait_type === "xlog_slug")?.value || + item.metadata?.raw?._xlog_slug || + item.metadata?.raw?._crosslog_slug || + item.id + return item.slug === input.page || item.id === input.page }) + } else { + page = pages?.list[0] + } - if (input.page) { - page = pages?.list.find((item) => { - item.slug = - item.attributes?.find((a) => a.trait_type === "xlog_slug")?.value || - item.metadata?.raw?._xlog_slug || - item.metadata?.raw?._crosslog_slug || - item.id - return item.slug === input.page || item.id === input.page - }) + if (localPage) { + if (page) { + if (new Date(localPage.date_updated) > new Date(page.date_updated)) { + localPage.metadata = page.metadata + page = localPage + } } else { - page = pages?.list[0] + page = localPage } } - if (!page) { + if (!page && !mustLocal) { throw notFound(`page ${input.page} not found`) } - expandPage(page, input.render || false) + if (page) { + expandPage(page, input.render || false) + } else { + page = null + } return page } diff --git a/src/pages/_site/[site]/preview/[page].tsx b/src/pages/_site/[site]/preview/[page].tsx new file mode 100644 index 00000000..54e35656 --- /dev/null +++ b/src/pages/_site/[site]/preview/[page].tsx @@ -0,0 +1,26 @@ +import { SiteLayout } from "~/components/site/SiteLayout" +import { SitePage } from "~/components/site/SitePage" +import { useGetPage } from "~/queries/page" +import type { ReactElement } from "react" +import { useRouter } from "next/router" + +function SitePagePage() { + const router = useRouter() + const site = router.query.site as string + const pageSlug = router.query.page as string + + const page = useGetPage({ + site: site, + page: pageSlug, + render: true, + includeAuthors: true, + }) + + return +} + +SitePagePage.getLayout = (page: ReactElement) => { + return {page} +} + +export default SitePagePage diff --git a/src/pages/dashboard/[subdomain]/editor.tsx b/src/pages/dashboard/[subdomain]/editor.tsx index 4f902a19..18b4b07d 100644 --- a/src/pages/dashboard/[subdomain]/editor.tsx +++ b/src/pages/dashboard/[subdomain]/editor.tsx @@ -24,7 +24,7 @@ import { getPageVisibility } from "~/lib/page-helpers" import { PageVisibilityEnum } from "~/lib/types" import { useGetPage, useCreateOrUpdatePage } from "~/queries/page" import { useGetSite } from "~/queries/site" -import { getStorage, setStorage, delStorage } from "~/lib/storage" +import { setStorage, delStorage } from "~/lib/storage" import { nanoid } from "nanoid" import { useQueryClient } from "@tanstack/react-query" import { PageContent } from "~/components/common/PageContent" @@ -34,6 +34,7 @@ import type { Root } from "hast" import type { EditorView } from "@codemirror/view" import { Editor } from "~/components/ui/Editor" import { renderPageContent } from "~/markdown" +import { Button } from "~/components/ui/Button" const getInputDatetimeValue = (date: Date | string) => { const str = dayjs(date).format() @@ -52,9 +53,13 @@ export default function SubdomainEditor() { useEffect(() => { if (subdomain) { if (!pageId) { - const key = `draft-${subdomain}-local-${nanoid()}` + const randomId = nanoid() + const key = `draft-${subdomain}-local-${randomId}` setDraftKey(key) queryClient.invalidateQueries(["getPagesBySite", subdomain]) + router.replace( + `/dashboard/${subdomain}/editor?id=local-${randomId}&type=${router.query.type}`, + ) } else { setDraftKey(`draft-${subdomain}-${pageId}`) } @@ -65,14 +70,13 @@ export default function SubdomainEditor() { const page = useGetPage({ site: subdomain!, - pageId: pageId, + pageId: pageId || draftKey.replace(`draft-${subdomain}-`, ""), render: false, }) const visibility = page.data ? getPageVisibility(page.data) : PageVisibilityEnum.Draft - const published = visibility !== PageVisibilityEnum.Draft const uploadFile = useUploadFile() @@ -161,25 +165,18 @@ export default function SubdomainEditor() { useEffect(() => { if (!page.data || !draftKey) return - const local = getStorage(draftKey) - const useLocal = - local?.date && +new Date(local?.date) > +new Date(page.data.date_updated) - if (useLocal && local?.values) { - setValues(local?.values) - } else { - setValues({ - title: page.data.title || "", - publishedAt: page.data.date_published, - published: !!page.data.id, - excerpt: page.data.summary?.content || "", - slug: page.data.slug || "", - tags: - page.data.tags - ?.filter((tag) => tag !== "post" && tag !== "page") - ?.join(", ") || "", - content: page.data.body?.content || "", - }) - } + setValues({ + title: page.data.title || "", + publishedAt: page.data.date_published, + published: !!page.data.id, + excerpt: page.data.summary?.content || "", + slug: page.data.slug || "", + tags: + page.data.tags + ?.filter((tag) => tag !== "post" && tag !== "page") + ?.join(", ") || "", + content: page.data.body?.content || "", + }) }, [page.data, subdomain, draftKey]) const [currentScrollArea, setCurrentScrollArea] = useState("") @@ -353,25 +350,37 @@ export default function SubdomainEditor() {
- {visibility === PageVisibilityEnum.Published - ? `Published${ - getStorage(draftKey) - ? " and local modifications exist" - : "" - }` - : visibility === PageVisibilityEnum.Scheduled - ? "Scheduled" - : "Draft"} + {visibility.toLowerCase()} +