From 3ba60cadf55ae91765eb6983ccb5a029e76d9469 Mon Sep 17 00:00:00 2001 From: Christomatt Date: Mon, 26 Jan 2026 15:04:37 +0100 Subject: [PATCH] refactor: reformat PostCard component for improved readability and consistent styling. --- src/components/PostCard.tsx | 456 ++++++++++++++++++------------------ 1 file changed, 231 insertions(+), 225 deletions(-) diff --git a/src/components/PostCard.tsx b/src/components/PostCard.tsx index b6d37cf..e5fe380 100644 --- a/src/components/PostCard.tsx +++ b/src/components/PostCard.tsx @@ -15,14 +15,14 @@ import { formatFullHandle, NODE_DOMAIN } from '@/lib/utils/handle'; // Component for link preview image that hides on error function LinkPreviewImage({ src, alt }: { src: string; alt: string }) { const [hasError, setHasError] = useState(false); - + if (hasError) return null; - + return (
- {alt} setHasError(true)} />
@@ -60,19 +60,19 @@ export function PostCard({ post, onLike, onRepost, onComment, onDelete, onHide, const formatTime = (dateStr: string | Date) => { const date = new Date(dateStr); - + if (isNaN(date.getTime())) { return ''; } - + const now = new Date(); const diff = now.getTime() - date.getTime(); - + // If post is in the future (minor clock skew), show "now" if (diff < 0) { return 'now'; } - + const seconds = Math.floor(diff / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); @@ -163,7 +163,7 @@ export function PostCard({ post, onLike, onRepost, onComment, onDelete, onHide, e.preventDefault(); e.stopPropagation(); setShowMenu(false); - + if (!currentUser) { showToast('Please log in to block users', 'error'); return; @@ -188,7 +188,7 @@ export function PostCard({ post, onLike, onRepost, onComment, onDelete, onHide, e.preventDefault(); e.stopPropagation(); setShowMenu(false); - + if (!currentUser) { showToast('Please log in to mute users', 'error'); return; @@ -222,8 +222,8 @@ export function PostCard({ post, onLike, onRepost, onComment, onDelete, onHide, } // Extract node domain from the post - const nodeDomain = post.nodeDomain || (post.author.handle.includes('@') - ? post.author.handle.split('@')[1] + const nodeDomain = post.nodeDomain || (post.author.handle.includes('@') + ? post.author.handle.split('@')[1] : null); if (!nodeDomain) { @@ -370,11 +370,11 @@ export function PostCard({ post, onLike, onRepost, onComment, onDelete, onHide, likesCount: 0, repostsCount: 0, repliesCount: 0, - author: typeof post.swarmReplyToAuthor === 'string' + author: typeof post.swarmReplyToAuthor === 'string' ? JSON.parse(post.swarmReplyToAuthor) : post.swarmReplyToAuthor, isSwarm: true, - nodeDomain: (typeof post.swarmReplyToAuthor === 'string' + nodeDomain: (typeof post.swarmReplyToAuthor === 'string' ? JSON.parse(post.swarmReplyToAuthor) : post.swarmReplyToAuthor)?.nodeDomain, } as Post : null); @@ -426,137 +426,98 @@ export function PostCard({ post, onLike, onRepost, onComment, onDelete, onHide,
{!isDetail && } -
- e.stopPropagation()}> -
- {post.author.avatarUrl ? ( - {post.author.displayName} - ) : ( - post.author.displayName?.charAt(0).toUpperCase() || post.author.handle.charAt(0).toUpperCase() - )} -
- -
-
- e.stopPropagation()}> - {post.author.displayName || post.author.handle} - - {post.bot && ( - - - AI Account - - )} -
- {formatFullHandle(post.author.handle, post.nodeDomain)} · {formatTime(post.createdAt)} -
- {currentUser && currentUser.id !== post.author.id && ( -
- - {showMenu && ( - <> -
+ e.stopPropagation()}> +
+ {post.author.avatarUrl ? ( + {post.author.displayName} + ) : ( + post.author.displayName?.charAt(0).toUpperCase() || post.author.handle.charAt(0).toUpperCase() + )} +
+ +
+
+ e.stopPropagation()}> + {post.author.displayName || post.author.handle} + + {post.bot && ( + { - e.preventDefault(); - e.stopPropagation(); - setShowMenu(false); - }} - /> -
-
+ {formatFullHandle(post.author.handle, post.nodeDomain)} · {formatTime(post.createdAt)} +
+ {currentUser && currentUser.id !== post.author.id && ( +
+ + {showMenu && ( + <> +
{ + e.preventDefault(); + e.stopPropagation(); + setShowMenu(false); + }} + /> +
- - Mute - - - {(post.nodeDomain || post.author.handle.includes('@')) && ( + + {(post.nodeDomain || post.author.handle.includes('@')) && ( + + )} +
+ + )} +
+ )} +
+ + {effectiveReplyTo && !showThread && ( +
+ Replying to e.stopPropagation()}>{formatFullHandle(effectiveReplyTo.author.handle)} +
+ )} + +
{renderContent(post.content, post.linkPreviewUrl ?? undefined)}
+ + {post.media && post.media.length > 0 && ( +
+ {post.media.map((item) => { + const isVideo = item.mimeType?.startsWith('video/'); + return ( +
+ {isVideo ? ( + { + e.stopPropagation(); + const video = e.currentTarget; + video.muted = !video.muted; + }} + /> + ) : ( + {item.altText )}
- - )} + ); + })}
)} -
- {effectiveReplyTo && !showThread && ( -
- Replying to e.stopPropagation()}>{formatFullHandle(effectiveReplyTo.author.handle)} -
- )} + {post.linkPreviewUrl && ( + + )} -
{renderContent(post.content, post.linkPreviewUrl ?? undefined)}
- - {post.media && post.media.length > 0 && ( -
- {post.media.map((item) => { - const isVideo = item.mimeType?.startsWith('video/'); - return ( -
- {isVideo ? ( - { - e.stopPropagation(); - const video = e.currentTarget; - video.muted = !video.muted; - }} - /> - ) : ( - {item.altText - )} + {post.linkPreviewUrl && !post.linkPreviewUrl.match(/(youtube\.com|youtu\.be|vimeo\.com)/) && ( + e.stopPropagation()} + > + {post.linkPreviewImage && ( + + )} +
+
{post.linkPreviewTitle ? decodeHtmlEntities(post.linkPreviewTitle) : ''}
+ {post.linkPreviewDescription && ( +
{decodeHtmlEntities(post.linkPreviewDescription)}
+ )} +
+ {new URL(post.linkPreviewUrl.startsWith('http') ? post.linkPreviewUrl : `https://${post.linkPreviewUrl}`).hostname}
- ); - })} -
- )} - - {post.linkPreviewUrl && ( - - )} - - {post.linkPreviewUrl && !post.linkPreviewUrl.match(/(youtube\.com|youtu\.be|vimeo\.com)/) && ( -
e.stopPropagation()} - > - {post.linkPreviewImage && ( - - )} -
-
{post.linkPreviewTitle ? decodeHtmlEntities(post.linkPreviewTitle) : ''}
- {post.linkPreviewDescription && ( -
{decodeHtmlEntities(post.linkPreviewDescription)}
- )} -
- {new URL(post.linkPreviewUrl.startsWith('http') ? post.linkPreviewUrl : `https://${post.linkPreviewUrl}`).hostname}
-
-
- )} - -
- - - - - {(currentUser?.id === post.author.id || (post.bot && currentUser?.id === post.bot.ownerId) || (parentPostAuthorId && currentUser?.id === parentPostAuthorId)) && ( - + )} -
-
+ +
+ + + + + {(currentUser && ( + currentUser.id === post.author.id || + (post.bot && currentUser.id === post.bot.ownerId) || + (parentPostAuthorId && currentUser.id === parentPostAuthorId) || + // Allow deleting own remote posts (where ID format differs but handle matches) + (post.author.id.startsWith('swarm:') && post.author.handle === currentUser.handle) + )) && ( + + )} +
+ ); }