feat: support mark any crossbell notes as xlog notes

This commit is contained in:
DIYgod 2022-09-29 21:52:42 +01:00
parent b02a4cd553
commit 306edcd9aa
No known key found for this signature in database
GPG Key ID: D159328F47A80DCA
4 changed files with 129 additions and 82 deletions

View File

@ -24,6 +24,7 @@ import { UniLink } from "../ui/UniLink"
import { nanoid } from "nanoid"
import { renderPageContent } from "~/markdown"
import { Tooltip } from "../ui/Tooltip"
import { APP_NAME } from "~/lib/env"
export const PagesManager: React.FC<{
isPost: boolean
@ -57,8 +58,12 @@ export const PagesManager: React.FC<{
toast.success("Converted!", {
id: convertToastId,
})
} else if (createOrUpdatePage.isError) {
toast.error("Failed to convert.", {
id: convertToastId,
})
}
}, [createOrUpdatePage.isSuccess, convertToastId])
}, [createOrUpdatePage.isSuccess, createOrUpdatePage.isError, convertToastId])
const pages = useGetPagesBySite({
type: isPost ? "post" : "page",
@ -85,6 +90,10 @@ export const PagesManager: React.FC<{
value: PageVisibilityEnum.Scheduled,
text: "Scheduled",
},
{
value: PageVisibilityEnum.Crossbell,
text: "Others on Crossbell",
},
].map((item) => ({
text: item.text,
onClick: () => {
@ -111,6 +120,7 @@ export const PagesManager: React.FC<{
const queryClient = useQueryClient()
const getPageMenuItems = (page: Note) => {
const isCrossbell = !page.applications?.includes("xlog")
return [
{
text: "Edit",
@ -133,21 +143,18 @@ export const PagesManager: React.FC<{
},
},
{
text: "Convert to " + (isPost ? "Page" : "Post"),
text:
"Convert to " +
(isCrossbell
? `${APP_NAME} ${isPost ? "Post" : "Page"}`
: isPost
? "Page"
: "Post"),
icon: <span className="i-tabler:transform inline-block"></span>,
onClick() {
if (!page.metadata) {
const toastId = toast.loading("Converting...")
const data = getStorage(`draft-${subdomain}-${page.id}`)
data.isPost = !isPost
setStorage(`draft-${subdomain}-${page.id}`, data)
queryClient.invalidateQueries(["getPagesBySite", subdomain])
queryClient.invalidateQueries(["getPage", page.id])
toast.success("Converted!", {
id: toastId,
})
} else {
setConvertToastId(toast.loading("Converting..."))
const toastId = toast.loading("Converting...")
if (isCrossbell) {
setConvertToastId(toastId)
createOrUpdatePage.mutate({
published: true,
pageId: page.id,
@ -155,8 +162,32 @@ export const PagesManager: React.FC<{
tags: page.tags
?.filter((tag) => tag !== "post" && tag !== "page")
?.join(", "),
isPost: !isPost,
isPost: isPost,
applications: page.applications,
})
} else {
if (!page.metadata) {
const data = getStorage(`draft-${subdomain}-${page.id}`)
data.isPost = !isPost
setStorage(`draft-${subdomain}-${page.id}`, data)
queryClient.invalidateQueries(["getPagesBySite", subdomain])
queryClient.invalidateQueries(["getPage", page.id])
toast.success("Converted!", {
id: toastId,
})
} else {
setConvertToastId(toastId)
createOrUpdatePage.mutate({
published: true,
pageId: page.id,
siteId: subdomain,
tags: page.tags
?.filter((tag) => tag !== "post" && tag !== "page")
?.join(", "),
isPost: !isPost,
applications: page.applications,
})
}
}
},
},
@ -199,6 +230,55 @@ export const PagesManager: React.FC<{
]
}
const importFile = () => {
const input = document.createElement("input")
input.type = "file"
input.accept = ".md"
input.addEventListener("change", async (e: any) => {
const file = e.target?.files?.[0]
const reader = new FileReader()
reader.readAsText(file, "UTF-8")
reader.onload = (evt) => {
if (evt.target?.result) {
const pageContent = renderPageContent(evt.target.result as string)
const id = nanoid()
const key = `draft-${subdomain}-local-${id}`
const tags =
pageContent.frontMatter.tags || pageContent.frontMatter.categories
setStorage(key, {
date: +new Date(),
values: {
content: evt.target.result,
published: false,
publishedAt: (
pageContent.frontMatter.date ||
file.lastModifiedDate ||
new Date()
).toISOString(),
slug:
pageContent.frontMatter.permalink ||
file.name.split(".").slice(0, -1).join("."),
tags: tags?.join?.(", ") || tags,
title: pageContent.frontMatter.title,
},
isPost: isPost,
})
queryClient.invalidateQueries(["getPagesBySite", subdomain])
router.push(
`/dashboard/${subdomain}/editor?id=local-${id}&type=${
isPost ? "post" : "page"
}`,
)
}
}
reader.onerror = (evt) => {
toast.error("Error reading file")
}
})
input.click()
}
const title = isPost ? "Posts" : "Pages"
const description = isPost ? (
<>
@ -276,60 +356,7 @@ export const PagesManager: React.FC<{
>
<Button
className={clsx(`space-x-2 inline-flex`)}
onClick={() => {
const input = document.createElement("input")
input.type = "file"
input.accept = ".md"
input.addEventListener("change", async (e: any) => {
const file = e.target?.files?.[0]
const reader = new FileReader()
reader.readAsText(file, "UTF-8")
reader.onload = (evt) => {
if (evt.target?.result) {
const pageContent = renderPageContent(
evt.target.result as string,
)
const id = nanoid()
const key = `draft-${subdomain}-local-${id}`
const tags =
pageContent.frontMatter.tags ||
pageContent.frontMatter.categories
setStorage(key, {
date: +new Date(),
values: {
content: evt.target.result,
published: false,
publishedAt: (
pageContent.frontMatter.date ||
file.lastModifiedDate ||
new Date()
).toISOString(),
slug:
pageContent.frontMatter.permalink ||
file.name.split(".").slice(0, -1).join("."),
tags: tags?.join?.(", ") || tags,
title: pageContent.frontMatter.title,
},
isPost: isPost,
})
queryClient.invalidateQueries([
"getPagesBySite",
subdomain,
])
router.push(
`/dashboard/${subdomain}/editor?id=local-${id}&type=${
isPost ? "post" : "page"
}`,
)
}
}
reader.onerror = (evt) => {
toast.error("Error reading file")
}
})
input.click()
}}
onClick={importFile}
>
<span className="i-bxs:duplicate inline-block"></span>
<span>Import</span>
@ -352,10 +379,16 @@ export const PagesManager: React.FC<{
return (
<Link key={page.id} href={getPageEditLink(page)}>
<a className="group relative hover:bg-zinc-100 rounded-lg py-3 px-3 transition-colors -mx-3 flex justify-between">
<div>
<div className="flex items-center">
<span>{page.title || "Untitled"}</span>
</div>
<div className="min-w-0">
{page.title ? (
<div className="flex items-center">
<span>{page.title}</span>
</div>
) : (
<div className="text-zinc-500 text-xs mt-1 truncate">
<span>{page.summary?.content}</span>
</div>
)}
<div className="text-zinc-400 text-xs mt-1">
<span className="capitalize">
{getPageVisibility(page).toLowerCase()}

View File

@ -25,6 +25,7 @@ export enum PageVisibilityEnum {
Published = "published",
Scheduled = "scheduled",
Draft = "draft",
Crossbell = "crossbell",
}
export type PostOnSiteHome = {

View File

@ -31,6 +31,7 @@ export async function createOrUpdatePage(input: {
/** Only needed when creating page */
isPost?: boolean
externalUrl?: string
applications?: string[]
}) {
if (!input.published) {
return await unidata.notes.set(
@ -78,7 +79,10 @@ export async function createOrUpdatePage(input: {
.map((tag) => tag.trim())
.filter((tag) => tag) || []),
],
applications: ["xlog"],
applications: [
"xlog",
...(input.applications?.filter((app) => app !== "xlog") || []),
],
...(input.slug && {
attributes: [
{
@ -176,6 +180,7 @@ export async function getPagesBySite(input: {
}
const visibility = input.visibility || PageVisibilityEnum.All
const crossbell = visibility === PageVisibilityEnum.Crossbell
const options = {
source: "Crossbell Note",
@ -183,8 +188,8 @@ export async function getPagesBySite(input: {
platform: "Crossbell",
limit: input.take || 1000,
filter: {
tags: [...(input.tags || []), input.type],
applications: ["xlog"],
tags: [...(input.tags || []), ...(crossbell ? [] : [input.type])],
applications: [...(crossbell ? [] : ["xlog"])],
},
cursor: "",
}
@ -206,12 +211,14 @@ export async function getPagesBySite(input: {
cursor = res.cursor
} while (cursor)
const local = getLocalPages({
site: input.site,
isPost: input.type === "post",
})
pages.list = pages.list.concat(local)
pages.total += local.length
if (!crossbell) {
const local = getLocalPages({
site: input.site,
isPost: input.type === "post",
})
pages.list = pages.list.concat(local)
pages.total += local.length
}
if (pages?.list) {
switch (visibility) {
@ -229,6 +236,11 @@ export async function getPagesBySite(input: {
(page) => +new Date(page.date_published) > +new Date(),
)
break
case PageVisibilityEnum.Crossbell:
pages.list = pages.list.filter(
(page) => !page.applications?.includes("xlog"),
)
break
}
pages.list = pages.list
.filter(

View File

@ -108,6 +108,7 @@ export default function SubdomainEditor() {
`${getSiteLink({ subdomain, domain: site.data?.custom_domain })}/${
values.slug
}`,
applications: page.data?.applications,
})
}