import React from 'react'; import { useForum } from '@/contexts/useForum'; import { Link } from 'react-router-dom'; import { formatDistanceToNow } from 'date-fns'; import { Skeleton } from '@/components/ui/skeleton'; import { MessageSquareText, Newspaper } from 'lucide-react'; import { AuthorDisplay } from './ui/author-display'; interface FeedItemBase { id: string; type: 'post' | 'comment'; timestamp: number; ownerAddress: string; cellId?: string; postId?: string; } interface PostFeedItem extends FeedItemBase { type: 'post'; title: string; cellId: string; postId: string; commentCount: number; voteCount: number; } interface CommentFeedItem extends FeedItemBase { type: 'comment'; content: string; postId: string; voteCount: number; } type FeedItem = PostFeedItem | CommentFeedItem; const ActivityFeed: React.FC = () => { const { posts, comments, getCellById, isInitialLoading } = useForum(); const combinedFeed: FeedItem[] = [ ...posts.map( (post): PostFeedItem => ({ id: post.id, type: 'post', timestamp: post.timestamp, ownerAddress: post.authorAddress, title: post.title, cellId: post.cellId, postId: post.id, commentCount: 0, voteCount: post.upvotes.length - post.downvotes.length, }) ), ...comments .map((comment): CommentFeedItem | null => { const parentPost = posts.find(p => p.id === comment.postId); if (!parentPost) return null; return { id: comment.id, type: 'comment', timestamp: comment.timestamp, ownerAddress: comment.authorAddress, content: comment.content, postId: comment.postId, cellId: parentPost.cellId, voteCount: comment.upvotes.length - comment.downvotes.length, }; }) .filter((item): item is CommentFeedItem => item !== null), ].sort((a, b) => b.timestamp - a.timestamp); const renderFeedItem = (item: FeedItem) => { const cell = item.cellId ? getCellById(item.cellId) : undefined; const timeAgo = formatDistanceToNow(new Date(item.timestamp), { addSuffix: true, }); const linkTarget = item.type === 'post' ? `/post/${item.postId}` : `/post/${item.postId}#comment-${item.id}`; return (
{item.content}
)} ); }; if (isInitialLoading) { return (No activity yet. Be the first to post!
) : ( combinedFeed.map(renderFeedItem) )}