Skip to content

Commit

Permalink
load post comments inline, add comments api
Browse files Browse the repository at this point in the history
  • Loading branch information
kualta committed Jun 29, 2024
1 parent efcb437 commit 021dabc
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 10 deletions.
36 changes: 36 additions & 0 deletions src/app/api/posts/[id]/comments/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { LimitType } from "@lens-protocol/client";
import { type NextRequest, NextResponse } from "next/server";
import { lensItemToPost } from "~/components/post/Post";
import { getLensClient } from "~/utils/getLensClient";

export const dynamic = "force-dynamic";

export async function GET(req: NextRequest, { params }: { params: { id: string } }) {
const id = params.id;
const cursor = req.nextUrl.searchParams.get("cursor") ?? undefined;

if (!id) {
return NextResponse.json({ error: "Missing publication id" }, { status: 400 });
}

try {
const { client } = await getLensClient();

const comments = await client.publication.fetchAll({
where: { commentOn: { id } },
limit: LimitType.TwentyFive,
cursor,
});

if (!comments.items) {
throw new Error("No comments found");
}

const commentsPosts = comments.items.map((comment) => lensItemToPost(comment));

return NextResponse.json({ comments: commentsPosts, nextCursor: comments.pageInfo.next }, { status: 200 });
} catch (error) {
console.error("Failed to load comments: ", error.message);
return NextResponse.json({ error: `${error.message}` }, { status: 500 });
}
}
8 changes: 6 additions & 2 deletions src/components/LoadingIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { LoaderCircleIcon } from "lucide-react";

export const LoadingSpinner = ({ size = 22 }: { size?: number }) => {
return <LoaderCircleIcon size={size} className="animate-spin justify-center items-center" />;
export const LoadingSpinner = ({ size = 22, className }: { size?: number; className?: string }) => {
return (
<div className={className}>
<LoaderCircleIcon size={size} className="animate-spin justify-center items-center" />
</div>
);
};
58 changes: 50 additions & 8 deletions src/components/post/PostComments.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,70 @@
import { PlusIcon } from "lucide-react";
import React, { useState, useEffect, useCallback } from "react";
import { LoadingSpinner } from "../LoadingIcon";
import { Button } from "../ui/button";
import type { Post } from "./Post";
import { PostView } from "./PostView";
import PostWizard from "./PostWizard";

export const PostComments = ({ post, isExpanded }: { post: Post; isExpanded: boolean }) => {
const comments = post.comments.map((comment, index) => (
const [comments, setComments] = useState(post.comments);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [cursor, setCursor] = useState(undefined);

useEffect(() => {
isExpanded ? loadMoreComments() : setComments(post.comments);
}, [isExpanded]);

const loadMoreComments = useCallback(async () => {
if (loading) return;
setLoading(true);
try {
const res = await fetch(`/api/posts/${post.id}/comments?${cursor ? `cursor=${cursor}` : ""}`, {
method: "GET",
});
if (!res.ok) throw new Error(res.statusText);
const { comments: newComments, nextCursor } = await res.json();
const diffComments = newComments.filter((comment) => !post.comments.find((c) => c.id === comment.id));
setComments((prevComments) => [...prevComments, ...diffComments]);
setCursor(nextCursor);
} catch (err) {
setError(`Could not fetch comments: ${err.message}`);
} finally {
setLoading(false);
}
}, [cursor, loading, post.id]);

const commentElements = comments.map((comment, index) => (
<PostView
key={comment.id}
post={comment}
settings={{
isComment: true,
showBadges: true,
isLastComment: index === post.comments.length - 1,
isLastComment: index === comments.length - 1,
}}
/>
));

if (error) throw new Error(error);

return (
<div className="w-full flex flex-col items-end justify-center gap-2 text-xs sm:text-sm">
{isExpanded && (
<div className="w-[90%] my-2">
<PostWizard replyingTo={post} />
</div>
)}
<ul className="w-[90%]">{comments}</ul>
<div className="w-[90%] gap-2">
{isExpanded && (
<div className="my-2">
<PostWizard replyingTo={post} />
</div>
)}
<ul>{commentElements}</ul>
{loading && <LoadingSpinner className="p-4" />}
{isExpanded && cursor && !loading && (
<Button variant="ghost" onClick={loadMoreComments} disabled={loading}>
<PlusIcon /> Load more Comments
</Button>
)}
</div>
</div>
);
};

0 comments on commit 021dabc

Please sign in to comment.