import React, { useState } from 'react';
import { Link, useParams } from 'react-router-dom';
import {
useCell,
useCellPosts,
useForumActions,
usePermissions,
useUserVotes,
useAuth,
useForumData,
} from '@/hooks';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Skeleton } from '@/components/ui/skeleton';
import { LinkRenderer } from '@/components/ui/link-renderer';
import { ShareButton } from '@/components/ui/ShareButton';
import {
ArrowLeft,
MessageSquare,
MessageCircle,
ArrowUp,
ArrowDown,
RefreshCw,
Shield,
UserX,
} from 'lucide-react';
import { formatDistanceToNow } from 'date-fns';
import { CypherImage } from './ui/CypherImage';
import { AuthorDisplay } from './ui/author-display';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip';
const PostList = () => {
const { cellId } = useParams<{ cellId: string }>();
// ✅ Use reactive hooks for data and actions
const cell = useCell(cellId);
const cellPosts = useCellPosts(cellId, { sortBy: 'relevance' });
const {
createPost,
votePost,
moderatePost,
unmoderatePost,
moderateUser,
refreshData,
isCreatingPost,
isVoting,
} = useForumActions();
const { canPost, canVote, canModerate } = usePermissions();
const userVotes = useUserVotes();
const { currentUser } = useAuth();
const { commentsByPost } = useForumData();
const [newPostTitle, setNewPostTitle] = useState('');
const [newPostContent, setNewPostContent] = useState('');
if (!cellId || cellPosts.isLoading) {
return (
{[...Array(3)].map((_, i) => (
))}
);
}
if (!cell) {
return (
Cell Not Found
The cell you're looking for doesn't exist.
);
}
const handleCreatePost = async (e: React.FormEvent) => {
e.preventDefault();
if (!newPostContent.trim()) return;
// ✅ All validation handled in hook
const post = await createPost(cellId, newPostTitle, newPostContent);
if (post) {
setNewPostTitle('');
setNewPostContent('');
}
};
// Handle keyboard shortcuts
const handleKeyDown = (e: React.KeyboardEvent) => {
// Enter inserts newline by default. Send on Ctrl+Enter or Shift+Enter.
const isSendCombo = (e.ctrlKey || e.metaKey || e.shiftKey) && e.key === 'Enter';
if (isSendCombo) {
e.preventDefault();
if (!isCreatingPost && newPostContent.trim() && newPostTitle.trim()) {
handleCreatePost(e as React.FormEvent);
}
}
};
const handleVotePost = async (postId: string, isUpvote: boolean) => {
// ✅ Permission checking handled in hook
await votePost(postId, isUpvote);
};
const getPostVoteType = (postId: string) => {
return userVotes.getPostVoteType(postId);
};
// ✅ Posts already filtered by hook based on user permissions
const visiblePosts = cellPosts.posts;
const handleModerate = async (postId: string) => {
const reason =
window.prompt('Enter a reason for moderation (optional):') || undefined;
if (!cell) return;
// ✅ All validation handled in hook
await moderatePost(cell.id, postId, reason);
};
const handleUnmoderate = async (postId: string) => {
const reason =
window.prompt('Optional note for unmoderation?') || undefined;
if (!cell) return;
await unmoderatePost(cell.id, postId, reason);
};
const handleModerateUser = async (userAddress: string) => {
const reason =
window.prompt('Reason for moderating this user? (optional)') || undefined;
if (!cell) return;
// ✅ All validation handled in hook
await moderateUser(cell.id, userAddress, reason);
};
return (
{cell.name}
{cell.description}
{canPost && (
)}
{!canPost && !currentUser && (
Connect wallet and verify Ordinal ownership to post
)}
{visiblePosts.length === 0 ? (
No Threads Yet
{canPost
? 'Be the first to post in this cell!'
: 'Connect your wallet and verify Ordinal ownership to start a thread.'}
) : (
visiblePosts.map(post => (
{post.upvotes.length - post.downvotes.length}
{post.title}
{formatDistanceToNow(post.timestamp, {
addSuffix: true,
})}
by
•
{commentsByPost[post.id]?.length || 0} comments
{canModerate(cell.id) && !post.moderated && (
Moderate post
)}
{canModerate(cell.id) && post.author !== cell.author && (
Moderate user
)}
{canModerate(cell.id) && post.moderated && (
Unmoderate post
)}
))
)}
);
};
export default PostList;