Chat
A real-time messaging interface that supports sending and receiving messages over MeshSocket. Ideal for device-to-device communication, command logs, or interactive chatbots.
Type
"chat"
Relevant Fields
Inherits all Control Definition. Key fields:
| Field | Type | Default | Description |
|---|---|---|---|
label |
string | falls back to id |
Header label |
config.target |
string | — | MeshSocket peer name to route messages to. Set this for companion/bot chat; omit for channel chat |
config.showTypingIndicators |
bool | true |
Show typing bubbles |
config.showReadReceipts |
bool | true |
Show read receipts |
config.allowReactions |
bool | true |
Allow emoji reactions on messages |
config.allowReplies |
bool | true |
Allow threaded replies |
config.allowImages |
bool | false |
Allow image attachments |
config.allowClear |
bool | true |
Show the local Clear Chat control in the header. Server-driven chat_clear frames are honored regardless of this flag |
config.historyCount |
number | 50 |
Number of messages to keep in history |
config.tint |
string | "#667eea" |
Chat bubble accent color |
Message actions (long-press)
Long-press any message bubble for an iMessage-style menu: Copy (the message text),
Reply (when allowReplies), React (emoji, when allowReactions), and Delete
(removes it from this device's window only). The old tap-to-reveal reaction bar is gone —
reactions now live in this menu.
Clearing the window
Two independent ways to wipe the log:
- Local — the header's Clear Chat menu (shown when
config.allowClearis true, the default) empties this device's window only. It does not notify peers. - Server-driven — the channel/companion authority clears every member's window by
emitting a
chat_clearframe. In channel mode it rides the sharedbroadcastmultiplexer like every other chat frame; in companion (config.target) mode it arrives as a broadcast:
json
// channel mode
"broadcast_request": { "msg_type": "chat_clear", "chatId": "team-chat" }
// companion mode
"broadcast": { "event": "chat_clear" }
An absent chatId clears every chat control on the channel; a present one targets just
that control's id. chat_clear is wire API — never rename it.
Examples
Device-to-device chat
{
"type": "chat",
"id": "team-chat",
"position": [0, 0],
"span": [4, 4],
"label": "Team Chat",
"config": {
"target": "hub-server",
"showTypingIndicators": true,
"showReadReceipts": true,
"allowReactions": true,
"allowReplies": true,
"historyCount": 100
}
}
Wire Protocol
When config.target is set, the chat routes to that peer by name (companion mode):
Outgoing — every message you send:
"route_msg_noreply": {
"target_name": "companion",
"type": "chat_message",
"payload": { "text": "your message" }
}
Incoming — the companion replies with a broadcast the chat listens for:
"broadcast": { "event": "chat_response", "text": "the reply" }
The optional name / sender.name / from field on the broadcast sets the reply's display name; otherwise it falls back to the target name.
The companion (server side) must wait for the MeshSocket welcome before routing — connect,
wait_until_ready(), then wait for the welcome event before sending.
Without config.target (channel mode) the chat sends a chat_message event and listens on chat_message for the whole channel.
Related
- Control Definition — Base fields
- Sync — Real-time data sync