One shared room where every member talks together, at /chatroom.

What it does

  • A single live room: every member reads and writes the same stream. Day separators, messages grouped by author for five minutes, and a compact composer at the bottom.
  • Live updates: when [TabRe Socket](../tabre_socket/) is running, new messages and deletions arrive through the public chat / chat_delete events and appear without a reload. The header pill shows Live while the socket is open and Auto-refresh when the room falls back to a 9-second catch-up poll. The poll also runs after the tab was hidden, and when the network comes back.
  • History: the newest 60 messages load first; Load older messages fetches earlier pages without moving the scroll position.
  • Send: Enter sends, Shift+Enter adds a line, IME composition is respected, and mobile keyboards keep Enter as a newline (the send button is the way). Markdown is rendered safely on the server.
  • Delete: a member can delete their own message, moderators any message; a second click confirms (Delete?). Deletions propagate live.
  • Guests see a sign-in card instead of the room. Groups without the reply permission read but cannot post.
  • Left menu entry under Community with a hash icon; it is active on /chatroom.

Settings (Admin → Plugins → TabRe Chat Room)

SettingDefaultMeaning
Longest message (characters)500100–2000
Seconds between two messages2Per member; 0 = off
Messages per minute20Per member; 0 = no limit
Messages kept500Older rows are pruned as the room fills

Data and endpoints

One table, dropped on uninstall: plugin_tabre_chatroom_msg (id, user_id, body, created_at).

RoutePurpose
/chatroomthe room (or the sign-in card for a guest)
/chatroom/feedJSON: latest page, ?after={id} for live catch-up, ?before={id} for older
/chatroom/sendPOST: store one message, answer with the escaped row HTML
/chatroom/deletePOST: remove one message the member or a moderator owns

Pruning runs on every 25th insert and hourly from cron (prune). The room keeps the newest keep_messages rows.

Without JavaScript

The page is a normal server-rendered stream; the composer is a real form with a CSRF field and posts to /chatroom/send, then redirects back. Delete buttons are forms too. Live updates and the jump pill are additions on top.

Notes for plugin authors

The room listens to the tabre-socket DOM event documented in the socket plugin's README:

document.addEventListener('tabre-socket', function (e) {
  if (e.detail.kind === 'chat') { /* post_id is the message id */ }
  if (e.detail.kind === 'chat_delete') { /* post_id was removed */ }
});