diff --git a/README.md b/README.md index 922f5c4..c068ea8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Pin Save - decentralized Pinterest +# PinSave - decentralized decentalized image sharing platform

Size Limit CLI @@ -18,7 +18,7 @@ -Pin Save is a decentralized image, video sharing and content aggregation platform where community controls the platform. +PinSave is a decentralized image and content aggregation platform where community controls the platform. 1. The decentralized feed reinforces the discovery of content and feedback. 2. Upgradeable, resilient decentralized storage. @@ -32,15 +32,15 @@ Pin Save is a decentralized image, video sharing and content aggregation platfor - Image posting: -![Pin Save Upload](https://raw.githubusercontent.com/PinSaveDAO/PinSave-Metis/refs/heads/main/assets/upload.png) +![PinSave Upload](https://raw.githubusercontent.com/PinSaveDAO/PinSave-Metis/refs/heads/main/assets/upload.png) - Profile Page with ENS: -![Pin Save Upload](https://raw.githubusercontent.com/PinSaveDAO/PinSave-Metis/refs/heads/main/assets/profile.png) +![PinSave Upload](https://raw.githubusercontent.com/PinSaveDAO/PinSave-Metis/refs/heads/main/assets/profile.png) -### Optimism Smart contracts +### Metis PinSave Smart contracts -[Metis Smart contract Etherscan](https://explorer.metis.io/token/0x6F67850013b5775E36E35071a5CdD16ea43e1061) +[Metis PinSave Smart contract Etherscan](https://explorer.metis.io/token/0x6F67850013b5775E36E35071a5CdD16ea43e1061) ## Setup @@ -54,9 +54,8 @@ yarn dev ## Further Resources - [PinSave Figma Resources](https://www.figma.com/community/file/1102944149244783025) -- [Zk Ok Pin Save](https://zkok.io/mina/pin-save/) -- [EthBucharest 2024: Zero Knowledge proofs on Mina, zkPassport and SoulBound NFTs](https://docs.google.com/presentation/d/1OmJJgzk4iFbKexqBw87oU7oh4H9lXlFFh3eas0EF9y8/edit?usp=sharing) +- [EthBucharest 2024 PinSave: Zero Knowledge proofs on Mina, zkPassport and SoulBound NFTs](https://docs.google.com/presentation/d/1OmJJgzk4iFbKexqBw87oU7oh4H9lXlFFh3eas0EF9y8/edit?usp=sharing) - [PinSave.app DR](https://ahrefs.com/website-authority-checker/?input=pinsave.app) -- [Npm Pin Save mina package](https://www.npmjs.com/package/pin-mina) -- [Pin Save on Dspyt](https://dspyt.com/PinSave) -- [Pin Save retroPGF3](https://round3.optimism.io/projects/0xc613e2a991ce0dbcf8fae1d6128e67543da9710e14831112fba654cc8fe8c389) +- [Npm PinSave mina package](https://www.npmjs.com/package/pin-mina) +- [PinSave on Dspyt](https://dspyt.com/PinSave) +- [PinSave retroPGF3](https://round3.optimism.io/projects/0xc613e2a991ce0dbcf8fae1d6128e67543da9710e14831112fba654cc8fe8c389) diff --git a/packages/frontend/LICENSE b/packages/frontend/LICENSE index 8b4dfcb..5824134 100644 --- a/packages/frontend/LICENSE +++ b/packages/frontend/LICENSE @@ -1,6 +1,6 @@ # MIT License -Copyright (c) Pavel Fedotov 2024 +Copyright (c) Pavel Fedotov 2025 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/frontend/components/Post/DisplayMedia.tsx b/packages/frontend/components/Post/DisplayMedia.tsx index ec025c7..07f4b36 100644 --- a/packages/frontend/components/Post/DisplayMedia.tsx +++ b/packages/frontend/components/Post/DisplayMedia.tsx @@ -47,6 +47,7 @@ const DisplayMedia: React.FC = ({ post }) => { width={width} src={post.image} alt={post.name} + loading="lazy" style={{ height: "95%", borderRadius: "10px", diff --git a/packages/frontend/components/Posts/PostCard.tsx b/packages/frontend/components/Posts/PostCard.tsx index 88edb38..59a47b5 100644 --- a/packages/frontend/components/Posts/PostCard.tsx +++ b/packages/frontend/components/Posts/PostCard.tsx @@ -2,10 +2,14 @@ import { Paper, Text } from "@mantine/core"; import Image from "next/image"; import Link from "next/link"; -import type { Post } from "@/services/upload"; +type PostReduced = { + image: string; + name: string; + tokenId: number; +}; interface IMyProps { - post: Post; + post: PostReduced; } const PostCard: React.FC = ({ post }) => { diff --git a/packages/frontend/components/SEO/index.tsx b/packages/frontend/components/SEO/index.tsx index bec93c3..2edf54c 100644 --- a/packages/frontend/components/SEO/index.tsx +++ b/packages/frontend/components/SEO/index.tsx @@ -23,6 +23,7 @@ const CommonSEO = ({ content={`${siteMetadata.siteUrl}${router.asPath}`} /> + diff --git a/packages/frontend/components/SEO/siteMetadata.ts b/packages/frontend/components/SEO/siteMetadata.ts index b1d0765..acb0e15 100644 --- a/packages/frontend/components/SEO/siteMetadata.ts +++ b/packages/frontend/components/SEO/siteMetadata.ts @@ -1,9 +1,9 @@ export const siteMetadata = { - title: "Pin Save - decentralized Pinterest", + title: "PinSave - Decentralized Image Sharing & Content Aggregation Platform", author: "Pavel Fedotov", - headerTitle: "Pin Save - decentralized Pinterest", + headerTitle: "PinSave - Decentralized Image Sharing", description: - "Pin Save is a platform for decentralized content aggregation and image sharing where users have content ownership.", + "PinSave is a platform for decentralized content aggregation and image sharing where users have content ownership.", ogType: "website", ogImageUrl: "https://metis.pinsave.app/TwitterIconWords.png", siteUrl: "https://metis.pinsave.app", diff --git a/packages/frontend/components/UploadForm/index.tsx b/packages/frontend/components/UploadForm/index.tsx index da59339..77a1e09 100644 --- a/packages/frontend/components/UploadForm/index.tsx +++ b/packages/frontend/components/UploadForm/index.tsx @@ -3,7 +3,6 @@ import { Paper, Title, TextInput, - Textarea, Group, Button, Image, @@ -13,7 +12,6 @@ import { } from "@mantine/core"; import { Dropzone, MIME_TYPES } from "@mantine/dropzone"; import { useState, useEffect } from "react"; -import ReactPlayer from "react-player"; import { Upload, Replace } from "tabler-icons-react"; import { useAccount, @@ -29,24 +27,21 @@ import { getContractInfo } from "@/utils/contracts"; export const dropzoneChildren = (image: File | undefined) => { if (image) { - let link = URL.createObjectURL(image); + let link: string = URL.createObjectURL(image); return ( - {image.type[0] === "i" ? ( - uploaded image - ) : ( - - )} + uploaded image + { const { address: senderAddress } = useAccount(); const { address: contractAddress, abi } = getContractInfo(); - const { data: hash, writeContract: writeMintPost } = useWriteContract(); + const { + data: hash, + writeContract: writeMintPost, + status, + } = useWriteContract(); const [name, setName] = useState(""); const [description, setDescription] = useState(""); @@ -98,22 +97,19 @@ const UploadForm = () => { const [postReceiver, setPostReceiver] = useState<`0x${string}` | undefined>( senderAddress ); - - const [isPostUpdated, setIsPostUpdated] = useState(false); - const [isPostLoading, setIsPostLoading] = useState(false); - - const [cid, setCid] = useState(""); - + const [ensName, setEnsName] = useState(""); const [provider, setProvider] = useState<"Pinata">("Pinata"); - const [lastHash, setLastHash] = useState(""); + const [isPostReady, setIsPostReady] = useState(false); + const [isPostLoading, setIsPostLoading] = useState(false); - const [ensName, setEnsName] = useState(""); + const [cid, setCID] = useState(""); + const [lastHash, setLastHash] = useState(); const config = createConfig({ chains: [mainnet], transports: { - [mainnet.id]: http(process.env.NEXT_PUBLIC_ALCHEMY), + [mainnet.id]: http(process.env.NEXT_PUBLIC_ALCHEMY_MAINNET), }, }); @@ -129,6 +125,7 @@ const UploadForm = () => { image?: File ) { if (description !== "" && name !== "" && image && postReceiver) { + setIsPostLoading(true); const cid: string | undefined = await UploadData({ data: { name: name, description: description, image: image }, provider: provider, @@ -138,13 +135,12 @@ const UploadForm = () => { throw new Error("no cid"); } - setCid(cid); + setCID(cid); + setIsPostReady(true); setImage(undefined); setName(""); setDescription(""); - - setIsPostLoading(true); } } @@ -160,14 +156,9 @@ const UploadForm = () => { setPostReceiver(receiverAddress); } - if (isPostLoading) { - setIsPostUpdated(true); - console.log("Updated response:" + cid); - } - - if (hash && hash !== lastHash && isPostUpdated) { + if (hash && hash !== lastHash && isPostReady) { setLastHash(hash); - setIsPostUpdated(false); + setIsPostReady(false); setIsPostLoading(false); } }, [ @@ -176,10 +167,11 @@ const UploadForm = () => { receiverAddress, lastHash, cid, - isPostUpdated, + isPostReady, senderAddress, ensName, hash, + fetchedAccount, ]); return ( @@ -214,7 +206,7 @@ const UploadForm = () => { )} - {!isPostUpdated ? ( + {!isPostLoading ? (

{ value={name} onChange={(e) => setName(e.target.value)} /> -