feat: mint and like list
This commit is contained in:
parent
791f6db487
commit
56c9a036e2
|
|
@ -20,6 +20,8 @@ import { DuplicateIcon } from "@heroicons/react/solid"
|
||||||
import { Comment } from "~/components/common/Comment"
|
import { Comment } from "~/components/common/Comment"
|
||||||
import { UniLink } from "~/components/ui/UniLink"
|
import { UniLink } from "~/components/ui/UniLink"
|
||||||
import { Modal } from "~/components/ui/Modal"
|
import { Modal } from "~/components/ui/Modal"
|
||||||
|
import { Avatar } from "../ui/Avatar"
|
||||||
|
import { BlockchainIcon } from "~/components/icons/BlockchainIcon"
|
||||||
|
|
||||||
export const PostFooter: React.FC<{
|
export const PostFooter: React.FC<{
|
||||||
page?: Note
|
page?: Note
|
||||||
|
|
@ -36,22 +38,8 @@ export const PostFooter: React.FC<{
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
let [isLikeOpen, setIsLikeOpen] = useState(false)
|
let [isLikeOpen, setIsLikeOpen] = useState(false)
|
||||||
let [isMintOpen, setIsMintOpen] = useState(false)
|
let [isMintOpen, setIsMintOpen] = useState(false)
|
||||||
|
let [isLikeListOpen, setIsLikeListOpen] = useState(false)
|
||||||
function closeLikeModal() {
|
let [isMintListOpen, setIsMintListOpen] = useState(false)
|
||||||
setIsLikeOpen(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
function openLikeModal() {
|
|
||||||
setIsLikeOpen(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeMintModal() {
|
|
||||||
setIsMintOpen(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
function openMintModal() {
|
|
||||||
setIsMintOpen(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const likes = useGetLikes({
|
const likes = useGetLikes({
|
||||||
pageId: page?.id,
|
pageId: page?.id,
|
||||||
|
|
@ -77,7 +65,7 @@ export const PostFooter: React.FC<{
|
||||||
router.push(`${SITE_URL}/dashboard/new-site`)
|
router.push(`${SITE_URL}/dashboard/new-site`)
|
||||||
} else if (page?.id) {
|
} else if (page?.id) {
|
||||||
if (isLike.data?.count) {
|
if (isLike.data?.count) {
|
||||||
openLikeModal()
|
setIsLikeOpen(true)
|
||||||
} else {
|
} else {
|
||||||
likePage.mutate({
|
likePage.mutate({
|
||||||
address,
|
address,
|
||||||
|
|
@ -95,7 +83,7 @@ export const PostFooter: React.FC<{
|
||||||
router.push(`${SITE_URL}/dashboard/new-site`)
|
router.push(`${SITE_URL}/dashboard/new-site`)
|
||||||
} else if (page?.id) {
|
} else if (page?.id) {
|
||||||
if (isMint.data?.count) {
|
if (isMint.data?.count) {
|
||||||
openMintModal()
|
setIsMintOpen(true)
|
||||||
} else {
|
} else {
|
||||||
mintPage.mutate({
|
mintPage.mutate({
|
||||||
address,
|
address,
|
||||||
|
|
@ -155,10 +143,10 @@ export const PostFooter: React.FC<{
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex fill-gray-400 text-gray-500 mt-14 mb-12">
|
<div className="flex fill-gray-400 text-gray-500 mt-14 mb-12 items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="like"
|
variant="like"
|
||||||
className={`flex items-center mr-10 ${
|
className={`flex items-center mr-2 ${
|
||||||
isLike.isSuccess && isLike.data.count && "active"
|
isLike.isSuccess && isLike.data.count && "active"
|
||||||
}`}
|
}`}
|
||||||
isAutoWidth={true}
|
isAutoWidth={true}
|
||||||
|
|
@ -170,24 +158,68 @@ export const PostFooter: React.FC<{
|
||||||
likeProgress
|
likeProgress
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<LikeIcon className="mr-2 w-10 h-10" />
|
<LikeIcon className="mr-1 w-10 h-10" />
|
||||||
<span>{likes.data?.count || 0}</span>
|
<span>{likes.data?.count || 0}</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
<ul
|
||||||
|
className="-space-x-4 mr-10 cursor-pointer"
|
||||||
|
onClick={() => setIsLikeListOpen(true)}
|
||||||
|
>
|
||||||
|
{likes.data?.list?.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>
|
||||||
<Button
|
<Button
|
||||||
variant="collect"
|
variant="collect"
|
||||||
className={`flex items-center mr-10 ${
|
className={`flex items-center mr-2 ${
|
||||||
isMint.isSuccess && isMint.data.count && "active"
|
isMint.isSuccess && isMint.data.count && "active"
|
||||||
}`}
|
}`}
|
||||||
isAutoWidth={true}
|
isAutoWidth={true}
|
||||||
onClick={mint}
|
onClick={mint}
|
||||||
isLoading={mintPage.isLoading || likeProgress}
|
isLoading={mintPage.isLoading || likeProgress}
|
||||||
>
|
>
|
||||||
<DuplicateIcon className="mr-2 w-10 h-10" />
|
<DuplicateIcon className="mr-1 w-10 h-10" />
|
||||||
<span>{mints.data?.count || 0}</span>
|
<span>{mints.data?.count || 0}</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
<ul
|
||||||
|
className="-space-x-4 cursor-pointer"
|
||||||
|
onClick={() => setIsMintListOpen(true)}
|
||||||
|
>
|
||||||
|
{mints.data?.list?.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>
|
||||||
<Modal
|
<Modal
|
||||||
open={isLikeOpen}
|
open={isLikeOpen}
|
||||||
setOpen={closeLikeModal}
|
setOpen={setIsLikeOpen}
|
||||||
title="Like successfull"
|
title="Like successfull"
|
||||||
>
|
>
|
||||||
<div className="p-5">
|
<div className="p-5">
|
||||||
|
|
@ -200,14 +232,14 @@ export const PostFooter: React.FC<{
|
||||||
</UniLink>
|
</UniLink>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-16 border-t flex items-center px-5">
|
<div className="h-16 border-t flex items-center px-5">
|
||||||
<Button isBlock onClick={closeLikeModal}>
|
<Button isBlock onClick={() => setIsLikeOpen(false)}>
|
||||||
Got it, thanks!
|
Got it, thanks!
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Modal
|
<Modal
|
||||||
open={isMintOpen}
|
open={isMintOpen}
|
||||||
setOpen={closeMintModal}
|
setOpen={setIsMintOpen}
|
||||||
title="Mint successfull"
|
title="Mint successfull"
|
||||||
>
|
>
|
||||||
<div className="p-5">
|
<div className="p-5">
|
||||||
|
|
@ -221,11 +253,93 @@ export const PostFooter: React.FC<{
|
||||||
</UniLink>
|
</UniLink>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-16 border-t flex items-center px-5">
|
<div className="h-16 border-t flex items-center px-5">
|
||||||
<Button isBlock onClick={closeMintModal}>
|
<Button isBlock onClick={() => setIsMintOpen(false)}>
|
||||||
Got it, thanks!
|
Got it, thanks!
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<Modal
|
||||||
|
open={isLikeListOpen}
|
||||||
|
setOpen={setIsLikeListOpen}
|
||||||
|
title="Like List"
|
||||||
|
>
|
||||||
|
<ul className="px-5">
|
||||||
|
{likes.data?.list?.map((like: any, index) => (
|
||||||
|
<li
|
||||||
|
className="py-3 flex items-center space-x-2 text-sm"
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
|
<UniLink
|
||||||
|
href={`https://crossbell.kindjeff.com/@${like?.fromCharacter?.handle}`}
|
||||||
|
className="flex items-center space-x-2 text-sm"
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
className="align-middle border-2 border-white"
|
||||||
|
images={
|
||||||
|
like.fromCharacter?.metadata?.content?.avatars || []
|
||||||
|
}
|
||||||
|
name={like.fromCharacter?.metadata?.content?.name}
|
||||||
|
size={40}
|
||||||
|
/>
|
||||||
|
<span>{like.fromCharacter?.metadata?.content?.name}</span>
|
||||||
|
<span className="text-zinc-400">
|
||||||
|
@{like.fromCharacter?.handle}
|
||||||
|
</span>
|
||||||
|
</UniLink>
|
||||||
|
<UniLink
|
||||||
|
href={"https://scan.crossbell.io/tx/" + like.transactionHash}
|
||||||
|
>
|
||||||
|
<BlockchainIcon />
|
||||||
|
</UniLink>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<div className="h-16 border-t flex items-center px-5">
|
||||||
|
<Button isBlock onClick={() => setIsLikeListOpen(false)}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
<Modal
|
||||||
|
open={isMintListOpen}
|
||||||
|
setOpen={setIsMintListOpen}
|
||||||
|
title="Mint List"
|
||||||
|
>
|
||||||
|
<ul className="px-5">
|
||||||
|
{mints.data?.list?.map((mint: any, index) => (
|
||||||
|
<li
|
||||||
|
className="py-3 flex items-center space-x-2 text-sm"
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
|
<UniLink
|
||||||
|
href={`https://crossbell.kindjeff.com/@${mint?.character?.handle}`}
|
||||||
|
className="flex items-center space-x-2 text-sm"
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
className="align-middle border-2 border-white"
|
||||||
|
images={mint.character?.metadata?.content?.avatars || []}
|
||||||
|
name={mint.character?.metadata?.content?.name}
|
||||||
|
size={40}
|
||||||
|
/>
|
||||||
|
<span>{mint.character?.metadata?.content?.name}</span>
|
||||||
|
<span className="text-zinc-400">
|
||||||
|
@{mint.character?.handle}
|
||||||
|
</span>
|
||||||
|
</UniLink>
|
||||||
|
<UniLink
|
||||||
|
href={"https://scan.crossbell.io/tx/" + mint.transactionHash}
|
||||||
|
>
|
||||||
|
<BlockchainIcon />
|
||||||
|
</UniLink>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<div className="h-16 border-t flex items-center px-5">
|
||||||
|
<Button isBlock onClick={() => setIsMintListOpen(false)}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
<Comment page={page} />
|
<Comment page={page} />
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ export const Avatar: React.FC<
|
||||||
|
|
||||||
const image = useMemo(() => {
|
const image = useMemo(() => {
|
||||||
for (const image of images) {
|
for (const image of images) {
|
||||||
if (image) return image
|
if (image)
|
||||||
|
return image.replace("ipfs://", "https://gateway.ipfs.io/ipfs/")
|
||||||
}
|
}
|
||||||
}, [images])
|
}, [images])
|
||||||
|
|
||||||
|
|
@ -51,7 +52,7 @@ export const Avatar: React.FC<
|
||||||
<span
|
<span
|
||||||
{...props}
|
{...props}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
`inline-flex text-zinc-500 bg-gray-400 flex-shrink-0 items-center justify-center text-xl font-medium uppercase`,
|
`inline-flex text-zinc-500 bg-gray-400 flex-shrink-0 items-center justify-center text-xl font-medium uppercase overflow-hidden`,
|
||||||
borderRadius,
|
borderRadius,
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
|
@ -61,13 +62,7 @@ export const Avatar: React.FC<
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||||
<img
|
<img src={image} width={size} height={size} alt={name || ""} />
|
||||||
className={borderRadius}
|
|
||||||
src={image}
|
|
||||||
width={size}
|
|
||||||
height={size}
|
|
||||||
alt={name || ""}
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,6 @@ export async function getLikes({ pageId }: { pageId: string }) {
|
||||||
pageId.split("-")[1],
|
pageId.split("-")[1],
|
||||||
{
|
{
|
||||||
linkType: "like",
|
linkType: "like",
|
||||||
limit: 0,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -381,13 +380,19 @@ export async function mintPage({
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMints({ pageId }: { pageId: string }) {
|
export async function getMints({ pageId }: { pageId: string }) {
|
||||||
return indexer.getMintedNotesOfNote(
|
const data = await indexer.getMintedNotesOfNote(
|
||||||
pageId.split("-")[0],
|
pageId.split("-")[0],
|
||||||
pageId.split("-")[1],
|
pageId.split("-")[1],
|
||||||
{
|
|
||||||
limit: 0,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
data.list.map(async (item: any) => {
|
||||||
|
const owner = item.owner
|
||||||
|
item.character = await indexer.getPrimaryCharacter(owner)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkMint({
|
export async function checkMint({
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ export default function Home({ region }: { region: string | null }) {
|
||||||
},
|
},
|
||||||
icon: <LoveIcon className="inline mb-2" />,
|
icon: <LoveIcon className="inline mb-2" />,
|
||||||
title: "Rich Interactions",
|
title: "Rich Interactions",
|
||||||
text: "Users can follow, comment, like, and collect your blog and posts, all on the blockchain of course.",
|
text: "Users can follow, comment, like, and mint your blog and posts, all on the blockchain of course.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
screenshot: {
|
screenshot: {
|
||||||
|
|
@ -105,9 +105,8 @@ export default function Home({ region }: { region: string | null }) {
|
||||||
"Only Controlled by Yourself",
|
"Only Controlled by Yourself",
|
||||||
"Open Source",
|
"Open Source",
|
||||||
"Self-hosting",
|
"Self-hosting",
|
||||||
"Like Interaction",
|
"Like Posts",
|
||||||
"Comment Interaction",
|
"Comment Posts",
|
||||||
"Following Interaction",
|
|
||||||
"Custom Domain",
|
"Custom Domain",
|
||||||
"Custom CSS",
|
"Custom CSS",
|
||||||
"Navigation",
|
"Navigation",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue