mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-08-26 15:41:13 +00:00
feat: add chat-cli /add (#208)
This commit is contained in:
@@ -66,9 +66,11 @@ and copies it to the clipboard.
|
||||
|
||||
**Group:**
|
||||
|
||||
1. Saro types `/new weekend <raya's address>` to create a group named "weekend"
|
||||
and invite Raya. A name is required; more addresses (e.g. Pax's) can follow.
|
||||
2. Once the invite commits, everyone can chat.
|
||||
1. Saro types `/new weekend` to create a group named "weekend". A name is
|
||||
required; addresses can follow (e.g. Pax's) to invite people at creation.
|
||||
2. Saro types `/add <raya's address>` to invite Raya; the invite stays pending
|
||||
until the group commits it.
|
||||
3. Once the invite commits, everyone can chat.
|
||||
|
||||
### Optional: KeyPackage registry
|
||||
|
||||
@@ -112,6 +114,7 @@ The registry is a throwaway testnet helper; v0.3 replaces it with a
|
||||
| `/account` | Show your account address (copies to clipboard) |
|
||||
| `/dm <address>` | Start a direct (1:1) chat |
|
||||
| `/new <name> [address...]` | Create a named group chat (optionally inviting members) |
|
||||
| `/add <address>` | Add someone to the active group |
|
||||
| `/chats` | List all established chats |
|
||||
| `/switch <user>` | Switch active chat |
|
||||
| `/delete <user>` | Delete a chat session |
|
||||
|
||||
@@ -272,6 +272,12 @@ where
|
||||
session.display_name()
|
||||
);
|
||||
}
|
||||
Event::ConversationMembersChanged { convo_id } => {
|
||||
let chat_id = convo_id.to_string();
|
||||
if let Some(session) = self.state.chats.get(&chat_id) {
|
||||
self.status = format!("Membership changed in {}.", session.display_name());
|
||||
}
|
||||
}
|
||||
Event::InboundError { message } => {
|
||||
self.status = format!("Could not process incoming message: {message}");
|
||||
}
|
||||
@@ -318,6 +324,7 @@ where
|
||||
self.add_system_message("/account - Show your account address");
|
||||
self.add_system_message("/dm <address> - Start a direct (1:1) chat");
|
||||
self.add_system_message("/new <name> [address...] - Create a group chat");
|
||||
self.add_system_message("/add <address> - Add someone to the active group");
|
||||
self.add_system_message("/nickname <name> - Name the active chat");
|
||||
self.add_system_message("/chats - List all chats");
|
||||
self.add_system_message("/switch <name|id> - Switch active chat");
|
||||
@@ -385,6 +392,50 @@ where
|
||||
self.status = msg.clone();
|
||||
Ok(Some(msg))
|
||||
}
|
||||
"/add" => {
|
||||
let address = args.trim();
|
||||
if address.is_empty() {
|
||||
return Ok(Some("Usage: /add <address>".to_string()));
|
||||
}
|
||||
let chat_id = self.state.active_chat.as_deref().ok_or_else(|| {
|
||||
anyhow::anyhow!("No active conversation. Use /new to create a group.")
|
||||
})?;
|
||||
// DMs are 1:1 and reject adds at the protocol level; refuse early
|
||||
// with a friendly hint rather than surfacing UnsupportedFunction.
|
||||
if self.state.chats.get(chat_id).map(|s| s.kind) == Some(ConversationClass::Dm) {
|
||||
return Ok(Some(
|
||||
"DMs are 1:1 — start a group with /new to add people.".to_string(),
|
||||
));
|
||||
}
|
||||
// Adding a signature key already in the group (yourself, or a
|
||||
// member/pending invite) makes MLS reject the commit with
|
||||
// DuplicateSignatureKey. Catch it here as a friendly no-op.
|
||||
if address == self.client.addr() {
|
||||
return Ok(Some(
|
||||
"That's your own address — you're already in the group.".to_string(),
|
||||
));
|
||||
}
|
||||
let already_present = self
|
||||
.client
|
||||
.group_members(chat_id)
|
||||
.map(|members| {
|
||||
members
|
||||
.iter()
|
||||
.any(|m| m.account.as_ref().map(|a| a.as_str()) == Some(address))
|
||||
})
|
||||
.unwrap_or(false);
|
||||
if already_present {
|
||||
return Ok(Some(
|
||||
"That account is already in the group (or its invite is pending)."
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
self.client
|
||||
.add_group_members(chat_id, &[address])
|
||||
.map_err(|e| anyhow::anyhow!("{e:?}"))?;
|
||||
self.status = "Invite pending — the group will commit it shortly.".to_string();
|
||||
Ok(Some("Invite pending".to_string()))
|
||||
}
|
||||
"/nickname" => {
|
||||
if args.is_empty() {
|
||||
return Ok(Some("Usage: /nickname <name>".to_string()));
|
||||
|
||||
Reference in New Issue
Block a user