@@ -5,16 +5,19 @@ use wasm_bindgen::{JsError, JsValue};
5
5
use xmtp_mls:: groups:: {
6
6
DMMetadataOptions , GroupMetadataOptions , HmacKey as XmtpHmacKey , PreconfiguredPolicies ,
7
7
} ;
8
+ use xmtp_mls:: storage:: consent_record:: ConsentState as XmtpConsentState ;
8
9
use xmtp_mls:: storage:: group:: ConversationType as XmtpConversationType ;
9
10
use xmtp_mls:: storage:: group:: GroupMembershipState as XmtpGroupMembershipState ;
10
11
use xmtp_mls:: storage:: group:: GroupQueryArgs ;
11
12
12
- use crate :: conversation :: MessageDisappearingSettings ;
13
+ use crate :: consent_state :: ConsentState ;
13
14
use crate :: messages:: Message ;
14
15
use crate :: permissions:: { GroupPermissionsOptions , PermissionPolicySet } ;
15
16
use crate :: streams:: { StreamCallback , StreamCloser } ;
16
17
use crate :: { client:: RustXmtpClient , conversation:: Conversation } ;
17
18
19
+ use xmtp_mls:: groups:: group_mutable_metadata:: MessageDisappearingSettings as XmtpMessageDisappearingSettings ;
20
+
18
21
#[ wasm_bindgen]
19
22
#[ derive( Debug , Clone ) ]
20
23
pub enum ConversationType {
@@ -76,50 +79,91 @@ impl From<GroupMembershipState> for XmtpGroupMembershipState {
76
79
pub struct ListConversationsOptions {
77
80
#[ wasm_bindgen( js_name = allowedStates) ]
78
81
pub allowed_states : Option < Vec < GroupMembershipState > > ,
82
+ #[ wasm_bindgen( js_name = consentStates) ]
83
+ pub consent_states : Option < Vec < ConsentState > > ,
79
84
#[ wasm_bindgen( js_name = conversationType) ]
80
85
pub conversation_type : Option < ConversationType > ,
81
86
#[ wasm_bindgen( js_name = createdAfterNs) ]
82
87
pub created_after_ns : Option < i64 > ,
83
88
#[ wasm_bindgen( js_name = createdBeforeNs) ]
84
89
pub created_before_ns : Option < i64 > ,
90
+ #[ wasm_bindgen( js_name = includeDuplicateDms) ]
91
+ pub include_duplicate_dms : bool ,
92
+ #[ wasm_bindgen( js_name = includeSyncGroups) ]
93
+ pub include_sync_groups : bool ,
85
94
pub limit : Option < i64 > ,
86
95
}
87
96
88
97
impl From < ListConversationsOptions > for GroupQueryArgs {
89
98
fn from ( opts : ListConversationsOptions ) -> GroupQueryArgs {
90
- GroupQueryArgs :: default ( )
91
- . maybe_allowed_states (
92
- opts
93
- . allowed_states
94
- . map ( |states| states. into_iter ( ) . map ( From :: from) . collect ( ) ) ,
95
- )
96
- . maybe_conversation_type ( opts. conversation_type . map ( Into :: into) )
97
- . maybe_created_after_ns ( opts. created_after_ns )
98
- . maybe_created_before_ns ( opts. created_before_ns )
99
- . maybe_limit ( opts. limit )
99
+ GroupQueryArgs {
100
+ allowed_states : opts
101
+ . allowed_states
102
+ . map ( |states| states. into_iter ( ) . map ( From :: from) . collect ( ) ) ,
103
+ consent_states : opts
104
+ . consent_states
105
+ . map ( |states| states. into_iter ( ) . map ( From :: from) . collect ( ) ) ,
106
+ conversation_type : opts. conversation_type . map ( Into :: into) ,
107
+ created_after_ns : opts. created_after_ns ,
108
+ created_before_ns : opts. created_before_ns ,
109
+ include_duplicate_dms : opts. include_duplicate_dms ,
110
+ include_sync_groups : opts. include_sync_groups ,
111
+ limit : opts. limit ,
112
+ }
100
113
}
101
114
}
102
115
103
116
#[ wasm_bindgen]
104
117
impl ListConversationsOptions {
105
118
#[ wasm_bindgen( constructor) ]
119
+ #[ allow( clippy:: too_many_arguments) ]
106
120
pub fn new (
107
121
allowed_states : Option < Vec < GroupMembershipState > > ,
122
+ consent_states : Option < Vec < ConsentState > > ,
108
123
conversation_type : Option < ConversationType > ,
109
124
created_after_ns : Option < i64 > ,
110
125
created_before_ns : Option < i64 > ,
126
+ include_duplicate_dms : bool ,
127
+ include_sync_groups : bool ,
111
128
limit : Option < i64 > ,
112
129
) -> Self {
113
130
Self {
114
131
allowed_states,
132
+ consent_states,
115
133
conversation_type,
116
134
created_after_ns,
117
135
created_before_ns,
136
+ include_duplicate_dms,
137
+ include_sync_groups,
118
138
limit,
119
139
}
120
140
}
121
141
}
122
142
143
+ #[ wasm_bindgen( getter_with_clone) ]
144
+ #[ derive( Clone ) ]
145
+ pub struct MessageDisappearingSettings {
146
+ pub from_ns : i64 ,
147
+ pub in_ns : i64 ,
148
+ }
149
+
150
+ impl From < MessageDisappearingSettings > for XmtpMessageDisappearingSettings {
151
+ fn from ( value : MessageDisappearingSettings ) -> Self {
152
+ Self {
153
+ from_ns : value. from_ns ,
154
+ in_ns : value. in_ns ,
155
+ }
156
+ }
157
+ }
158
+
159
+ #[ wasm_bindgen]
160
+ impl MessageDisappearingSettings {
161
+ #[ wasm_bindgen( constructor) ]
162
+ pub fn new ( from_ns : i64 , in_ns : i64 ) -> Self {
163
+ Self { from_ns, in_ns }
164
+ }
165
+ }
166
+
123
167
#[ wasm_bindgen( getter_with_clone) ]
124
168
#[ derive( Clone ) ]
125
169
pub struct CreateGroupOptions {
@@ -216,6 +260,24 @@ impl From<XmtpHmacKey> for HmacKey {
216
260
}
217
261
}
218
262
263
+ #[ wasm_bindgen( getter_with_clone) ]
264
+ pub struct ConversationListItem {
265
+ pub conversation : Conversation ,
266
+ #[ wasm_bindgen( js_name = lastMessage) ]
267
+ pub last_message : Option < Message > ,
268
+ }
269
+
270
+ #[ wasm_bindgen]
271
+ impl ConversationListItem {
272
+ #[ wasm_bindgen( constructor) ]
273
+ pub fn new ( conversation : Conversation , last_message : Option < Message > ) -> Self {
274
+ Self {
275
+ conversation,
276
+ last_message,
277
+ }
278
+ }
279
+ }
280
+
219
281
#[ wasm_bindgen]
220
282
pub struct Conversations {
221
283
inner_client : Arc < RustXmtpClient > ,
@@ -296,6 +358,73 @@ impl Conversations {
296
358
Ok ( convo. into ( ) )
297
359
}
298
360
361
+ #[ wasm_bindgen( js_name = createGroupByInboxIds) ]
362
+ pub async fn create_group_by_inbox_ids (
363
+ & self ,
364
+ inbox_ids : Vec < String > ,
365
+ options : Option < CreateGroupOptions > ,
366
+ ) -> Result < Conversation , JsError > {
367
+ let options = options. unwrap_or ( CreateGroupOptions {
368
+ permissions : None ,
369
+ group_name : None ,
370
+ group_image_url_square : None ,
371
+ group_description : None ,
372
+ custom_permission_policy_set : None ,
373
+ message_disappearing_settings : None ,
374
+ } ) ;
375
+
376
+ if let Some ( GroupPermissionsOptions :: CustomPolicy ) = options. permissions {
377
+ if options. custom_permission_policy_set . is_none ( ) {
378
+ return Err ( JsError :: new ( "CustomPolicy must include policy set" ) ) ;
379
+ }
380
+ } else if options. custom_permission_policy_set . is_some ( ) {
381
+ return Err ( JsError :: new ( "Only CustomPolicy may specify a policy set" ) ) ;
382
+ }
383
+
384
+ let metadata_options = options. clone ( ) . into_group_metadata_options ( ) ;
385
+
386
+ let group_permissions = match options. permissions {
387
+ Some ( GroupPermissionsOptions :: Default ) => {
388
+ Some ( PreconfiguredPolicies :: Default . to_policy_set ( ) )
389
+ }
390
+ Some ( GroupPermissionsOptions :: AdminOnly ) => {
391
+ Some ( PreconfiguredPolicies :: AdminsOnly . to_policy_set ( ) )
392
+ }
393
+ Some ( GroupPermissionsOptions :: CustomPolicy ) => {
394
+ if let Some ( policy_set) = options. custom_permission_policy_set {
395
+ Some (
396
+ policy_set
397
+ . try_into ( )
398
+ . map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?,
399
+ )
400
+ } else {
401
+ None
402
+ }
403
+ }
404
+ _ => None ,
405
+ } ;
406
+
407
+ let convo = if inbox_ids. is_empty ( ) {
408
+ let group = self
409
+ . inner_client
410
+ . create_group ( group_permissions, metadata_options)
411
+ . map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?;
412
+ group
413
+ . sync ( )
414
+ . await
415
+ . map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?;
416
+ group
417
+ } else {
418
+ self
419
+ . inner_client
420
+ . create_group_with_inbox_ids ( & inbox_ids, group_permissions, metadata_options)
421
+ . await
422
+ . map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?
423
+ } ;
424
+
425
+ Ok ( convo. into ( ) )
426
+ }
427
+
299
428
#[ wasm_bindgen( js_name = createDm) ]
300
429
pub async fn find_or_create_dm (
301
430
& self ,
@@ -314,6 +443,24 @@ impl Conversations {
314
443
Ok ( convo. into ( ) )
315
444
}
316
445
446
+ #[ wasm_bindgen( js_name = createDmByInboxId) ]
447
+ pub async fn find_or_create_dm_by_inbox_id (
448
+ & self ,
449
+ inbox_id : String ,
450
+ options : Option < CreateDMOptions > ,
451
+ ) -> Result < Conversation , JsError > {
452
+ let convo = self
453
+ . inner_client
454
+ . find_or_create_dm_by_inbox_id (
455
+ inbox_id,
456
+ options. unwrap_or_default ( ) . into_dm_metadata_options ( ) ,
457
+ )
458
+ . await
459
+ . map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?;
460
+
461
+ Ok ( convo. into ( ) )
462
+ }
463
+
317
464
#[ wasm_bindgen( js_name = findGroupById) ]
318
465
pub fn find_group_by_id ( & self , group_id : String ) -> Result < Conversation , JsError > {
319
466
let group_id = hex:: decode ( group_id) . map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?;
@@ -368,15 +515,20 @@ impl Conversations {
368
515
}
369
516
370
517
#[ wasm_bindgen( js_name = syncAllConversations) ]
371
- pub async fn sync_all_conversations ( & self ) -> Result < usize , JsError > {
518
+ pub async fn sync_all_conversations (
519
+ & self ,
520
+ consent_states : Option < Vec < ConsentState > > ,
521
+ ) -> Result < usize , JsError > {
372
522
let provider = self
373
523
. inner_client
374
524
. mls_provider ( )
375
525
. map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?;
526
+ let consents: Option < Vec < XmtpConsentState > > =
527
+ consent_states. map ( |states| states. into_iter ( ) . map ( |state| state. into ( ) ) . collect ( ) ) ;
376
528
377
529
let num_groups_synced = self
378
530
. inner_client
379
- . sync_all_welcomes_and_groups ( & provider, None )
531
+ . sync_all_welcomes_and_groups ( & provider, consents )
380
532
. await
381
533
. map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?;
382
534
@@ -387,14 +539,13 @@ impl Conversations {
387
539
pub fn list ( & self , opts : Option < ListConversationsOptions > ) -> Result < js_sys:: Array , JsError > {
388
540
let convo_list: js_sys:: Array = self
389
541
. inner_client
390
- . find_groups ( opts. unwrap_or_default ( ) . into ( ) )
542
+ . list_conversations ( opts. unwrap_or_default ( ) . into ( ) )
391
543
. map_err ( |e| JsError :: new ( format ! ( "{}" , e) . as_str ( ) ) ) ?
392
544
. into_iter ( )
393
545
. map ( |group| {
394
- JsValue :: from ( Conversation :: new (
395
- self . inner_client . clone ( ) ,
396
- group. group_id ,
397
- group. created_at_ns ,
546
+ JsValue :: from ( ConversationListItem :: new (
547
+ group. group . into ( ) ,
548
+ group. last_message . map ( |m| m. into ( ) ) ,
398
549
) )
399
550
} )
400
551
. collect ( ) ;
0 commit comments