fix: fix publish post

This commit is contained in:
0xzio
2024-12-07 10:39:15 +08:00
parent 5b31519cee
commit 2f5fbde7b2
6 changed files with 99 additions and 66 deletions

View File

@@ -1,12 +0,0 @@
import LoadingDots from '@/components/icons/loading-dots'
export default function Loading() {
return (
<>
<div className="h-10 w-48 animate-pulse rounded-md bg-stone-100 dark:bg-stone-800" />
<div className="flex h-full w-full items-center justify-center">
<LoadingDots />
</div>
</>
)
}

View File

@@ -1,7 +1,8 @@
'use client'
import { Dispatch, SetStateAction, useState } from 'react'
import { Post, updatePostPublishStatus, usePost } from '@/hooks/usePost'
import { usePost } from '@/hooks/usePost'
import { usePublishPost } from '@/hooks/usePublishPost'
import { IObjectNode, Node } from '@/lib/model'
import { useNodes } from '@/lib/node-hooks'
import { cn } from '@/lib/utils'
@@ -9,7 +10,6 @@ import { store } from '@/store'
import { GateType } from '@prisma/client'
import { PopoverClose } from '@radix-ui/react-popover'
import { useParams, usePathname } from 'next/navigation'
import { usePublishPost } from '../hooks/usePublishPost'
import LoadingDots from './icons/loading-dots'
import { useSiteContext } from './SiteContext'
import { Button } from './ui/button'
@@ -17,10 +17,13 @@ import { Label } from './ui/label'
import { Popover, PopoverContent, PopoverTrigger } from './ui/popover'
import { Switch } from './ui/switch'
interface Props {}
interface Props {
className?: string
}
export function PublishPopover({}: Props) {
export function PublishPopover({ className }: Props) {
const [isOpen, setOpen] = useState(false)
return (
<Popover
open={isOpen}
@@ -29,7 +32,12 @@ export function PublishPopover({}: Props) {
}}
>
<PopoverTrigger asChild>
<Button className="w-24" onClick={() => setOpen(true)}>
<Button
className={cn('w-24', className)}
onClick={() => {
setOpen(true)
}}
>
Publish
</Button>
</PopoverTrigger>
@@ -43,11 +51,12 @@ interface PublishPopoverContentProps {
}
function PublishPopoverContent({ setOpen }: PublishPopoverContentProps) {
const { post } = usePost()
const { spaceId } = useSiteContext()
const { nodeId } = useParams()
const { nodeId } = useParams()!
const { nodes } = useNodes()
const pathname = usePathname()
const isToday = pathname.startsWith('/~/objects/today')
const isToday = pathname?.startsWith('/~/objects/today')
const activeNode = isToday
? new Node(store.node.getTodayNode())
@@ -57,10 +66,11 @@ function PublishPopoverContent({ setOpen }: PublishPopoverContentProps) {
activeNode?.props?.gateType || GateType.FREE,
)
const [collectible, setCollectible] = useState(
activeNode?.props?.collectible || false,
post?.collectible || activeNode?.props?.collectible || false,
)
const { isLoading, publishPost } = usePublishPost()
if (!activeNode) return null
if (!activeNode && !post) return null
return (
<PopoverContent align="end" className="w-[360px] flex flex-col gap-5">
@@ -106,7 +116,7 @@ function PublishPopoverContent({ setOpen }: PublishPopoverContentProps) {
className="w-full"
onClick={async () => {
await publishPost(
activeNode.raw as IObjectNode,
activeNode ? (activeNode.raw as IObjectNode) : (null as any),
gateType,
collectible,
)

View File

@@ -75,7 +75,7 @@ export const editorPlugins = [
// Functionality
autoformatPlugin,
// ...blockMenuPlugins,
...blockMenuPlugins,
...dndPlugins,
EmojiPlugin,
exitBreakPlugin,

View File

@@ -84,7 +84,7 @@ export const useCreateEditor = (value: any = []) => {
override: {
components: withDraggables(
withPlaceholders({
[AIPlugin.key]: AILeaf,
// [AIPlugin.key]: AILeaf,
[BlockquotePlugin.key]: BlockquoteElement,
[BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }),
[CodeBlockPlugin.key]: CodeBlockElement,
@@ -128,7 +128,8 @@ export const useCreateEditor = (value: any = []) => {
}),
),
},
plugins: [...copilotPlugins, ...editorPlugins],
// plugins: [...copilotPlugins, ...editorPlugins],
plugins: [...editorPlugins],
value: Array.isArray(value) ? value : [getEmptyElement()],
})

View File

@@ -1,7 +1,6 @@
import { useState } from 'react'
import { useCheckChain } from '@/hooks/useCheckChain'
import { Post } from '@/hooks/usePost'
import { usePosts } from '@/hooks/usePosts'
import { Post, usePost } from '@/hooks/usePost'
import { useWagmiConfig } from '@/hooks/useWagmiConfig'
import { creationFactoryAbi } from '@/lib/abi'
import { addressMap } from '@/lib/address'
@@ -20,12 +19,33 @@ import { useAccount, useWriteContract } from 'wagmi'
import { useSiteContext } from '../components/SiteContext'
export function usePublishPost() {
const { spaceId } = useSiteContext()
const { spaceId, id } = useSiteContext()
const { address } = useAccount()
const [isLoading, setLoading] = useState(false)
const checkChain = useCheckChain()
const { writeContractAsync } = useWriteContract()
const wagmiConfig = useWagmiConfig()
const { post: currentPost } = usePost()
function getContent(node: IObjectNode) {
if (currentPost) return currentPost.content
const nodes = store.node.getNodes()
const content = nodeToSlate({
node: node,
nodes,
isOutliner: false,
isOutlinerSpace: false,
})
return JSON.stringify(content)
}
function getImage(node: IObjectNode) {
if (!node) return ''
return node.props.objectType === ObjectType.IMAGE
? node.props?.imageUrl
: node.props.coverUrl
}
return {
isLoading,
@@ -36,17 +56,11 @@ export function usePublishPost() {
) => {
setLoading(true)
const nodes = store.node.getNodes()
const content = nodeToSlate({
node: node,
nodes,
isOutliner: false,
isOutlinerSpace: false,
})
const content = getContent(node)
// console.log('======>>>>>content:', content)
// console.log('======>>>>>node:', node)
const post = await api.post.bySlug.query(node.id)
const post = currentPost || (await api.post.bySlug.query(node.id))
let creationId: number | undefined
try {
@@ -56,7 +70,11 @@ export function usePublishPost() {
address: addressMap.CreationFactory,
abi: creationFactoryAbi,
functionName: 'create',
args: [node.id, precision.token(0.0001024), spaceId as Address],
args: [
post?.slug || node?.id,
precision.token(0.0001024),
spaceId as Address,
],
})
await waitForTransactionReceipt(wagmiConfig, { hash })
@@ -71,25 +89,25 @@ export function usePublishPost() {
}
await api.post.publish.mutate({
type: node.props?.objectType || PostType.ARTICLE,
nodeId: node.id,
type: post?.type || node.props?.objectType || PostType.ARTICLE,
postId: post?.id,
nodeId: node?.id,
gateType,
collectible,
creationId,
image:
node.props.objectType === ObjectType.IMAGE
? node.props?.imageUrl
: node.props.coverUrl,
content: JSON.stringify(content),
image: getImage(node),
content: content,
})
await store.node.updateNode(node.id, {
props: {
...node.props,
gateType,
collectible,
},
} as IObjectNode)
if (node) {
await store.node.updateNode(node.id, {
props: {
...node.props,
gateType,
collectible,
},
} as IObjectNode)
}
setLoading(false)
revalidateMetadata(`posts`)

View File

@@ -109,7 +109,8 @@ export const postRouter = router({
publish: protectedProcedure
.input(
z.object({
nodeId: z.string(),
postId: z.string().optional(),
nodeId: z.string().optional(),
creationId: z.number().optional(),
type: z.nativeEnum(PostType),
gateType: z.nativeEnum(GateType),
@@ -123,36 +124,49 @@ export const postRouter = router({
const { nodeId, gateType, collectible, creationId } = input
let post = await prisma.post.findFirst({
where: { nodeId },
where: { OR: [{ nodeId }, { id: input.postId }] },
})
const [title, ...nodes] = JSON.parse(input.content)
function getPostInfo() {
if (input.postId) {
return { title: post?.title, content: input.content }
}
const [title, ...nodes] = JSON.parse(input.content)
return {
title: SlateNode.string(title),
content: JSON.stringify(nodes),
}
}
const info = getPostInfo()
if (!post) {
post = await prisma.post.create({
data: {
userId,
slug: input.nodeId,
title: SlateNode.string(title),
title: info.title,
type: input.type,
nodeId: input.nodeId,
postStatus: PostStatus.PUBLISHED,
image: input.image,
gateType: input.gateType,
collectible: input.collectible,
content: JSON.stringify(nodes),
content: info.content,
},
})
} else {
post = await prisma.post.update({
where: { id: post.id },
data: {
title: SlateNode.string(title),
title: info.title,
type: input.type,
image: input.image,
postStatus: PostStatus.PUBLISHED,
gateType: input.gateType,
collectible: input.collectible,
content: JSON.stringify(nodes),
content: info.content,
},
})
}
@@ -192,14 +206,16 @@ export const postRouter = router({
revalidatePath('/(blog)/posts/page/[page]', 'page')
// sync google
syncToGoogleDrive(ctx.token.uid, {
...newPost,
postStatus: PostStatus.PUBLISHED,
collectible,
creationId,
cid: res.cid,
gateType,
} as any)
// syncToGoogleDrive(ctx.token.uid, {
// ...newPost,
// postStatus: PostStatus.PUBLISHED,
// collectible,
// creationId,
// cid: res.cid,
// gateType,
// } as any)
return newPost
return newPost
}),