mirror of
https://github.com/penxio/penx.git
synced 2026-04-19 03:03:06 -04:00
fix: fix publish post
This commit is contained in:
@@ -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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -75,7 +75,7 @@ export const editorPlugins = [
|
||||
|
||||
// Functionality
|
||||
autoformatPlugin,
|
||||
// ...blockMenuPlugins,
|
||||
...blockMenuPlugins,
|
||||
...dndPlugins,
|
||||
EmojiPlugin,
|
||||
exitBreakPlugin,
|
||||
|
||||
@@ -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()],
|
||||
})
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -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
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user