feat: use crossbell kit to create and update page
This commit is contained in:
parent
b23fe136cd
commit
98893e661d
|
|
@ -57,9 +57,11 @@ import { cn, pick } from "~/lib/utils"
|
|||
import { Rendered, renderPageContent } from "~/markdown"
|
||||
import { checkPageSlug } from "~/models/page.model"
|
||||
import {
|
||||
useCreateOrUpdatePage,
|
||||
useCreatePage,
|
||||
useDeletePage,
|
||||
useGetDistinctNoteTagsOfCharacter,
|
||||
useGetPage,
|
||||
useUpdatePage,
|
||||
} from "~/queries/page"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
|
||||
|
|
@ -186,12 +188,13 @@ export default function SubdomainEditor() {
|
|||
[isPost, queryClient, subdomain, visibility],
|
||||
)
|
||||
|
||||
const createOrUpdatePage = useCreateOrUpdatePage()
|
||||
const createPage = useCreatePage()
|
||||
const updatePage = useUpdatePage()
|
||||
|
||||
const isMobileLayout = useIsMobileLayout()
|
||||
const [isRendering, setIsRendering] = useState(!isMobileLayout)
|
||||
|
||||
const savePage = async (published: boolean) => {
|
||||
const savePage = async () => {
|
||||
const check = await checkPageSlug({
|
||||
slug: values.slug || defaultSlug,
|
||||
characterId: site.data?.characterId,
|
||||
|
|
@ -201,58 +204,87 @@ export default function SubdomainEditor() {
|
|||
toast.error(check)
|
||||
} else {
|
||||
const uniqueTags = Array.from(new Set(values.tags.split(","))).join(",")
|
||||
createOrUpdatePage.mutate({
|
||||
|
||||
const baseValues = {
|
||||
...values,
|
||||
tags: uniqueTags,
|
||||
slug: values.slug || defaultSlug,
|
||||
siteId: subdomain,
|
||||
...(visibility === PageVisibilityEnum.Draft
|
||||
? {}
|
||||
: { pageId: `${page?.data?.characterId}-${page?.data?.noteId}` }),
|
||||
isPost: isPost,
|
||||
published,
|
||||
applications: page.data?.metadata?.content?.sources,
|
||||
characterId: site.data?.characterId,
|
||||
cover: values.cover,
|
||||
disableAISummary: values.disableAISummary,
|
||||
})
|
||||
}
|
||||
if (visibility === PageVisibilityEnum.Draft) {
|
||||
createPage.mutate({
|
||||
...baseValues,
|
||||
isPost: isPost,
|
||||
})
|
||||
} else {
|
||||
updatePage.mutate({
|
||||
...baseValues,
|
||||
noteId: page?.data?.noteId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const deleteP = useDeletePage()
|
||||
const deletePage = async () => {
|
||||
if (page.data) {
|
||||
if (!page.data?.noteId) {
|
||||
// Is draft
|
||||
delStorage(`draft-${page.data.characterId}-${page.data.draftKey}`)
|
||||
} else {
|
||||
// Is Note
|
||||
return deleteP.mutateAsync({
|
||||
site: subdomain,
|
||||
id: `${page.data.characterId}-${page.data.noteId}`,
|
||||
characterId: page.data.characterId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [isCheersOpen, setIsCheersOpen] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (createOrUpdatePage.isSuccess) {
|
||||
if (createOrUpdatePage.data?.code === 0) {
|
||||
if (draftKey) {
|
||||
delStorage(draftKey)
|
||||
queryClient.invalidateQueries([
|
||||
"getPagesBySite",
|
||||
site.data?.characterId,
|
||||
])
|
||||
queryClient.invalidateQueries([
|
||||
"getPage",
|
||||
draftKey.replace(`draft-${site.data?.characterId}-`, ""),
|
||||
])
|
||||
} else {
|
||||
queryClient.invalidateQueries(["getPage", pageId])
|
||||
}
|
||||
|
||||
if (createOrUpdatePage.data.data) {
|
||||
router.replace(
|
||||
`/dashboard/${subdomain}/editor?id=${site.data?.characterId}-${
|
||||
createOrUpdatePage.data.data
|
||||
}&type=${searchParams?.get("type")}`,
|
||||
)
|
||||
}
|
||||
|
||||
setIsCheersOpen(true)
|
||||
showConfetti()
|
||||
if (createPage.isSuccess || updatePage.isSuccess) {
|
||||
if (draftKey) {
|
||||
delStorage(draftKey)
|
||||
queryClient.invalidateQueries([
|
||||
"getPagesBySite",
|
||||
site.data?.characterId,
|
||||
])
|
||||
queryClient.invalidateQueries([
|
||||
"getPage",
|
||||
draftKey.replace(`draft-${site.data?.characterId}-`, ""),
|
||||
])
|
||||
} else {
|
||||
toast.error("Error: " + createOrUpdatePage.data?.message)
|
||||
queryClient.invalidateQueries(["getPage", pageId])
|
||||
}
|
||||
|
||||
if (createPage.data?.noteId) {
|
||||
router.replace(
|
||||
`/dashboard/${subdomain}/editor?id=${
|
||||
createPage.data?.noteId
|
||||
}&type=${searchParams?.get("type")}`,
|
||||
)
|
||||
}
|
||||
|
||||
setIsCheersOpen(true)
|
||||
showConfetti()
|
||||
|
||||
createPage.reset()
|
||||
updatePage.reset()
|
||||
}
|
||||
}, [createOrUpdatePage.isSuccess])
|
||||
}, [createPage.isSuccess, updatePage.isSuccess])
|
||||
|
||||
useEffect(() => {
|
||||
if (createPage.isError || updatePage.isError) {
|
||||
toast.error("Error: " + (createPage.error || updatePage.error))
|
||||
createPage.reset()
|
||||
updatePage.reset()
|
||||
}
|
||||
}, [createPage.isError, updatePage.isSuccess])
|
||||
|
||||
useEffect(() => {
|
||||
if (!page.data || !draftKey) return
|
||||
|
|
@ -500,6 +532,7 @@ export default function SubdomainEditor() {
|
|||
<OptionsButton
|
||||
visibility={visibility}
|
||||
savePage={savePage}
|
||||
deletePage={deletePage}
|
||||
published={visibility !== PageVisibilityEnum.Draft}
|
||||
isRendering={isRendering}
|
||||
renderPage={setIsRendering}
|
||||
|
|
@ -539,7 +572,7 @@ export default function SubdomainEditor() {
|
|||
: ""
|
||||
}
|
||||
published={visibility !== PageVisibilityEnum.Draft}
|
||||
isSaving={createOrUpdatePage.isLoading}
|
||||
isSaving={createPage.isLoading || updatePage.isLoading}
|
||||
isDisabled={
|
||||
visibility !== PageVisibilityEnum.Modified &&
|
||||
visibility !== PageVisibilityEnum.Draft
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ export const OptionsButton = ({
|
|||
visibility,
|
||||
previewPage,
|
||||
savePage,
|
||||
deletePage,
|
||||
isRendering,
|
||||
renderPage,
|
||||
published,
|
||||
|
|
@ -23,7 +24,8 @@ export const OptionsButton = ({
|
|||
visibility: PageVisibilityEnum | undefined
|
||||
previewPage: () => void
|
||||
renderPage: Dispatch<SetStateAction<boolean>>
|
||||
savePage: (published: boolean) => any
|
||||
savePage: () => any
|
||||
deletePage: () => any
|
||||
propertiesWidget: React.ReactNode
|
||||
isRendering: boolean
|
||||
published: boolean
|
||||
|
|
@ -109,7 +111,7 @@ export const OptionsButton = ({
|
|||
className={`${
|
||||
active ? "bg-accent text-white" : "text-gray-900"
|
||||
} group flex w-full items-center rounded-md px-2 py-2 text-sm`}
|
||||
onClick={() => savePage(true)}
|
||||
onClick={() => savePage()}
|
||||
>
|
||||
{t(published ? "Update" : "Publish")}
|
||||
</button>
|
||||
|
|
@ -152,7 +154,7 @@ export const OptionsButton = ({
|
|||
open={deleteConfirmModalOpen}
|
||||
setOpen={setDeleteConfirmModalOpen}
|
||||
onConfirm={() => {
|
||||
savePage(false)
|
||||
deletePage()
|
||||
}}
|
||||
isPost={isPost}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -222,7 +222,6 @@ export const PagesManager = ({ isPost }: { isPost: boolean }) => {
|
|||
{batchSelected.length > 0 ? (
|
||||
<PagesManagerBatchSelectActionTab
|
||||
isPost={isPost}
|
||||
isNotxLogContent={false}
|
||||
pages={pages.data}
|
||||
batchSelected={batchSelected}
|
||||
setBatchSelected={setBatchSelected}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,10 @@ import type { InfiniteData } from "@tanstack/react-query"
|
|||
import { useQueryClient } from "@tanstack/react-query"
|
||||
|
||||
import { type TabItem, Tabs } from "~/components/ui/Tabs"
|
||||
import { APP_NAME } from "~/lib/env"
|
||||
import { useTranslation } from "~/lib/i18n/client"
|
||||
import { delStorage, getStorage, setStorage } from "~/lib/storage"
|
||||
import { ExpandedNote } from "~/lib/types"
|
||||
import { useCreateOrUpdatePage, useDeletePage } from "~/queries/page"
|
||||
import { useDeletePage, useUpdatePage } from "~/queries/page"
|
||||
|
||||
import { DeleteConfirmationModal } from "./DeleteConfirmationModal"
|
||||
|
||||
|
|
@ -20,13 +19,11 @@ function getPageId(page: ExpandedNote) {
|
|||
|
||||
export const PagesManagerBatchSelectActionTab = ({
|
||||
isPost,
|
||||
isNotxLogContent,
|
||||
pages,
|
||||
batchSelected,
|
||||
setBatchSelected,
|
||||
}: {
|
||||
isPost: boolean
|
||||
isNotxLogContent: boolean
|
||||
pages?: InfiniteData<{
|
||||
list: ExpandedNote[]
|
||||
}>
|
||||
|
|
@ -41,7 +38,7 @@ export const PagesManagerBatchSelectActionTab = ({
|
|||
const queryClient = useQueryClient()
|
||||
|
||||
// Convert or Delete page
|
||||
const createOrUpdatePage = useCreateOrUpdatePage()
|
||||
const updatePage = useUpdatePage()
|
||||
const deletePage = useDeletePage()
|
||||
|
||||
const tabItems: TabItem[] = [
|
||||
|
|
@ -65,13 +62,7 @@ export const PagesManagerBatchSelectActionTab = ({
|
|||
},
|
||||
},
|
||||
{
|
||||
text:
|
||||
"Convert to " +
|
||||
(isNotxLogContent
|
||||
? `${APP_NAME} ${isPost ? "Post" : "Page"}`
|
||||
: isPost
|
||||
? "Page"
|
||||
: "Post"),
|
||||
text: "Convert to " + (isPost ? "Page" : "Post"),
|
||||
onClick: async () => {
|
||||
// Start message
|
||||
const toastId = toast.loading("Converting...")
|
||||
|
|
@ -90,48 +81,22 @@ export const PagesManagerBatchSelectActionTab = ({
|
|||
try {
|
||||
await Promise.all(
|
||||
selectedPages.map((page) => {
|
||||
// Check again to ensure it's not
|
||||
const isNotxLogContent =
|
||||
!page.metadata?.content?.sources?.includes("xlog")
|
||||
|
||||
const targetNoteBase = {
|
||||
published: true,
|
||||
pageId: `${page.characterId}-${page.noteId}`,
|
||||
siteId: subdomain,
|
||||
tags: page.metadata?.content?.tags
|
||||
?.filter((tag) => tag !== "post" && tag !== "page")
|
||||
?.join(", "),
|
||||
applications: page.metadata?.content?.sources,
|
||||
}
|
||||
|
||||
if (isNotxLogContent) {
|
||||
return createOrUpdatePage.mutateAsync({
|
||||
...targetNoteBase,
|
||||
isPost: isPost, // Convert to xLog content
|
||||
characterId: page.characterId,
|
||||
})
|
||||
if (!page.noteId) {
|
||||
// Is draft
|
||||
const key = `draft-${page?.characterId}-${page.draftKey}`
|
||||
const data = getStorage(key)
|
||||
data.isPost = !isPost
|
||||
setStorage(key, data)
|
||||
} else {
|
||||
if (!page.noteId) {
|
||||
// Is draft
|
||||
const key = `draft-${page?.characterId}-${page.draftKey}`
|
||||
const data = getStorage(key)
|
||||
data.isPost = !isPost
|
||||
setStorage(key, data)
|
||||
} else {
|
||||
// IsNote
|
||||
return createOrUpdatePage.mutateAsync({
|
||||
...targetNoteBase,
|
||||
isPost: !isPost, // Change type
|
||||
characterId: page.characterId,
|
||||
})
|
||||
}
|
||||
// IsNote
|
||||
return updatePage.mutate({
|
||||
characterId: page.characterId,
|
||||
noteId: page.noteId,
|
||||
isPost: !isPost, // Change type
|
||||
})
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
toast.success(t("Converted!"), {
|
||||
id: toastId,
|
||||
})
|
||||
} catch (e) {
|
||||
// Some failed
|
||||
toast.error(t("Failed to convert."), {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ import { Menu } from "@headlessui/react"
|
|||
import { useQueryClient } from "@tanstack/react-query"
|
||||
|
||||
import { useGetState } from "~/hooks/useGetState"
|
||||
import { APP_NAME } from "~/lib/env"
|
||||
import { getNoteSlugFromNote, getTwitterShareUrl } from "~/lib/helpers"
|
||||
import { useTranslation } from "~/lib/i18n/client"
|
||||
import { delStorage, getStorage, setStorage } from "~/lib/storage"
|
||||
import { ExpandedNote } from "~/lib/types"
|
||||
import { useCreateOrUpdatePage, useDeletePage } from "~/queries/page"
|
||||
import { useDeletePage, useUpdatePage } from "~/queries/page"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
|
||||
import { DeleteConfirmationModal } from "./DeleteConfirmationModal"
|
||||
|
|
@ -41,11 +40,10 @@ export const PagesManagerMenu = ({
|
|||
}) => {
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
const isCrossbell = !page.metadata?.content?.sources?.includes("xlog")
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const subdomain = params?.subdomain as string
|
||||
const createOrUpdatePage = useCreateOrUpdatePage()
|
||||
const updatePage = useUpdatePage()
|
||||
|
||||
const editLink = usePageEditLink(page, isPost)
|
||||
const queryClient = useQueryClient()
|
||||
|
|
@ -76,17 +74,19 @@ export const PagesManagerMenu = ({
|
|||
}, [deletePage.isError])
|
||||
|
||||
useEffect(() => {
|
||||
if (createOrUpdatePage.isSuccess) {
|
||||
if (updatePage.isSuccess) {
|
||||
toast.success(t("Converted!"), {
|
||||
id: getCurrentToastId(),
|
||||
})
|
||||
} else if (createOrUpdatePage.isError) {
|
||||
updatePage.reset()
|
||||
} else if (updatePage.isError) {
|
||||
toast.error(t("Failed to convert."), {
|
||||
id: getCurrentToastId(),
|
||||
})
|
||||
updatePage.reset()
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [createOrUpdatePage.isSuccess, createOrUpdatePage.isError])
|
||||
}, [updatePage.isSuccess, updatePage.isError])
|
||||
|
||||
const site = useGetSite(subdomain)
|
||||
|
||||
|
|
@ -99,60 +99,34 @@ export const PagesManagerMenu = ({
|
|||
},
|
||||
},
|
||||
{
|
||||
text:
|
||||
"Convert to " +
|
||||
(isCrossbell
|
||||
? `${APP_NAME} ${isPost ? "Post" : "Page"}`
|
||||
: isPost
|
||||
? "Page"
|
||||
: "Post"),
|
||||
text: "Convert to " + (isPost ? "Page" : "Post"),
|
||||
icon: (
|
||||
<span className="icon-[mingcute--transfer-3-line] inline-block"></span>
|
||||
),
|
||||
onClick() {
|
||||
const toastId = toast.loading("Converting...")
|
||||
if (isCrossbell) {
|
||||
setConvertToastId(toastId)
|
||||
createOrUpdatePage.mutate({
|
||||
published: true,
|
||||
pageId: `${page.characterId}-${page.noteId}`,
|
||||
siteId: subdomain,
|
||||
tags: page.metadata?.content?.tags
|
||||
?.filter((tag) => tag !== "post" && tag !== "page")
|
||||
?.join(", "),
|
||||
isPost: isPost,
|
||||
applications: page.metadata?.content?.sources,
|
||||
characterId: page.characterId,
|
||||
|
||||
if (!page.noteId) {
|
||||
const data = getStorage(
|
||||
`draft-${site.data?.characterId}-${page.draftKey}`,
|
||||
)
|
||||
data.isPost = !isPost
|
||||
setStorage(`draft-${site.data?.characterId}-${page.draftKey}`, data)
|
||||
queryClient.invalidateQueries([
|
||||
"getPagesBySite",
|
||||
site.data?.characterId,
|
||||
])
|
||||
queryClient.invalidateQueries(["getPage", page.characterId])
|
||||
toast.success("Converted!", {
|
||||
id: toastId,
|
||||
})
|
||||
} else {
|
||||
if (!page.noteId) {
|
||||
const data = getStorage(
|
||||
`draft-${site.data?.characterId}-${page.draftKey}`,
|
||||
)
|
||||
data.isPost = !isPost
|
||||
setStorage(`draft-${site.data?.characterId}-${page.draftKey}`, data)
|
||||
queryClient.invalidateQueries([
|
||||
"getPagesBySite",
|
||||
site.data?.characterId,
|
||||
])
|
||||
queryClient.invalidateQueries(["getPage", page.characterId])
|
||||
toast.success("Converted!", {
|
||||
id: toastId,
|
||||
})
|
||||
} else {
|
||||
setConvertToastId(toastId)
|
||||
createOrUpdatePage.mutate({
|
||||
published: true,
|
||||
pageId: `${page.characterId}-${page.noteId}`,
|
||||
siteId: subdomain,
|
||||
tags: page.metadata?.content?.tags
|
||||
?.filter((tag) => tag !== "post" && tag !== "page")
|
||||
?.join(", "),
|
||||
isPost: !isPost,
|
||||
applications: page.metadata?.content?.sources,
|
||||
characterId: page.characterId,
|
||||
})
|
||||
}
|
||||
setConvertToastId(toastId)
|
||||
updatePage.mutate({
|
||||
isPost: !isPost,
|
||||
characterId: page.characterId,
|
||||
noteId: page.noteId,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -43,115 +43,6 @@ export async function checkPageSlug(input: {
|
|||
}
|
||||
}
|
||||
|
||||
export async function createOrUpdatePage(
|
||||
input: {
|
||||
pageId?: string
|
||||
siteId: string
|
||||
slug?: string
|
||||
tags?: string
|
||||
title?: string
|
||||
content?: string
|
||||
published?: boolean
|
||||
publishedAt?: string
|
||||
excerpt?: string
|
||||
/** Only needed when creating page */
|
||||
isPost?: boolean
|
||||
applications?: string[]
|
||||
cover?: {
|
||||
address?: string
|
||||
mime_type?: string
|
||||
}
|
||||
disableAISummary?: boolean
|
||||
},
|
||||
customUnidata?: Unidata,
|
||||
newbieToken?: string,
|
||||
) {
|
||||
const { default: unidata } = await import("~/queries/unidata.server")
|
||||
|
||||
if (!input.published) {
|
||||
return await (customUnidata || unidata).notes.set(
|
||||
{
|
||||
source: "Crossbell Note",
|
||||
identity: input.siteId,
|
||||
platform: "Crossbell",
|
||||
action: "remove",
|
||||
},
|
||||
{
|
||||
id: input.pageId,
|
||||
},
|
||||
{
|
||||
newbieToken,
|
||||
},
|
||||
)
|
||||
}
|
||||
return await (customUnidata || unidata).notes.set(
|
||||
{
|
||||
source: "Crossbell Note",
|
||||
identity: input.siteId,
|
||||
platform: "Crossbell",
|
||||
action: input.pageId ? "update" : "add",
|
||||
},
|
||||
{
|
||||
...(input.pageId && { id: input.pageId }),
|
||||
...(input.title && { title: input.title }),
|
||||
...(input.content && {
|
||||
body: {
|
||||
content: input.content,
|
||||
mime_type: "text/markdown",
|
||||
},
|
||||
}),
|
||||
date_published: input.publishedAt || new Date().toISOString(),
|
||||
...(input.excerpt && {
|
||||
summary: {
|
||||
content: input.excerpt,
|
||||
mime_type: "text/markdown",
|
||||
},
|
||||
}),
|
||||
tags: [
|
||||
input.isPost ? "post" : "page",
|
||||
...(input.tags
|
||||
?.split(",")
|
||||
.map((tag) => tag.trim())
|
||||
.filter((tag) => tag) || []),
|
||||
],
|
||||
applications: [
|
||||
"xlog",
|
||||
...(input.applications?.filter((app) => app !== "xlog") || []),
|
||||
],
|
||||
attributes: [
|
||||
...(input.slug
|
||||
? [
|
||||
{
|
||||
trait_type: "xlog_slug",
|
||||
value: input.slug,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(input.disableAISummary
|
||||
? [
|
||||
{
|
||||
trait_type: "xlog_disable_ai_summary",
|
||||
value: input.disableAISummary,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
attachments: input.cover?.address
|
||||
? [
|
||||
{
|
||||
name: "cover",
|
||||
address: input.cover.address,
|
||||
mime_type: input.cover.mime_type,
|
||||
},
|
||||
]
|
||||
: [],
|
||||
},
|
||||
{
|
||||
newbieToken,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export async function postNotes(
|
||||
input: {
|
||||
siteId: string
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
"use client"
|
||||
|
||||
import { NoteMetadata } from "crossbell"
|
||||
import { nanoid } from "nanoid"
|
||||
|
||||
import {
|
||||
useAccountState,
|
||||
useIsNoteLiked,
|
||||
useMintNote,
|
||||
useNoteLikeCount,
|
||||
useNoteLikeList,
|
||||
usePostNote,
|
||||
usePostNoteForNote,
|
||||
useToggleLikeNote,
|
||||
useUpdateNote,
|
||||
} from "@crossbell/connect-kit"
|
||||
import { useContract } from "@crossbell/contract"
|
||||
import { useRefCallback } from "@crossbell/util-hooks"
|
||||
|
|
@ -202,26 +207,211 @@ export const useCheckComment = ({
|
|||
)
|
||||
}
|
||||
|
||||
export function useCreateOrUpdatePage() {
|
||||
const newbieToken = useAccountState((s) => s.email?.token)
|
||||
const unidata = useUnidata()
|
||||
export function useCreatePage() {
|
||||
const queryClient = useQueryClient()
|
||||
const mutation = useMutation(
|
||||
async (
|
||||
payload: Parameters<typeof pageModel.createOrUpdatePage>[0] & {
|
||||
characterId?: number
|
||||
},
|
||||
) => {
|
||||
return pageModel.createOrUpdatePage(payload, unidata, newbieToken)
|
||||
},
|
||||
{
|
||||
onSuccess: (data, variables) => {
|
||||
queryClient.invalidateQueries(["getPagesBySite", variables.characterId])
|
||||
queryClient.invalidateQueries(["getPage", variables.characterId])
|
||||
},
|
||||
const { mutateAsync: _, ...postNote } = usePostNote()
|
||||
|
||||
const mutate = useRefCallback(
|
||||
(input: {
|
||||
characterId?: number
|
||||
slug?: string
|
||||
tags?: string
|
||||
title?: string
|
||||
content?: string
|
||||
publishedAt?: string
|
||||
excerpt?: string
|
||||
isPost?: boolean
|
||||
cover?: {
|
||||
address?: string
|
||||
mime_type?: string
|
||||
}
|
||||
disableAISummary?: boolean
|
||||
}) => {
|
||||
if (!input.characterId) {
|
||||
throw new Error("characterId is required")
|
||||
}
|
||||
|
||||
return postNote.mutate(
|
||||
{
|
||||
characterId: input.characterId,
|
||||
metadata: {
|
||||
title: input.title,
|
||||
content: input.content,
|
||||
date_published: input.publishedAt || new Date().toISOString(),
|
||||
summary: input.excerpt,
|
||||
tags: [
|
||||
input.isPost ? "post" : "page",
|
||||
...(input.tags
|
||||
?.split(",")
|
||||
.map((tag) => tag.trim())
|
||||
.filter((tag) => tag) || []),
|
||||
],
|
||||
sources: ["xlog"],
|
||||
attributes: [
|
||||
{
|
||||
trait_type: "xlog_slug",
|
||||
value: input.slug || nanoid(),
|
||||
},
|
||||
...(input.disableAISummary
|
||||
? [
|
||||
{
|
||||
trait_type: "xlog_disable_ai_summary",
|
||||
value: input.disableAISummary,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
attachments: [
|
||||
...(input.cover?.address
|
||||
? [
|
||||
{
|
||||
name: "cover",
|
||||
address: input.cover.address,
|
||||
mime_type: input.cover.mime_type,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
} as NoteMetadata & {
|
||||
summary?: string
|
||||
},
|
||||
},
|
||||
{
|
||||
onSuccess: (data, variables) => {
|
||||
queryClient.invalidateQueries(["getPagesBySite", input.characterId])
|
||||
queryClient.invalidateQueries(["getPage", input.characterId])
|
||||
},
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
return mutation
|
||||
|
||||
return {
|
||||
...postNote,
|
||||
mutate,
|
||||
}
|
||||
}
|
||||
|
||||
export function useUpdatePage() {
|
||||
const queryClient = useQueryClient()
|
||||
const { mutateAsync: _, ...updateNote } = useUpdateNote()
|
||||
|
||||
const mutate = useRefCallback(
|
||||
(input: {
|
||||
noteId?: number
|
||||
characterId?: number
|
||||
slug?: string
|
||||
tags?: string
|
||||
title?: string
|
||||
content?: string
|
||||
publishedAt?: string
|
||||
excerpt?: string
|
||||
isPost?: boolean
|
||||
cover?: {
|
||||
address?: string
|
||||
mime_type?: string
|
||||
}
|
||||
disableAISummary?: boolean
|
||||
}) => {
|
||||
if (!input.characterId || !input.noteId) {
|
||||
throw new Error("characterId and noteId are required")
|
||||
}
|
||||
|
||||
return updateNote.mutate(
|
||||
{
|
||||
note: {
|
||||
characterId: input.characterId,
|
||||
noteId: input.noteId,
|
||||
},
|
||||
edit(metadataDraft) {
|
||||
if (input.title !== undefined) {
|
||||
metadataDraft.title = input.title
|
||||
}
|
||||
if (input.content !== undefined) {
|
||||
metadataDraft.content = input.content
|
||||
}
|
||||
if (input.publishedAt !== undefined) {
|
||||
metadataDraft.date_published = input.publishedAt
|
||||
}
|
||||
if (input.excerpt !== undefined) {
|
||||
;(metadataDraft as any).summary = input.excerpt
|
||||
}
|
||||
|
||||
if (!metadataDraft.tags) {
|
||||
metadataDraft.tags = []
|
||||
}
|
||||
if (input.isPost !== undefined) {
|
||||
metadataDraft.tags[0] = input.isPost ? "post" : "page"
|
||||
}
|
||||
if (input.tags !== undefined) {
|
||||
metadataDraft.tags = [
|
||||
metadataDraft.tags[0],
|
||||
...input.tags
|
||||
.split(",")
|
||||
.map((tag) => tag.trim())
|
||||
.filter((tag) => tag),
|
||||
]
|
||||
}
|
||||
|
||||
if (input.slug !== undefined) {
|
||||
const slug = metadataDraft.attributes?.find(
|
||||
(attr) => attr.trait_type === "xlog_slug",
|
||||
)
|
||||
if (slug) {
|
||||
slug.value = input.slug
|
||||
} else {
|
||||
metadataDraft.attributes?.push({
|
||||
trait_type: "xlog_slug",
|
||||
value: input.slug,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (input.disableAISummary !== undefined) {
|
||||
const disableAISummary = metadataDraft.attributes?.find(
|
||||
(attr) => attr.trait_type === "xlog_disable_ai_summary",
|
||||
)
|
||||
if (disableAISummary) {
|
||||
disableAISummary.value = input.disableAISummary
|
||||
} else {
|
||||
metadataDraft.attributes?.push({
|
||||
trait_type: "xlog_disable_ai_summary",
|
||||
value: input.disableAISummary,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (input.cover?.address !== undefined) {
|
||||
const cover = metadataDraft.attachments?.find(
|
||||
(attr) => attr.name === "cover",
|
||||
)
|
||||
if (cover) {
|
||||
cover.address = input.cover.address
|
||||
cover.mime_type = input.cover.mime_type
|
||||
} else {
|
||||
metadataDraft.attachments?.push({
|
||||
name: "cover",
|
||||
address: input.cover.address,
|
||||
mime_type: input.cover.mime_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
onSuccess: (data, variables) => {
|
||||
queryClient.invalidateQueries(["getPagesBySite", input.characterId])
|
||||
queryClient.invalidateQueries(["getPage", input.characterId])
|
||||
},
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
return {
|
||||
...updateNote,
|
||||
mutate,
|
||||
}
|
||||
}
|
||||
|
||||
export function usePostNotes() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue