diff --git a/bin/chat-cli/README.md b/bin/chat-cli/README.md index 7c8827d..9848b4c 100644 --- a/bin/chat-cli/README.md +++ b/bin/chat-cli/README.md @@ -70,7 +70,8 @@ and copies it to the clipboard. required; addresses can follow (e.g. Pax's) to invite people at creation. 2. Saro types `/add ` to invite Raya; the invite stays pending until the group commits it. -3. Once the invite commits, everyone can chat. +3. `/members` lists the roster — Raya shows `(pending)` until the commit lands, + then appears without it. Once committed, both can chat. ### Optional: KeyPackage registry @@ -115,6 +116,7 @@ The registry is a throwaway testnet helper; v0.3 replaces it with a | `/dm
` | Start a direct (1:1) chat | | `/new [address...]` | Create a named group chat (optionally inviting members) | | `/add
` | Add someone to the active group | +| `/members` | List members of the active conversation | | `/chats` | List all established chats | | `/switch ` | Switch active chat | | `/delete ` | Delete a chat session | diff --git a/bin/chat-cli/src/app.rs b/bin/chat-cli/src/app.rs index 60adb1e..cebdefd 100644 --- a/bin/chat-cli/src/app.rs +++ b/bin/chat-cli/src/app.rs @@ -325,6 +325,7 @@ where self.add_system_message("/dm
- Start a direct (1:1) chat"); self.add_system_message("/new [address...] - Create a group chat"); self.add_system_message("/add
- Add someone to the active group"); + self.add_system_message("/members - List members of the active conversation"); self.add_system_message("/nickname - Name the active chat"); self.add_system_message("/chats - List all chats"); self.add_system_message("/switch - Switch active chat"); @@ -436,6 +437,36 @@ where self.status = "Invite pending — the group will commit it shortly.".to_string(); Ok(Some("Invite pending".to_string())) } + "/members" => { + let chat_id = self + .state + .active_chat + .clone() + .ok_or_else(|| anyhow::anyhow!("No active conversation."))?; + let members = self + .client + .group_members(&chat_id) + .map_err(|e| anyhow::anyhow!("{e:?}"))?; + let my_addr = self.client.addr().to_string(); + self.add_system_message(&format!("── Members ({}) ──", members.len())); + for m in &members { + let id = m + .account + .as_ref() + .map(|a| a.as_str()) + .unwrap_or_else(|| m.local_identity.as_str()); + let short = &id[..16.min(id.len())]; + let mut tags = String::new(); + if m.account.as_ref().map(|a| a.as_str()) == Some(my_addr.as_str()) { + tags.push_str(" (you)"); + } + if m.pending { + tags.push_str(" (pending)"); + } + self.add_system_message(&format!(" • {short}…{tags}")); + } + Ok(Some(format!("{} member(s)", members.len()))) + } "/nickname" => { if args.is_empty() { return Ok(Some("Usage: /nickname ".to_string()));