FluxyChat

Core SDK

Inbox

Cross-room inbox — items feed, counter badges, channels, and realtime onItem.

Inbox model

FluxyChat separates three concepts that are easy to conflate:

ConceptWhat it isSDK / API
Items feedFlat list of inbox rows (mentions, unread rooms, snoozed, follow-ups)useInbox().items
CounterGlobal badge: number of rooms with unread messagesuseInbox().counter
UnseenRows in the current view that need attention (mentions + unread)useInbox().unseen
Channel watermarkPer-room “how far you read” in chat historymarkReadRest(roomId, messageId) / markReadLatest in useChat

The inbox tracks noticing (mentions, unread rooms, snooze, follow-ups).
The room channel tracks reading (last read message id inside a room). Clearing inbox unread does not automatically advance the room watermark unless you call mark-read.

Quick start

import { useInbox } from "@fluxy-chat/react";

function InboxSidebar() {
  const { items, counter, unseen, status, reload, onItem } = useInbox({
    pollIntervalMs: 30_000,
    realtime: true,
    onItem: (item) => console.log("live inbox push", item),
  });

  return (
    <div>
      <h2>Inbox {counter > 0 ? `(${counter})` : ""}</h2>
      {status === "loading" && <p>Loading…</p>}
      <ul>
        {items.map((item) => (
          <li key={item.id}>
            <a href={`/rooms/${item.roomId}`}>
              [{item.kind}] {item.roomName ?? item.roomId}
              {item.unreadCount != null ? ` · ${item.unreadCount} unread` : ""}
            </a>
          </li>
        ))}
      </ul>
    </div>
  );
}

Item kinds

Each row in items is a FluxyInboxItem:

kindSource in REST summaryTypical use
mentionsummary.mentions@you in a room
unreadsummary.unreadRoomsRoom has messages after your watermark
snoozesummary.snoozedRoomsRoom hidden until snoozedUntil
follow_upsummary.followUpsOperator reminder you created

Items are built from GET /inbox and merged with realtime pushes on the user channel WebSocket (onItem).

Counter vs unseen

  • countersummary.counts.unreadRooms (or length of unread room list). Use for nav badges.
  • unseen — count of mention + unread rows in the current items feed (respects client query filter).
useInbox({ query: { unread: true } }); // narrows REST snapshot client-side

Mark read (room channel)

Marking a room read advances the channel watermark, not the inbox snooze state:

await client.markReadRest(roomId, messageId);
await reload(); // refresh inbox summary

In chat UI, useChat({ readOn: "mount" }) or markReadLatest: true sends read receipts when the user opens a room.

REST

MethodPathDescription
GET/inboxInbox summary (mentions, unread, snoozed, follow-ups, counts)
POST/inbox/rooms/:roomId/snoozeSnooze a room
POST/inbox/follow-upsSchedule follow-up
POST/rooms/:roomId/readAdvance read watermark { messageId }

Requires authenticated member JWT (same as chat).

Realtime

When realtime: true (default when authenticated), useInbox subscribes to the user channel. Server pushes inbox_item events; the hook merges them into items and calls onItem once per new row.

Console

The dashboard Inbox page (/inbox) shows the items feed, sidebar badge via useInbox().counter, live onItem banner, and Mark read on unread rows.

On this page