feat(posts): Add user replies tab and improve reply management

- Add "replies" tab to user profile page to display posts where user replied to others
- Implement replies fetching via new `type=replies` query parameter in posts API
- Add reply deletion permissions for parent post owners on their own posts
- Add swarm reply deletion notification to origin nodes when replies are deleted
- Pass `parentPostAuthorId` prop to PostCard for improved reply context tracking
- Update profile tab navigation to include replies tab for non-bot users
- Add loading and empty states for replies tab display
- Improve authorization logic to allow parent post owners to delete replies on their posts
This commit is contained in:
Christomatt
2026-01-26 14:22:32 +01:00
parent 141b99747a
commit a2ec470354
7 changed files with 232 additions and 27 deletions
+54
View File
@@ -112,6 +112,60 @@ export async function POST(request: NextRequest) {
}
}
/**
* DELETE /api/swarm/replies
*
* Receives a deletion request from another node.
* Removes a reply that was previously delivered.
*/
export async function DELETE(request: NextRequest) {
try {
if (!db) {
return NextResponse.json({ error: 'Database not available' }, { status: 503 });
}
const body = await request.json();
const { replyId, nodeDomain, authorHandle } = body;
if (!replyId || !nodeDomain) {
return NextResponse.json({ error: 'replyId and nodeDomain required' }, { status: 400 });
}
// Find the reply by its swarm ID
const swarmReplyId = `swarm:${nodeDomain}:${replyId}`;
const existingReply = await db.query.posts.findFirst({
where: eq(posts.apId, swarmReplyId),
});
if (!existingReply) {
// Already deleted or never existed
return NextResponse.json({ success: true, message: 'Reply not found or already deleted' });
}
// Decrement parent's reply count
if (existingReply.replyToId) {
const parentPost = await db.query.posts.findFirst({
where: eq(posts.id, existingReply.replyToId),
});
if (parentPost && parentPost.repliesCount > 0) {
await db.update(posts)
.set({ repliesCount: parentPost.repliesCount - 1 })
.where(eq(posts.id, existingReply.replyToId));
}
}
// Delete the reply
await db.delete(posts).where(eq(posts.id, existingReply.id));
console.log(`[Swarm] Deleted reply ${swarmReplyId} from ${nodeDomain}`);
return NextResponse.json({ success: true });
} catch (error) {
console.error('[Swarm] Delete reply error:', error);
return NextResponse.json({ error: 'Failed to delete reply' }, { status: 500 });
}
}
/**
* GET /api/swarm/replies?postId=xxx
*