feat: collapsible post cards in circle feed
Posts start collapsed showing author, timestamp, a thumbnail (if image) and truncated text preview with ▼ chevron. Tap the author row to expand the full post (body, full image, reactions, comments). Tap again to collapse. Lets users scan many posts quickly and expand only what interests them. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
581fdb074d
commit
560761968b
1 changed files with 29 additions and 5 deletions
|
|
@ -29,6 +29,7 @@ function PostCard({
|
||||||
onDeleted: (id: string) => void;
|
onDeleted: (id: string) => void;
|
||||||
onReact: (postId: string, emoji: string) => void;
|
onReact: (postId: string, emoji: string) => void;
|
||||||
}) {
|
}) {
|
||||||
|
const [collapsed, setCollapsed] = useState(true);
|
||||||
const [showComments, setShowComments] = useState(false);
|
const [showComments, setShowComments] = useState(false);
|
||||||
const [comments, setComments] = useState<CircleComment[]>([]);
|
const [comments, setComments] = useState<CircleComment[]>([]);
|
||||||
const [commentText, setCommentText] = useState("");
|
const [commentText, setCommentText] = useState("");
|
||||||
|
|
@ -112,15 +113,31 @@ function PostCard({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-2xl shadow-sm">
|
<div className="bg-white dark:bg-gray-800 rounded-2xl shadow-sm">
|
||||||
{/* Author row */}
|
{/* Author row — tap to collapse/expand */}
|
||||||
<div className="flex items-center justify-between px-4 pt-3 pb-2">
|
<div className="flex items-center justify-between px-4 pt-3 pb-2">
|
||||||
<div className="flex items-center gap-2">
|
<button
|
||||||
<div className="w-8 h-8 bg-rose-100 dark:bg-rose-900/40 rounded-full flex items-center justify-center text-sm">👨👩👧</div>
|
onClick={() => setCollapsed(v => !v)}
|
||||||
<div>
|
className="flex items-center gap-2 flex-1 min-w-0 text-left"
|
||||||
|
>
|
||||||
|
<div className="w-8 h-8 bg-rose-100 dark:bg-rose-900/40 rounded-full flex items-center justify-center text-sm flex-shrink-0">👨👩👧</div>
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
<p className="text-sm font-medium">{post.authorFamilyName}</p>
|
<p className="text-sm font-medium">{post.authorFamilyName}</p>
|
||||||
<p className="text-xs text-gray-400">{timeAgo(post.createdAt)}{post.sourceKind ? ` · shared a ${post.sourceKind}` : ""}</p>
|
<p className="text-xs text-gray-400">{timeAgo(post.createdAt)}{post.sourceKind ? ` · shared a ${post.sourceKind}` : ""}</p>
|
||||||
</div>
|
</div>
|
||||||
|
{/* Collapsed preview */}
|
||||||
|
{collapsed && (
|
||||||
|
<div className="flex items-center gap-2 flex-shrink-0 max-w-[45%]">
|
||||||
|
{post.imageUrl && (
|
||||||
|
<img src={post.imageUrl} alt="" className="w-10 h-10 rounded-lg object-cover flex-shrink-0" />
|
||||||
|
)}
|
||||||
|
{post.body && (
|
||||||
|
<span className="text-xs text-gray-400 truncate">{post.body}</span>
|
||||||
|
)}
|
||||||
|
<span className="text-gray-300 text-xs flex-shrink-0">▼</span>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
{!collapsed && <span className="text-gray-300 text-xs flex-shrink-0 ml-2">▲</span>}
|
||||||
|
</button>
|
||||||
{/* ⋯ menu — rendered outside overflow:hidden so it doesn't get clipped */}
|
{/* ⋯ menu — rendered outside overflow:hidden so it doesn't get clipped */}
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<button onClick={() => setShowMenu(v => !v)} className="p-2 text-gray-400 text-lg">⋯</button>
|
<button onClick={() => setShowMenu(v => !v)} className="p-2 text-gray-400 text-lg">⋯</button>
|
||||||
|
|
@ -153,6 +170,12 @@ function PostCard({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Collapsed divider */}
|
||||||
|
{collapsed && <div className="border-t border-gray-50 dark:border-gray-700 rounded-b-2xl" />}
|
||||||
|
|
||||||
|
{/* Expanded content */}
|
||||||
|
{!collapsed && <>
|
||||||
|
|
||||||
{/* Delete confirmation */}
|
{/* Delete confirmation */}
|
||||||
{deleteConfirm && (
|
{deleteConfirm && (
|
||||||
<div className="mx-4 mb-3 p-3 bg-red-50 dark:bg-red-900/20 rounded-xl space-y-2">
|
<div className="mx-4 mb-3 p-3 bg-red-50 dark:bg-red-900/20 rounded-xl space-y-2">
|
||||||
|
|
@ -257,6 +280,7 @@ function PostCard({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</>} {/* end !collapsed */}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue