feat: support mark any crossbell notes as xlog notes
This commit is contained in:
parent
b02a4cd553
commit
306edcd9aa
|
|
@ -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()}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export enum PageVisibilityEnum {
|
|||
Published = "published",
|
||||
Scheduled = "scheduled",
|
||||
Draft = "draft",
|
||||
Crossbell = "crossbell",
|
||||
}
|
||||
|
||||
export type PostOnSiteHome = {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ export default function SubdomainEditor() {
|
|||
`${getSiteLink({ subdomain, domain: site.data?.custom_domain })}/${
|
||||
values.slug
|
||||
}`,
|
||||
applications: page.data?.applications,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue