diff --git a/README.md b/README.md index 75abab9..8bc2412 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ ## Overview +**what?** + [pingpad](https://pingpad.io) is a minimalistic decentralized social platform, made for you and your community. **why?** -- complexity is the enemy. -- clarity paves the way for brilliance. -- embrace simplicity by focusing on clear and efficient solutions. + +clarity paves the way for brilliance. pingpad is focusing on clear and efficient solutions. + +**how?** + +built on top of [lens](https://lens.xyz) network ## Gallery diff --git a/src/app/api/profile/unfollow/route.ts b/src/app/api/profile/unfollow/route.ts new file mode 100644 index 0000000..7099395 --- /dev/null +++ b/src/app/api/profile/unfollow/route.ts @@ -0,0 +1,39 @@ +import { LensTransactionStatusType } from "@lens-protocol/client"; +import { type NextRequest, NextResponse } from "next/server"; +import { getLensClient } from "~/utils/getLensClient"; + +export const dynamic = "force-dynamic"; + +export async function POST(req: NextRequest) { + const { searchParams } = req.nextUrl; + const id = searchParams.get("id") || undefined; + + try { + const { client } = await getLensClient(); + + const result = await client.profile.unfollow({ + unfollow: [id], + }); + + if (result.isFailure()) { + return NextResponse.json({ error: result.error.message }, { status: 500 }); + } + + if (result.value.__typename === "LensProfileManagerRelayError") { + return NextResponse.json({ error: result.value.reason }, { status: 500 }); + } + + const data = result.value; + + const completion = await client.transaction.waitUntilComplete({ forTxId: data.txId }); + if (completion?.status === LensTransactionStatusType.Failed) { + console.error(completion.reason); + return NextResponse.json({ error: completion.reason, extra: completion.extraInfo }, { status: 500 }); + } + + return NextResponse.json({ result: result.value }, { status: 200, statusText: "Success" }); + } catch (error) { + console.error("Failed to unfollow profile: ", error.message); + return NextResponse.json({ error: `${error.message}` }, { status: 500 }); + } +} diff --git a/src/components/FollowButton.tsx b/src/components/FollowButton.tsx index d39b991..697cc2d 100644 --- a/src/components/FollowButton.tsx +++ b/src/components/FollowButton.tsx @@ -5,21 +5,23 @@ import { toast } from "sonner"; import type { User } from "./post/Post"; import { Button } from "./ui/button"; -export const FollowButton = ({ user }: {user: User}) => { +export const FollowButton = ({ user }: { user: User }) => { const [following, setFollowing] = useState(user.actions.followed); const toggleFollow = async () => { + const endpoint = following ? "/api/profile/unfollow" : "/api/profile/follow"; + setFollowing(!following); - const result = await fetch(`/api/profile/follow?id=${user.id}`, { + const result = await fetch(`${endpoint}?id=${user.id}`, { method: "POST", }); if (!result.ok) { setFollowing(!following); - toast.error(`Failed to follow: ${result.statusText} `); + toast.error(`${following ? "Unfollow" : "Follow"} action failed: ${result.statusText} `); } else { - toast.success("Followed successfully!"); + toast.success(`${following ? "Unfollowed" : "Followed"} Successfully!`); } };