feat(chat): right-click menus everywhere in the chat, and deleting your own message

Rail: a room — open, mark as read, mute / unmute notifications (per browser,
the unread count still shows), copy name, group settings, leave; the pet and
+ — chat with the pet, new chat, mark all chats as read. A message — copy
text, reply (quotes it into the box), message the sender privately (group),
delete your own (asks first). A file — open in a new tab, download, copy file
name. A group member — message privately, copy name, remove (the creator).

DELETE /api/chat/rooms/:id/messages/:messageId deletes the caller's OWN text
message and its files (403 for anyone else, an admin included) and tells the
members with a chat_deleted frame (exactAudience).
This commit is contained in:
2026-11-03 09:47:32 +07:00
parent 0d3e92cfda
commit 0016b6a427
15 changed files with 612 additions and 33 deletions
+2 -1
View File
@@ -3509,11 +3509,12 @@ PATCH /api/chat/rooms/:id {name?, add?, remove?} — the g
POST /api/chat/rooms/:id/leave Leave a group; the last one out deletes it and its files
GET /api/chat/rooms/:id/messages?before=&limit= {messages (oldest first), hasMore} — 50 by default, ≤ 200
POST /api/chat/rooms/:id/messages JSON {body} or multipart `body` + ≤ 10 `files` of ≤ 25 MB; body ≤ 8000 chars
DELETE /api/chat/rooms/:id/messages/:messageId Delete your OWN text message and its files (403 EFORBIDDEN otherwise, an admin included)
POST /api/chat/rooms/:id/read {upTo} — read mark, never moves back
GET /api/chat/rooms/:id/files/:fileId The file, members only, `sandbox` CSP + `nosniff`; PNG/JPEG/GIF/WebP inline, else attachment
```
Files are stored under `<data dir>/chat/<room id>/<32 hex id>` — a name the server makes. A group change adds a `system` message (`created`, `renamed`, `left`, `added:<ids>`, `removed:<ids>`). Every change is sent over `/ws` as `chat_message` (`{roomId, message, to}`) or `chat_room` (`{roomId, to}`) to exactly the user ids in `to` (`scope.exactAudience`), whatever their role.
Files are stored under `<data dir>/chat/<room id>/<32 hex id>` — a name the server makes. Right-click menus in the window: a room (open, mark read, mute notifications — per browser —, copy name, group settings, leave), the rail's pet and **+** (mark all read), a message (copy text, reply, message the sender privately, delete your own), a file (open, download, copy name) and a group member (message privately, remove — the creator). A group change adds a `system` message (`created`, `renamed`, `left`, `added:<ids>`, `removed:<ids>`). Every change is sent over `/ws` as `chat_message` (`{roomId, message, to}`), `chat_room` (`{roomId, to}`) or `chat_deleted` (`{roomId, messageId, to}`) to exactly the user ids in `to` (`scope.exactAudience`), whatever their role.
### Session snapshots