From e4cfade7be4efae1f835257633372d15d7816c05 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Mon, 1 Jul 2024 12:23:57 -0700 Subject: [PATCH] Expose group description bindings (#883) * first pass at exposing description bindings * add more bindings * fix up some test * fix node lint --- bindings_ffi/src/mls.rs | 33 +++++++++++++++ bindings_node/src/conversations.rs | 3 ++ xmtp_mls/src/groups/group_mutable_metadata.rs | 3 +- xmtp_mls/src/groups/intents.rs | 7 ++++ xmtp_mls/src/groups/mod.rs | 41 +++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/bindings_ffi/src/mls.rs b/bindings_ffi/src/mls.rs index 68d89996b..174614936 100644 --- a/bindings_ffi/src/mls.rs +++ b/bindings_ffi/src/mls.rs @@ -638,6 +638,7 @@ pub struct FfiCreateGroupOptions { pub permissions: Option, pub group_name: Option, pub group_image_url_square: Option, + pub group_description: Option, } impl FfiCreateGroupOptions { @@ -645,6 +646,7 @@ impl FfiCreateGroupOptions { GroupMetadataOptions { name: self.group_name, image_url_square: self.group_image_url_square, + description: self.group_description, } } } @@ -866,6 +868,35 @@ impl FfiGroup { Ok(group_image_url_square) } + pub async fn update_group_description( + &self, + group_description: String, + ) -> Result<(), GenericError> { + let group = MlsGroup::new( + self.inner_client.context().clone(), + self.group_id.clone(), + self.created_at_ns, + ); + + group + .update_group_description(&self.inner_client, group_description) + .await?; + + Ok(()) + } + + pub fn group_description(&self) -> Result { + let group = MlsGroup::new( + self.inner_client.context().clone(), + self.group_id.clone(), + self.created_at_ns, + ); + + let group_description = group.group_description()?; + + Ok(group_description) + } + pub fn admin_list(&self) -> Result, GenericError> { let group = MlsGroup::new( self.inner_client.context().clone(), @@ -1538,6 +1569,7 @@ mod tests { permissions: Some(FfiGroupPermissionsOptions::AdminOnly), group_name: Some("Group Name".to_string()), group_image_url_square: Some("url".to_string()), + group_description: Some("group description".to_string()), }, ) .await @@ -1547,6 +1579,7 @@ mod tests { assert_eq!(members.len(), 2); assert_eq!(group.group_name().unwrap(), "Group Name"); assert_eq!(group.group_image_url_square().unwrap(), "url"); + assert_eq!(group.group_description().unwrap(), "group description"); } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] diff --git a/bindings_node/src/conversations.rs b/bindings_node/src/conversations.rs index a57cb09e3..298a6e21e 100644 --- a/bindings_node/src/conversations.rs +++ b/bindings_node/src/conversations.rs @@ -27,6 +27,7 @@ pub struct NapiCreateGroupOptions { pub permissions: Option, pub group_name: Option, pub group_image_url_square: Option, + pub group_description: Option, } impl NapiCreateGroupOptions { @@ -34,6 +35,7 @@ impl NapiCreateGroupOptions { GroupMetadataOptions { name: self.group_name, image_url_square: self.group_image_url_square, + description: self.group_description, } } } @@ -61,6 +63,7 @@ impl NapiConversations { permissions: None, group_name: None, group_image_url_square: None, + group_description: None, }, }; diff --git a/xmtp_mls/src/groups/group_mutable_metadata.rs b/xmtp_mls/src/groups/group_mutable_metadata.rs index 41e4e67b7..fa706cb1b 100644 --- a/xmtp_mls/src/groups/group_mutable_metadata.rs +++ b/xmtp_mls/src/groups/group_mutable_metadata.rs @@ -89,7 +89,8 @@ impl GroupMutableMetadata { ); attributes.insert( MetadataField::Description.to_string(), - DEFAULT_GROUP_DESCRIPTION.to_string(), + opts.description + .unwrap_or_else(|| DEFAULT_GROUP_DESCRIPTION.to_string()), ); attributes.insert( MetadataField::GroupImageUrlSquare.to_string(), diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index 832622c42..15f61c044 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -174,6 +174,13 @@ impl UpdateMetadataIntentData { field_value: group_image_url_square, } } + + pub fn new_update_group_description(group_description: String) -> Self { + Self { + field_name: MetadataField::Description.to_string(), + field_value: group_description, + } + } } impl From for Vec { diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index 5c510ae19..b70aec2d2 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -208,6 +208,7 @@ pub struct MlsGroup { pub struct GroupMetadataOptions { pub name: Option, pub image_url_square: Option, + pub description: Option, } impl Clone for MlsGroup { @@ -666,6 +667,40 @@ impl MlsGroup { } } + pub async fn update_group_description( + &self, + client: &Client, + group_description: String, + ) -> Result<(), GroupError> + where + ApiClient: XmtpApi, + { + let conn = self.context.store.conn()?; + let intent_data: Vec = + UpdateMetadataIntentData::new_update_group_description(group_description).into(); + let intent = conn.insert_group_intent(NewGroupIntent::new( + IntentKind::MetadataUpdate, + self.group_id.clone(), + intent_data, + ))?; + + self.sync_until_intent_resolved(conn, intent.id, client) + .await + } + + pub fn group_description(&self) -> Result { + let mutable_metadata = self.mutable_metadata()?; + match mutable_metadata + .attributes + .get(&MetadataField::Description.to_string()) + { + Some(group_description) => Ok(group_description.clone()), + None => Err(GroupError::GroupMutableMetadata( + GroupMutableMetadataError::MissingExtension, + )), + } + } + pub async fn update_group_image_url_square( &self, client: &Client, @@ -1749,6 +1784,7 @@ mod tests { GroupMetadataOptions { name: Some("Group Name".to_string()), image_url_square: Some("url".to_string()), + description: Some("group description".to_string()), }, ) .unwrap(); @@ -1762,9 +1798,14 @@ mod tests { .attributes .get(&MetadataField::GroupImageUrlSquare.to_string()) .unwrap(); + let amal_group_description: &String = binding + .attributes + .get(&MetadataField::Description.to_string()) + .unwrap(); assert_eq!(amal_group_name, "Group Name"); assert_eq!(amal_group_image_url, "url"); + assert_eq!(amal_group_description, "group description"); } #[tokio::test(flavor = "multi_thread", worker_threads = 1)]