Skip to main content

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

PropTypeRequiredDefaultDescription
sessionobjectYes--Supabase auth session with user.id

URL Parameters

ParamDescription
postIdThe 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_at timestamp 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_posts with 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_url render 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} />} />
  • 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