354 lines
10 KiB
TypeScript
354 lines
10 KiB
TypeScript
import { Note } from "~/lib/types"
|
|
import { LikeIcon } from "~/components/icons/LikeIcon"
|
|
import {
|
|
useLikePage,
|
|
useUnlikePage,
|
|
useMintPage,
|
|
useGetLikes,
|
|
useCheckLike,
|
|
useGetMints,
|
|
useCheckMint,
|
|
} from "~/queries/page"
|
|
import { useGetUserSites } from "~/queries/site"
|
|
import { useAccount } from "wagmi"
|
|
import { useConnectModal } from "@rainbow-me/rainbowkit"
|
|
import { useState, useEffect } from "react"
|
|
import { Button } from "../ui/Button"
|
|
import { useRouter } from "next/router"
|
|
import { SITE_URL, CSB_SCAN, CSB_IO } from "~/lib/env"
|
|
import { DuplicateIcon } from "@heroicons/react/solid"
|
|
import { Comment } from "~/components/common/Comment"
|
|
import { UniLink } from "~/components/ui/UniLink"
|
|
import { Modal } from "~/components/ui/Modal"
|
|
import { Avatar } from "../ui/Avatar"
|
|
import { MintIcon } from "~/components/icons/MintIcon"
|
|
import { getLikes, getMints } from "~/models/page.model"
|
|
import { CharacterList } from "~/components/common/CharacterList"
|
|
|
|
export const PostFooter: React.FC<{
|
|
page?: Note
|
|
}> = ({ page }) => {
|
|
const likePage = useLikePage()
|
|
const unlikePage = useUnlikePage()
|
|
const mintPage = useMintPage()
|
|
|
|
const { address } = useAccount()
|
|
const { openConnectModal } = useConnectModal()
|
|
const [likeProgress, setLikeProgress] = useState(false)
|
|
const [mintProgress, setMintProgress] = useState(false)
|
|
const userSite = useGetUserSites(address)
|
|
const router = useRouter()
|
|
let [isLikeOpen, setIsLikeOpen] = useState(false)
|
|
let [isMintOpen, setIsMintOpen] = useState(false)
|
|
let [isLikeListOpen, setIsLikeListOpen] = useState(false)
|
|
let [isMintListOpen, setIsMintListOpen] = useState(false)
|
|
|
|
const likes = useGetLikes({
|
|
pageId: page?.id,
|
|
})
|
|
const isLike = useCheckLike({
|
|
address,
|
|
pageId: page?.id,
|
|
})
|
|
|
|
const mints = useGetMints({
|
|
pageId: page?.id,
|
|
})
|
|
const isMint = useCheckMint({
|
|
address,
|
|
pageId: page?.id,
|
|
})
|
|
|
|
const like = async () => {
|
|
if (!address) {
|
|
setLikeProgress(true)
|
|
openConnectModal?.()
|
|
} else if (!userSite.data) {
|
|
router.push(`${SITE_URL}/dashboard/new-site`)
|
|
} else if (page?.id) {
|
|
if (isLike.data?.count) {
|
|
setIsLikeOpen(true)
|
|
} else {
|
|
likePage.mutate({
|
|
address,
|
|
pageId: page?.id,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
const mint = async () => {
|
|
if (!address) {
|
|
setMintProgress(true)
|
|
openConnectModal?.()
|
|
} else if (!userSite.data) {
|
|
router.push(`${SITE_URL}/dashboard/new-site`)
|
|
} else if (page?.id) {
|
|
if (isMint.data?.count) {
|
|
setIsMintOpen(true)
|
|
} else {
|
|
mintPage.mutate({
|
|
address,
|
|
pageId: page?.id,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (
|
|
mintProgress &&
|
|
address &&
|
|
isMint.isSuccess &&
|
|
page?.id &&
|
|
userSite.isSuccess
|
|
) {
|
|
if (!userSite.data) {
|
|
router.push(`${SITE_URL}/dashboard/new-site`)
|
|
}
|
|
if (!isMint.data.count) {
|
|
mintPage.mutate({
|
|
address,
|
|
pageId: page?.id,
|
|
})
|
|
}
|
|
setMintProgress(false)
|
|
}
|
|
}, [
|
|
userSite.isSuccess,
|
|
userSite.data,
|
|
router,
|
|
mintProgress,
|
|
address,
|
|
isMint.isSuccess,
|
|
isMint.data?.count,
|
|
mintPage,
|
|
page?.id,
|
|
])
|
|
|
|
useEffect(() => {
|
|
if (
|
|
likeProgress &&
|
|
address &&
|
|
isLike.isSuccess &&
|
|
page?.id &&
|
|
userSite.isSuccess
|
|
) {
|
|
if (!userSite.data) {
|
|
router.push(`${SITE_URL}/dashboard/new-site`)
|
|
}
|
|
if (!isLike.data.count) {
|
|
likePage.mutate({
|
|
address,
|
|
pageId: page?.id,
|
|
})
|
|
}
|
|
setLikeProgress(false)
|
|
}
|
|
}, [
|
|
userSite.isSuccess,
|
|
userSite.data,
|
|
router,
|
|
likeProgress,
|
|
address,
|
|
isLike.isSuccess,
|
|
isLike.data?.count,
|
|
likePage,
|
|
page?.id,
|
|
])
|
|
|
|
const [likeList, setLikeList] = useState<any[]>([])
|
|
const [likeCursor, setLikeCursor] = useState<string>()
|
|
useEffect(() => {
|
|
if (likes.isSuccess && likes.data) {
|
|
setLikeList(likes.data.list || [])
|
|
setLikeCursor(likes.data.cursor || "")
|
|
}
|
|
}, [likes.isSuccess])
|
|
|
|
const loadMoreLikes = async () => {
|
|
if (likeCursor && page?.id) {
|
|
const subs = await getLikes({
|
|
pageId: page.id,
|
|
cursor: likeCursor,
|
|
})
|
|
setLikeList((prev) => [...prev, ...(subs?.list || [])])
|
|
setLikeCursor(subs?.cursor || "")
|
|
}
|
|
}
|
|
|
|
const [mintList, setMintList] = useState<any[]>([])
|
|
const [mintCursor, setMintCursor] = useState<string>()
|
|
useEffect(() => {
|
|
if (mints.isSuccess && mints.data) {
|
|
setMintList(mints.data.list || [])
|
|
setMintCursor(mints.data.cursor || "")
|
|
}
|
|
}, [mints.isSuccess])
|
|
|
|
const loadMoreMints = async () => {
|
|
if (mintCursor && page?.id) {
|
|
const subs = await getMints({
|
|
pageId: page.id,
|
|
cursor: mintCursor,
|
|
})
|
|
setMintList((prev) => [...prev, ...(subs?.list || [])])
|
|
setMintCursor(subs?.cursor || "")
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div className="xlog-post-footer flex fill-gray-400 text-gray-500 mt-14 mb-12 items-center">
|
|
<div className="xlog-post-like flex items-center">
|
|
<Button
|
|
variant="like"
|
|
className={`flex items-center mr-2 ${
|
|
isLike.isSuccess && isLike.data.count && "active"
|
|
}`}
|
|
isAutoWidth={true}
|
|
onClick={like}
|
|
isLoading={
|
|
userSite.isLoading ||
|
|
likePage.isLoading ||
|
|
unlikePage.isLoading ||
|
|
likeProgress
|
|
}
|
|
>
|
|
<LikeIcon className="mr-1 w-10 h-10" />
|
|
<span>{likes.data?.count || 0}</span>
|
|
</Button>
|
|
<ul
|
|
className="-space-x-4 mr-10 cursor-pointer"
|
|
onClick={() => setIsLikeListOpen(true)}
|
|
>
|
|
{likes.data?.list
|
|
?.sort((a, b) =>
|
|
b.fromCharacter?.metadata?.content?.avatars ? 1 : -1,
|
|
)
|
|
.slice(0, 3)
|
|
?.map((like: any, index) => (
|
|
<li className="inline-block" key={index}>
|
|
<Avatar
|
|
className="align-middle border-2 border-white"
|
|
images={
|
|
like.fromCharacter?.metadata?.content?.avatars || []
|
|
}
|
|
name={like.fromCharacter?.metadata?.content?.name}
|
|
size={40}
|
|
/>
|
|
</li>
|
|
))}
|
|
{(likes.data?.count || 0) > 3 && (
|
|
<li className="inline-block">
|
|
<div className="align-middle border-2 border-white w-10 h-10 rounded-full inline-flex bg-gray-100 items-center justify-center text-gray-400 font-medium">
|
|
+{likes.data!.count - 3}
|
|
</div>
|
|
</li>
|
|
)}
|
|
</ul>
|
|
</div>
|
|
<div className="xlog-post-mint flex items-center">
|
|
<Button
|
|
variant="collect"
|
|
className={`flex items-center mr-2 ${
|
|
isMint.isSuccess && isMint.data.count && "active"
|
|
}`}
|
|
isAutoWidth={true}
|
|
onClick={mint}
|
|
isLoading={mintPage.isLoading || likeProgress}
|
|
>
|
|
<MintIcon className="mr-2 w-8 h-8" />
|
|
<span>{mints.data?.count || 0}</span>
|
|
</Button>
|
|
<ul
|
|
className="-space-x-4 cursor-pointer"
|
|
onClick={() => setIsMintListOpen(true)}
|
|
>
|
|
{mints.data?.list
|
|
?.sort((a, b: any) =>
|
|
b.character?.metadata?.content?.avatars ? 1 : -1,
|
|
)
|
|
.slice(0, 3)
|
|
.map((mint: any, index) => (
|
|
<li className="inline-block" key={index}>
|
|
<Avatar
|
|
className="align-middle border-2 border-white"
|
|
images={mint.character?.metadata?.content?.avatars || []}
|
|
name={mint.character?.metadata?.content?.name}
|
|
size={40}
|
|
/>
|
|
</li>
|
|
))}
|
|
{(mints.data?.count || 0) > 3 && (
|
|
<li className="inline-block">
|
|
<div className="align-middle border-2 border-white w-10 h-10 rounded-full inline-flex bg-gray-100 items-center justify-center text-gray-400 font-medium">
|
|
+{mints.data!.count - 3}
|
|
</div>
|
|
</li>
|
|
)}
|
|
</ul>
|
|
</div>
|
|
<Modal
|
|
open={isLikeOpen}
|
|
setOpen={setIsLikeOpen}
|
|
title="Like successfull"
|
|
>
|
|
<div className="p-5">
|
|
Your like has been permanently stored on the blockchain, view them{" "}
|
|
<UniLink
|
|
className="text-theme-color"
|
|
href={`${CSB_SCAN}/tx/${isLike.data?.list?.[0]?.transactionHash}`}
|
|
>
|
|
here
|
|
</UniLink>
|
|
</div>
|
|
<div className="h-16 border-t flex items-center px-5">
|
|
<Button isBlock onClick={() => setIsLikeOpen(false)}>
|
|
Got it, thanks!
|
|
</Button>
|
|
</div>
|
|
</Modal>
|
|
<Modal
|
|
open={isMintOpen}
|
|
setOpen={setIsMintOpen}
|
|
title="Mint successfull"
|
|
>
|
|
<div className="p-5">
|
|
Your minting has been permanently stored on the blockchain, view
|
|
them{" "}
|
|
<UniLink
|
|
className="text-theme-color"
|
|
href={`${CSB_SCAN}/tx/${isMint.data?.list?.[0]?.transactionHash}`}
|
|
>
|
|
here
|
|
</UniLink>
|
|
</div>
|
|
<div className="h-16 border-t flex items-center px-5">
|
|
<Button isBlock onClick={() => setIsMintOpen(false)}>
|
|
Got it, thanks!
|
|
</Button>
|
|
</div>
|
|
</Modal>
|
|
<CharacterList
|
|
open={isLikeListOpen}
|
|
setOpen={setIsLikeListOpen}
|
|
title="Like List"
|
|
loadMore={loadMoreLikes}
|
|
hasMore={!!likeCursor}
|
|
list={likeList}
|
|
></CharacterList>
|
|
<CharacterList
|
|
open={isMintListOpen}
|
|
setOpen={setIsMintListOpen}
|
|
title="Mint List"
|
|
loadMore={loadMoreMints}
|
|
hasMore={!!mintCursor}
|
|
list={mintList}
|
|
></CharacterList>
|
|
</div>
|
|
<Comment page={page} />
|
|
</>
|
|
)
|
|
}
|