add group management menu with metadata, invites, and members

This commit is contained in:
2026-09-30 17:10:27 +07:00
parent ce1cff83ff
commit 8c7c672675
7 changed files with 724 additions and 43 deletions
+11 -5
View File
@@ -302,17 +302,19 @@ Validation: same commands; manually delete a message, pin and unpin, leave and r
The remaining moderation surface, all through the calls the backend already exposes.
- **Edit metadata** — a dialog started from `group.metadata().cloned().unwrap_or_default()`:
name, about, picture, the flags. `children` is preserved as-is — `edit_metadata` re-emits
the full list, and a `9002` that drops one is rejected by the relay.
- **Edit metadata** — a dialog opened from the panel header's `Manage` menu, started from
`group.metadata().cloned().unwrap_or_default()`: name, about, picture, the flags. `children`
is preserved as-is — `edit_metadata` re-emits the full list, and a `9002` that drops one is
rejected by the relay.
- **Invite** — `create_invite(code, cx)` with an input or generated code, then
`metadata.naddr(relay, Some(code))` copied to the clipboard (`naddr` needs parsed metadata;
a group whose relay publishes no `39000` cannot mint a link).
- **Users and roles** — add by `npub` → `put_user(pubkey, roles, cx)`, remove →
`remove_user(pubkey, cx)`; role choices come from `Group::roles()`. The relay is the
authority for both the roles it supports and who may call these.
- **React** — the row menu sends `send_reaction(target, emoji, cx)`; a kind `7` row appears
inline (that is the current backend behaviour).
- **React** — a `React` submenu in the same row menu sends `send_reaction(target, emoji, cx)`;
a kind `7` row appears inline (that is the current backend behaviour). Unlike the items above
it is not admin-only, so the menu now exists for every member.
Validation: same commands; manually exercise each write against a relay that grants the
account admin, and confirm the refusal path shows the relay's message.
@@ -376,3 +378,7 @@ this repo; `coop_web` check is the proxy.
- The fork banner's button joins the target group rather than opening it: the panel holds no
dock handle and the plan's call is `join_key` alone; the joined group then appears in the
sidebar.
- The admin writes sit behind a `Manage` menu in the panel header, shown only while the current
user is in `Group::admins()`; the details dialog stays read-only. The message row menu is now
built for every member — `React` is not moderation — and only its `Pin`/`Delete` items are
gated on being an admin.
+6 -4
View File
@@ -569,12 +569,14 @@ before they reach the consumer, so a replay cannot double-hydrate.
## Not wired up yet
- **Administration is partly built.** The sidebar's `Groups` tab lists
- **Administration is built on the client side.** The sidebar's `Groups` tab lists
`GroupsRegistry::groups()`, opens a `GroupPanel`, and offers the new-group and
join dialogs; `crates/workspace/src/panels/browse.rs` browses a relay and joins
from a result. The panel now has a read-only details dialog, message delete and
pin/unpin for admins, a pins strip, a fork banner, and leave. Editing metadata,
invites, and adding or removing users and roles are still to be built.
from a result. The panel has a read-only details dialog, a header `Manage` menu
(edit metadata, invite link, members and roles) shown to admins, a message menu
with reactions and admin pin/delete, a pins strip, a fork banner, and leave.
What a given account may actually do is the relay's call; the client shows the
refusal verbatim.
- **Remote deletions are not folded in.** A `9005` from another admin never reaches the
standing REQ, so only our own accepted deletes evict the row.
- **The LiveKit response shape is a guess.** The NIP names no fields, so