Skip to main content

Stories & Live

Closegram supports ephemeral Stories (photo and video, expire after 24 hours) and Live streaming sessions powered by LiveKit (WebRTC). Stories and Live now both post/view/comment/react end to end.

Each property has its own checkbox marking whether that specific piece is fully implemented and functional end to end (frontend + backend) — update these yourself as work lands; this page won't overwrite them.

  • Post a 24-hour story — photo or video (this doc previously said video was blocked by the upload endpoint; the /upload multer fileFilter already accepted video/* mimetypes, CreateStoryModal.tsx was the only piece still restricting to images — corrected)
  • View others' stories / story viewer
  • Comment on a story
  • React to a story with an emoji — a quick-reaction bar (👍❤️😂😮😢) calling the same generic likePost mutation regular posts use
  • Choose a story's audience (Everyone / Followers / Close Friends) — StoryCreateInput.audience is captured and saved with the story (added a close_friends value to the shared PostVisibility enum); fixed this session: it's now actually checked back too — getPost, getHomeStories, and getUserStories all gate on it, matching how regular Post.visibility already worked — see the technical reference
  • See who has viewed your story — fixed this session: storyViewers/storyViewerCount used to call nonexistent PostManager methods and threw at runtime; they now delegate to the existing watch-history viewer-tracking system (watch-history.manager.js#getPostViewers/#getPostViewersCount), owner-only — see the technical reference
  • Go live / start a live broadcast — GoLiveModal.tsx creates the stream, LiveRoomPage.tsx (owner view) connects to LiveKit as a publisher (camera + mic) once started
  • Join / watch a live stream — LiveRoomPage.tsx (viewer view) connects to LiveKit as a subscriber; enforces visibility (public / followers only / close friends / private) the same way a regular post does
  • Live chat / comments during a stream — send, pin/unpin (host), delete (the comment's own author, or the host)
  • Live reactions — a 6-emoji reaction bar (👍❤️😂😮😢😡), with live counts per reaction type
  • Live coin gifts — viewers send coin-priced gifts from a picker in the live room (sendLiveGift, liveGiftCatalog, liveStreamGifts), backed by a new live_stream_gift table; coins move sender → streamer through the ledger (sendTip, balance-checked). Gift prices are server-authoritative.
  • Speaker requests in live streams — viewers raise a hand (requestLiveSpeaker), the owner approves (respondToLiveSpeakerRequest), and approved viewers get a LiveKit publish token; UI in LiveSpeakerControls on the live room (the LiveKit publish-on-approval reconnect is the remaining live-only step)
  • Promote a live stream — a "Promote" button in the live room (promoteLiveStream) creates a companion post linking back to the live and runs it through the normal post-promotion flow, since a live stream isn't itself a promotable post
  • Default story/live audience, auto-archive, and location toggles — /settings/story-live now persists all of them via privacySettings/updatePrivacySettings: a default-audience select (defaultStoryAudience), plus saveStoryToArchive and shareLocation toggles
  • Hide your story from specific people
  • Live archive — browse your own past, ended live streams (Settings → Archive)
  • Live discovery — a dedicated /live page listing who's live now, trending, and scheduled streams, with a "Go live" button
  • Real-time live updates — comments, reaction counts, viewer count, speaker requests and the who's-live rail update live over graphql-ws subscriptions (liveStreamCommentAdded, liveStreamReactionsUpdated, liveStreamUpdated, liveStreamsChanged, liveSpeakerRequestsChanged, liveSpeakerStatusChanged) — no manual refresh

See the technical reference for GraphQL schemas, routes, source file links, and per-field wiring status.