PostDetail
Location: src/components/PostDetail.jsx
Overview
PostDetail renders a single post in its full expanded form, along with a threaded comment section. It is the destination when a user clicks on a post from the feed or saved page. The component supports post editing, deletion, saving/unsaving, link sharing, image lightbox viewing, and nested comment threads with replies.
Author intent styles are applied to give the post its visual customization (font, surface, frame, effects, emphasis, background image). Comments support threaded nesting up to 2 levels deep, with deeper replies collapsible behind a toggle.
Relevant Invariants
- Invariant #4: "Intent Precedes Interpretation" -- The post's intent badge and styling are prominently displayed.
- Invariant #5: "Repair Over Punishment" -- Posts can be edited; edits are marked with "(edited)" but not punished.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
session | object | Yes | -- | Supabase auth session with user.id |
URL Parameters
| Param | Description |
|---|---|
postId | The ID of the post to display (from route :postId) |
Key Behaviors
- Post Rendering: Applies intent CSS variables, author font, surface, frame, effects, and emphasis classes. Supports background images.
- Comment Threading: Comments are organized into a tree using
parent_comment_id. Root comments render up to 2 levels of nesting; deeper replies are collapsed behind "View X more replies" toggle. - Sort Order: Comments can be sorted by newest or oldest first.
- Inline Editing: Post authors can edit content inline. A textarea replaces the content with Save/Cancel actions. The
edited_attimestamp is set on save. - Post Deletion: Authors can delete the post with a confirmation dialog, navigating to home on success.
- Save/Unsave: Toggles the post's saved status in
saved_postswith optimistic UI updates. - Share: Copies the current URL to the clipboard with a toast notification.
- Image Lightbox: Multi-image gallery with keyboard navigation (Escape, ArrowLeft, ArrowRight) and body scroll locking.
- Voice Playback: Posts with
voice_urlrender a VoicePlayer component. - User Links: Author and commenter names link to
/room/:username.
Usage
import PostDetail from '@/components/PostDetail';
// Rendered via React Router
<Route path="/post/:postId" element={<PostDetail session={session} />} />
Related
- Post -- Compact post card used in feeds
- Feed -- Navigates to PostDetail on post click
- Lightbox -- Standalone lightbox component (PostDetail has its own inline lightbox)
- Avatar -- Used for comment author avatars
Last updated: 2026-02-07