@@ -165,6 +165,11 @@ pub struct StatusUpdateItem {
165
165
#[ serde( skip_serializing_if = "Option::is_none" ) ]
166
166
pub info : Option < String > ,
167
167
168
+ /// Optional link the info message will point to.
169
+ /// Used to set `window.location.href` in JS land.
170
+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
171
+ pub href : Option < String > ,
172
+
168
173
/// The new name of the editing document.
169
174
/// This is not needed if the webxdc doesn't edit documents.
170
175
#[ serde( skip_serializing_if = "Option::is_none" ) ]
@@ -353,19 +358,22 @@ impl Context {
353
358
354
359
if can_info_msg {
355
360
if let Some ( ref info) = status_update_item. info {
356
- if let Some ( info_msg_id) = self
361
+ let info_msg_id = self
357
362
. get_overwritable_info_msg_id ( & instance, from_id)
358
- . await ?
359
- {
360
- chat:: update_msg_text_and_timestamp (
361
- self ,
362
- instance. chat_id ,
363
- info_msg_id,
364
- info. as_str ( ) ,
365
- timestamp,
366
- )
367
363
. await ?;
368
- notify_msg_id = info_msg_id;
364
+
365
+ if info_msg_id. is_some ( ) && status_update_item. href . is_none ( ) {
366
+ if let Some ( info_msg_id) = info_msg_id {
367
+ chat:: update_msg_text_and_timestamp (
368
+ self ,
369
+ instance. chat_id ,
370
+ info_msg_id,
371
+ info. as_str ( ) ,
372
+ timestamp,
373
+ )
374
+ . await ?;
375
+ notify_msg_id = info_msg_id;
376
+ }
369
377
} else {
370
378
notify_msg_id = chat:: add_info_msg_with_cmd (
371
379
self ,
@@ -380,6 +388,12 @@ impl Context {
380
388
. await ?;
381
389
}
382
390
notify_text = info. to_string ( ) ;
391
+
392
+ if let Some ( href) = status_update_item. href {
393
+ let mut notify_msg = Message :: load_from_db ( self , notify_msg_id) . await ?;
394
+ notify_msg. param . set ( Param :: Arg , href) ;
395
+ notify_msg. update_param ( self ) . await ?;
396
+ }
383
397
}
384
398
}
385
399
@@ -944,6 +958,15 @@ impl Message {
944
958
let hash = Sha256 :: digest ( data. as_bytes ( ) ) ;
945
959
Ok ( format ! ( "{:x}" , hash) )
946
960
}
961
+
962
+ /// Get link attached to an info message.
963
+ ///
964
+ /// The info message needs to be of type SystemMessage::WebxdcInfoMessage.
965
+ /// Typically, this is used to start the corresponding webxdc app
966
+ /// with `window.location.href` set in JS land.
967
+ pub fn get_webxdc_href ( & self ) -> Option < String > {
968
+ self . param . get ( Param :: Arg ) . map ( |href| href. to_string ( ) )
969
+ }
947
970
}
948
971
949
972
#[ cfg( test) ]
@@ -1457,6 +1480,7 @@ mod tests {
1457
1480
StatusUpdateItem {
1458
1481
payload : json ! ( { "foo" : "bar" } ) ,
1459
1482
info : None ,
1483
+ href : None ,
1460
1484
document : None ,
1461
1485
summary : None ,
1462
1486
uid : Some ( "iecie2Ze" . to_string ( ) ) ,
@@ -1482,6 +1506,7 @@ mod tests {
1482
1506
StatusUpdateItem {
1483
1507
payload : json ! ( { "nothing" : "this should be ignored" } ) ,
1484
1508
info : None ,
1509
+ href : None ,
1485
1510
document : None ,
1486
1511
summary : None ,
1487
1512
uid : Some ( "iecie2Ze" . to_string ( ) ) ,
@@ -1516,6 +1541,7 @@ mod tests {
1516
1541
StatusUpdateItem {
1517
1542
payload : json ! ( { "foo2" : "bar2" } ) ,
1518
1543
info : None ,
1544
+ href : None ,
1519
1545
document : None ,
1520
1546
summary : None ,
1521
1547
uid : None ,
@@ -1536,6 +1562,7 @@ mod tests {
1536
1562
StatusUpdateItem {
1537
1563
payload : Value :: Bool ( true ) ,
1538
1564
info : None ,
1565
+ href : None ,
1539
1566
document : None ,
1540
1567
summary : None ,
1541
1568
uid : None ,
@@ -3110,4 +3137,38 @@ sth_for_the = "future""#
3110
3137
3111
3138
Ok ( ( ) )
3112
3139
}
3140
+
3141
+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
3142
+ async fn test_webxdc_href ( ) -> Result < ( ) > {
3143
+ let mut tcm = TestContextManager :: new ( ) ;
3144
+ let alice = tcm. alice ( ) . await ;
3145
+ let bob = tcm. bob ( ) . await ;
3146
+
3147
+ let grp_id = alice
3148
+ . create_group_with_members ( ProtectionStatus :: Unprotected , "grp" , & [ & bob] )
3149
+ . await ;
3150
+ let instance = send_webxdc_instance ( & alice, grp_id) . await ?;
3151
+ let sent1 = alice. pop_sent_msg ( ) . await ;
3152
+
3153
+ alice
3154
+ . send_webxdc_status_update (
3155
+ instance. id ,
3156
+ r##"{"payload": "my deeplink data", "info": "my move!", "href": "#foobar"}"## ,
3157
+ "d" ,
3158
+ )
3159
+ . await ?;
3160
+ alice. flush_status_updates ( ) . await ?;
3161
+ let sent2 = alice. pop_sent_msg ( ) . await ;
3162
+ let info_msg = alice. get_last_msg ( ) . await ;
3163
+ assert ! ( info_msg. is_info( ) ) ;
3164
+ assert_eq ! ( info_msg. get_webxdc_href( ) , Some ( "#foobar" . to_string( ) ) ) ;
3165
+
3166
+ bob. recv_msg ( & sent1) . await ;
3167
+ bob. recv_msg_trash ( & sent2) . await ;
3168
+ let info_msg = bob. get_last_msg ( ) . await ;
3169
+ assert ! ( info_msg. is_info( ) ) ;
3170
+ assert_eq ! ( info_msg. get_webxdc_href( ) , Some ( "#foobar" . to_string( ) ) ) ;
3171
+
3172
+ Ok ( ( ) )
3173
+ }
3113
3174
}
0 commit comments