@@ -19,6 +19,7 @@ mod integration;
19
19
mod maps_integration;
20
20
21
21
use std:: cmp:: max;
22
+ use std:: collections:: HashMap ;
22
23
use std:: path:: Path ;
23
24
24
25
use anyhow:: { anyhow, bail, ensure, format_err, Context as _, Result } ;
@@ -202,7 +203,7 @@ pub struct StatusUpdateItem {
202
203
203
204
/// Array of other users `selfAddr` that should be notified about this update.
204
205
#[ serde( skip_serializing_if = "Option::is_none" ) ]
205
- pub notify : Option < Vec < String > > ,
206
+ pub notify : Option < HashMap < String , String > > ,
206
207
}
207
208
208
209
/// Update items as passed to the UIs.
@@ -336,7 +337,6 @@ impl Context {
336
337
} ;
337
338
338
339
let mut notify_msg_id = instance. id ;
339
- let mut notify_text = "" . to_string ( ) ;
340
340
let mut param_changed = false ;
341
341
342
342
let mut instance = instance. clone ( ) ;
@@ -358,7 +358,6 @@ impl Context {
358
358
let summary = sanitize_bidi_characters ( summary) ;
359
359
instance. param . set ( Param :: WebxdcSummary , summary. clone ( ) ) ;
360
360
param_changed = true ;
361
- notify_text = summary;
362
361
}
363
362
}
364
363
@@ -393,7 +392,6 @@ impl Context {
393
392
)
394
393
. await ?;
395
394
}
396
- notify_text = info. to_string ( ) ;
397
395
398
396
if let Some ( href) = status_update_item. href {
399
397
let mut notify_msg = Message :: load_from_db ( self , notify_msg_id) . await ?;
@@ -415,14 +413,20 @@ impl Context {
415
413
} ) ;
416
414
}
417
415
418
- if !notify_text . is_empty ( ) && from_id != ContactId :: SELF {
416
+ if from_id != ContactId :: SELF {
419
417
if let Some ( notify_list) = status_update_item. notify {
420
418
let self_addr = instance. get_webxdc_self_addr ( self ) . await ?;
421
- if notify_list. contains ( & self_addr) {
419
+ if let Some ( notify_text ) = notify_list. get ( & self_addr) {
422
420
self . emit_event ( EventType :: IncomingWebxdcNotify {
423
421
contact_id : from_id,
424
422
msg_id : notify_msg_id,
425
- text : notify_text,
423
+ text : notify_text. clone ( ) ,
424
+ } ) ;
425
+ } else if let Some ( notify_text) = notify_list. get ( "*" ) {
426
+ self . emit_event ( EventType :: IncomingWebxdcNotify {
427
+ contact_id : from_id,
428
+ msg_id : notify_msg_id,
429
+ text : notify_text. clone ( ) ,
426
430
} ) ;
427
431
}
428
432
}
@@ -2970,7 +2974,7 @@ sth_for_the = "future""#
2970
2974
. send_webxdc_status_update (
2971
2975
alice_instance. id ,
2972
2976
& format ! (
2973
- "{{\" payload\" :7,\" info\" : \" Alice moved\" ,\" notify\" :[ \" {}\" ] }}" ,
2977
+ "{{\" payload\" :7,\" info\" : \" Alice moved\" ,\" notify\" :{{ \" {}\" : \" Your move! \" }} }}" ,
2974
2978
bob_instance. get_webxdc_self_addr( & bob) . await ?
2975
2979
) ,
2976
2980
)
@@ -2979,17 +2983,20 @@ sth_for_the = "future""#
2979
2983
let sent2 = alice. pop_sent_msg ( ) . await ;
2980
2984
let info_msg = alice. get_last_msg ( ) . await ;
2981
2985
assert ! ( info_msg. is_info( ) ) ;
2982
- assert ! ( !has_incoming_webxdc_event( & alice, info_msg, "Alice moved" ) . await ) ;
2986
+ assert_eq ! ( info_msg. text, "Alice moved" ) ;
2987
+ assert ! ( !has_incoming_webxdc_event( & alice, info_msg, "" ) . await ) ;
2983
2988
2984
2989
bob. recv_msg_trash ( & sent2) . await ;
2985
2990
let info_msg = bob. get_last_msg ( ) . await ;
2986
2991
assert ! ( info_msg. is_info( ) ) ;
2987
- assert ! ( has_incoming_webxdc_event( & bob, info_msg, "Alice moved" ) . await ) ;
2992
+ assert_eq ! ( info_msg. text, "Alice moved" ) ;
2993
+ assert ! ( has_incoming_webxdc_event( & bob, info_msg, "Your move!" ) . await ) ;
2988
2994
2989
2995
fiona. recv_msg_trash ( & sent2) . await ;
2990
2996
let info_msg = fiona. get_last_msg ( ) . await ;
2991
2997
assert ! ( info_msg. is_info( ) ) ;
2992
- assert ! ( !has_incoming_webxdc_event( & fiona, info_msg, "Alice moved" ) . await ) ;
2998
+ assert_eq ! ( info_msg. text, "Alice moved" ) ;
2999
+ assert ! ( !has_incoming_webxdc_event( & fiona, info_msg, "" ) . await ) ;
2993
3000
2994
3001
Ok ( ( ) )
2995
3002
}
@@ -3013,7 +3020,7 @@ sth_for_the = "future""#
3013
3020
. send_webxdc_status_update (
3014
3021
alice_instance. id ,
3015
3022
& format ! (
3016
- "{{\" payload\" :7,\" info\" : \" moved\" , \" summary\" : \" ignored for notify as info is set \" , \" notify\" :[ \" {}\" , \" {}\" ] }}" ,
3023
+ "{{\" payload\" :7,\" info\" : \" moved\" , \" summary\" : \" move summary \" , \" notify\" :{{ \" {}\" : \" move, Bob \" , \" {}\" : \" move, Fiona \" }} }}" ,
3017
3024
bob_instance. get_webxdc_self_addr( & bob) . await ?,
3018
3025
fiona_instance. get_webxdc_self_addr( & fiona) . await ?
3019
3026
) ,
@@ -3024,17 +3031,17 @@ sth_for_the = "future""#
3024
3031
let sent2 = alice. pop_sent_msg ( ) . await ;
3025
3032
let info_msg = alice. get_last_msg ( ) . await ;
3026
3033
assert ! ( info_msg. is_info( ) ) ;
3027
- assert ! ( !has_incoming_webxdc_event( & alice, info_msg, "moved " ) . await ) ;
3034
+ assert ! ( !has_incoming_webxdc_event( & alice, info_msg, "" ) . await ) ;
3028
3035
3029
3036
bob. recv_msg_trash ( & sent2) . await ;
3030
3037
let info_msg = bob. get_last_msg ( ) . await ;
3031
3038
assert ! ( info_msg. is_info( ) ) ;
3032
- assert ! ( has_incoming_webxdc_event( & bob, info_msg, "moved " ) . await ) ;
3039
+ assert ! ( has_incoming_webxdc_event( & bob, info_msg, "move, Bob " ) . await ) ;
3033
3040
3034
3041
fiona. recv_msg_trash ( & sent2) . await ;
3035
3042
let info_msg = fiona. get_last_msg ( ) . await ;
3036
3043
assert ! ( info_msg. is_info( ) ) ;
3037
- assert ! ( has_incoming_webxdc_event( & fiona, info_msg, "moved " ) . await ) ;
3044
+ assert ! ( has_incoming_webxdc_event( & fiona, info_msg, "move, Fiona " ) . await ) ;
3038
3045
3039
3046
Ok ( ( ) )
3040
3047
}
@@ -3060,7 +3067,7 @@ sth_for_the = "future""#
3060
3067
. send_webxdc_status_update (
3061
3068
alice_instance. id ,
3062
3069
& format ! (
3063
- "{{\" payload\" :7,\" info\" : \" moved\" , \" notify\" :[ \" {}\" ] }}" ,
3070
+ "{{\" payload\" :7,\" info\" : \" moved\" , \" notify\" :{{ \" {}\" : \" bla \" }} }}" ,
3064
3071
alice2_instance. get_webxdc_self_addr( & alice2) . await ?
3065
3072
) ,
3066
3073
)
@@ -3069,44 +3076,120 @@ sth_for_the = "future""#
3069
3076
let sent2 = alice. pop_sent_msg ( ) . await ;
3070
3077
let info_msg = alice. get_last_msg ( ) . await ;
3071
3078
assert ! ( info_msg. is_info( ) ) ;
3072
- assert ! ( !has_incoming_webxdc_event( & alice, info_msg, "moved " ) . await ) ;
3079
+ assert ! ( !has_incoming_webxdc_event( & alice, info_msg, "" ) . await ) ;
3073
3080
3074
3081
alice2. recv_msg_trash ( & sent2) . await ;
3075
3082
let info_msg = alice2. get_last_msg ( ) . await ;
3076
3083
assert ! ( info_msg. is_info( ) ) ;
3077
- assert ! ( !has_incoming_webxdc_event( & alice2, info_msg, "moved " ) . await ) ;
3084
+ assert ! ( !has_incoming_webxdc_event( & alice2, info_msg, "" ) . await ) ;
3078
3085
3079
3086
Ok ( ( ) )
3080
3087
}
3081
3088
3082
3089
#[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
3083
- async fn test_webxdc_notify_summary ( ) -> Result < ( ) > {
3090
+ async fn test_webxdc_notify_all ( ) -> Result < ( ) > {
3084
3091
let mut tcm = TestContextManager :: new ( ) ;
3085
3092
let alice = tcm. alice ( ) . await ;
3086
3093
let bob = tcm. bob ( ) . await ;
3094
+ let fiona = tcm. fiona ( ) . await ;
3087
3095
3088
3096
let grp_id = alice
3089
- . create_group_with_members ( ProtectionStatus :: Unprotected , "grp" , & [ & bob] )
3097
+ . create_group_with_members ( ProtectionStatus :: Unprotected , "grp" , & [ & bob, & fiona] )
3098
+ . await ;
3099
+ let alice_instance = send_webxdc_instance ( & alice, grp_id) . await ?;
3100
+ let sent1 = alice. pop_sent_msg ( ) . await ;
3101
+ bob. recv_msg ( & sent1) . await ;
3102
+ fiona. recv_msg ( & sent1) . await ;
3103
+
3104
+ alice
3105
+ . send_webxdc_status_update (
3106
+ alice_instance. id ,
3107
+ "{\" payload\" :7,\" info\" : \" go\" , \" notify\" :{\" *\" :\" notify all\" } }" ,
3108
+ )
3109
+ . await ?;
3110
+ alice. flush_status_updates ( ) . await ?;
3111
+ let sent2 = alice. pop_sent_msg ( ) . await ;
3112
+ let info_msg = alice. get_last_msg ( ) . await ;
3113
+ assert_eq ! ( info_msg. text, "go" ) ;
3114
+ assert ! ( !has_incoming_webxdc_event( & alice, info_msg, "" ) . await ) ;
3115
+
3116
+ bob. recv_msg_trash ( & sent2) . await ;
3117
+ let info_msg = bob. get_last_msg ( ) . await ;
3118
+ assert_eq ! ( info_msg. text, "go" ) ;
3119
+ assert ! ( has_incoming_webxdc_event( & bob, info_msg, "notify all" ) . await ) ;
3120
+
3121
+ fiona. recv_msg_trash ( & sent2) . await ;
3122
+ let info_msg = fiona. get_last_msg ( ) . await ;
3123
+ assert_eq ! ( info_msg. text, "go" ) ;
3124
+ assert ! ( has_incoming_webxdc_event( & fiona, info_msg, "notify all" ) . await ) ;
3125
+
3126
+ Ok ( ( ) )
3127
+ }
3128
+
3129
+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
3130
+ async fn test_webxdc_notify_bob_and_all ( ) -> Result < ( ) > {
3131
+ let mut tcm = TestContextManager :: new ( ) ;
3132
+ let alice = tcm. alice ( ) . await ;
3133
+ let bob = tcm. bob ( ) . await ;
3134
+ let fiona = tcm. fiona ( ) . await ;
3135
+
3136
+ let grp_id = alice
3137
+ . create_group_with_members ( ProtectionStatus :: Unprotected , "grp" , & [ & bob, & fiona] )
3090
3138
. await ;
3091
3139
let alice_instance = send_webxdc_instance ( & alice, grp_id) . await ?;
3092
3140
let sent1 = alice. pop_sent_msg ( ) . await ;
3093
3141
let bob_instance = bob. recv_msg ( & sent1) . await ;
3142
+ let fiona_instance = fiona. recv_msg ( & sent1) . await ;
3094
3143
3095
3144
alice
3096
3145
. send_webxdc_status_update (
3097
3146
alice_instance. id ,
3098
3147
& format ! (
3099
- "{{\" payload\" :7,\" summary \" : \" 4 moves done \" ,\" notify \" :[ \" {} \" ] }}" ,
3148
+ "{{\" payload\" :7, \" notify \" :{{ \" {} \" : \" notify bob \" ,\" * \" : \" notify all \" }} }}" ,
3100
3149
bob_instance. get_webxdc_self_addr( & bob) . await ?
3101
3150
) ,
3102
3151
)
3103
3152
. await ?;
3104
3153
alice. flush_status_updates ( ) . await ?;
3105
3154
let sent2 = alice. pop_sent_msg ( ) . await ;
3106
- assert ! ( !has_incoming_webxdc_event( & alice, alice_instance, "4 moves done" ) . await ) ;
3155
+ bob. recv_msg_trash ( & sent2) . await ;
3156
+ fiona. recv_msg_trash ( & sent2) . await ;
3157
+ assert ! ( has_incoming_webxdc_event( & bob, bob_instance, "notify bob" ) . await ) ;
3158
+ assert ! ( has_incoming_webxdc_event( & fiona, fiona_instance, "notify all" ) . await ) ;
3159
+
3160
+ Ok ( ( ) )
3161
+ }
3162
+
3163
+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
3164
+ async fn test_webxdc_notify_all_and_bob ( ) -> Result < ( ) > {
3165
+ let mut tcm = TestContextManager :: new ( ) ;
3166
+ let alice = tcm. alice ( ) . await ;
3167
+ let bob = tcm. bob ( ) . await ;
3168
+ let fiona = tcm. fiona ( ) . await ;
3169
+
3170
+ let grp_id = alice
3171
+ . create_group_with_members ( ProtectionStatus :: Unprotected , "grp" , & [ & bob, & fiona] )
3172
+ . await ;
3173
+ let alice_instance = send_webxdc_instance ( & alice, grp_id) . await ?;
3174
+ let sent1 = alice. pop_sent_msg ( ) . await ;
3175
+ let bob_instance = bob. recv_msg ( & sent1) . await ;
3176
+ let fiona_instance = fiona. recv_msg ( & sent1) . await ;
3107
3177
3178
+ alice
3179
+ . send_webxdc_status_update (
3180
+ alice_instance. id ,
3181
+ & format ! (
3182
+ "{{\" payload\" :7, \" notify\" :{{\" *\" : \" notify all\" , \" {}\" : \" notify bob\" }} }}" ,
3183
+ bob_instance. get_webxdc_self_addr( & bob) . await ?
3184
+ ) ,
3185
+ )
3186
+ . await ?;
3187
+ alice. flush_status_updates ( ) . await ?;
3188
+ let sent2 = alice. pop_sent_msg ( ) . await ;
3108
3189
bob. recv_msg_trash ( & sent2) . await ;
3109
- assert ! ( has_incoming_webxdc_event( & bob, bob_instance, "4 moves done" ) . await ) ;
3190
+ fiona. recv_msg_trash ( & sent2) . await ;
3191
+ assert ! ( has_incoming_webxdc_event( & bob, bob_instance, "notify bob" ) . await ) ;
3192
+ assert ! ( has_incoming_webxdc_event( & fiona, fiona_instance, "notify all" ) . await ) ;
3110
3193
3111
3194
Ok ( ( ) )
3112
3195
}
0 commit comments