@@ -560,10 +560,13 @@ pub(crate) async fn receive_imf_inner(
560
560
return Ok ( None ) ;
561
561
}
562
562
let msg = Message :: load_from_db_optional ( context, old_msg_id) . await ?;
563
- if msg. is_none ( ) {
564
- message:: prune_tombstone ( context, rfc724_mid) . await ?;
563
+ // The tombstone being pruned means that we expected the message to appear on IMAP after
564
+ // deletion. NB: Not all such messages have `msgs.deleted=1`, see how external deletion
565
+ // requests deal with message reordering.
566
+ match msg. is_none ( ) && !message:: prune_tombstone ( context, rfc724_mid) . await ? {
567
+ true => replace_msg_id = None ,
568
+ false => replace_msg_id = Some ( old_msg_id) ,
565
569
}
566
- replace_msg_id = Some ( old_msg_id) ;
567
570
if let Some ( msg) = msg. filter ( |msg| msg. download_state ( ) != DownloadState :: Done ) {
568
571
// the message was partially downloaded before and is fully downloaded now.
569
572
info ! (
@@ -574,32 +577,39 @@ pub(crate) async fn receive_imf_inner(
574
577
} else {
575
578
replace_chat_id = None ;
576
579
}
577
- } else {
578
- replace_msg_id = if rfc724_mid_orig == rfc724_mid {
579
- None
580
- } else if let Some ( ( old_msg_id, old_ts_sent) ) =
581
- message:: rfc724_mid_exists ( context, rfc724_mid_orig) . await ?
582
- {
583
- message:: prune_tombstone ( context, rfc724_mid_orig) . await ?;
584
- if imap:: is_dup_msg (
585
- mime_parser. has_chat_version ( ) ,
586
- mime_parser. timestamp_sent ,
587
- old_ts_sent,
588
- ) {
589
- info ! ( context, "Deleting duplicate message {rfc724_mid_orig}." ) ;
590
- let target = context. get_delete_msgs_target ( ) . await ?;
591
- context
592
- . sql
593
- . execute (
594
- "UPDATE imap SET target=? WHERE folder=? AND uidvalidity=? AND uid=?" ,
595
- ( target, folder, uidvalidity, uid) ,
596
- )
597
- . await ?;
598
- }
599
- Some ( old_msg_id)
580
+ } else if rfc724_mid_orig == rfc724_mid {
581
+ replace_msg_id = None ;
582
+ replace_chat_id = None ;
583
+ } else if let Some ( ( old_msg_id, old_ts_sent, is_trash) ) = message:: rfc724_mid_exists_ex (
584
+ context,
585
+ rfc724_mid_orig,
586
+ "chat_id=3" , // Trash
587
+ )
588
+ . await ?
589
+ {
590
+ if is_trash && !message:: prune_tombstone ( context, rfc724_mid_orig) . await ? {
591
+ replace_msg_id = None ;
592
+ } else if imap:: is_dup_msg (
593
+ mime_parser. has_chat_version ( ) ,
594
+ mime_parser. timestamp_sent ,
595
+ old_ts_sent,
596
+ ) {
597
+ info ! ( context, "Deleting duplicate message {rfc724_mid_orig}." ) ;
598
+ let target = context. get_delete_msgs_target ( ) . await ?;
599
+ context
600
+ . sql
601
+ . execute (
602
+ "UPDATE imap SET target=? WHERE folder=? AND uidvalidity=? AND uid=?" ,
603
+ ( target, folder, uidvalidity, uid) ,
604
+ )
605
+ . await ?;
606
+ replace_msg_id = Some ( old_msg_id) ;
600
607
} else {
601
- None
602
- } ;
608
+ replace_msg_id = Some ( old_msg_id) ;
609
+ }
610
+ replace_chat_id = None ;
611
+ } else {
612
+ replace_msg_id = None ;
603
613
replace_chat_id = None ;
604
614
}
605
615
0 commit comments