@@ -558,43 +558,53 @@ pub(crate) async fn receive_imf_inner(
558558 let ( replace_msg_id, replace_chat_id) ;
559559 if let Some ( ( old_msg_id, _) ) = message:: rfc724_mid_exists ( context, rfc724_mid) . await ? {
560560 let msg = Message :: load_from_db_optional ( context, old_msg_id) . await ?;
561- if msg. is_none ( ) {
562- message:: prune_tombstone ( context, rfc724_mid) . await ?;
561+ // The tombstone being pruned means that we expected the message to appear on IMAP after
562+ // deletion. NB: Not all such messages have `msgs.deleted=1`, see how external deletion
563+ // requests deal with message reordering.
564+ match msg. is_none ( ) && !message:: prune_tombstone ( context, rfc724_mid) . await ? {
565+ true => replace_msg_id = None ,
566+ false => replace_msg_id = Some ( old_msg_id) ,
563567 }
564- replace_msg_id = Some ( old_msg_id) ;
565568 if let Some ( msg) = msg. filter ( |msg| msg. download_state ( ) != DownloadState :: Done ) {
566569 // the message was partially downloaded before and is fully downloaded now.
567570 info ! ( context, "Message already partly in DB, replacing." ) ;
568571 replace_chat_id = Some ( msg. chat_id ) ;
569572 } else {
570573 replace_chat_id = None ;
571574 }
572- } else {
573- replace_msg_id = if rfc724_mid_orig == rfc724_mid {
574- None
575- } else if let Some ( ( old_msg_id, old_ts_sent) ) =
576- message:: rfc724_mid_exists ( context, rfc724_mid_orig) . await ?
577- {
578- message:: prune_tombstone ( context, rfc724_mid_orig) . await ?;
579- if imap:: is_dup_msg (
580- mime_parser. has_chat_version ( ) ,
581- mime_parser. timestamp_sent ,
582- old_ts_sent,
583- ) {
584- info ! ( context, "Deleting duplicate message {rfc724_mid_orig}." ) ;
585- let target = context. get_delete_msgs_target ( ) . await ?;
586- context
587- . sql
588- . execute (
589- "UPDATE imap SET target=? WHERE folder=? AND uidvalidity=? AND uid=?" ,
590- ( target, folder, uidvalidity, uid) ,
591- )
592- . await ?;
593- }
594- Some ( old_msg_id)
575+ } else if rfc724_mid_orig == rfc724_mid {
576+ replace_msg_id = None ;
577+ replace_chat_id = None ;
578+ } else if let Some ( ( old_msg_id, old_ts_sent, is_trash) ) = message:: rfc724_mid_exists_ex (
579+ context,
580+ rfc724_mid_orig,
581+ "chat_id=3" , // Trash
582+ )
583+ . await ?
584+ {
585+ if is_trash && !message:: prune_tombstone ( context, rfc724_mid_orig) . await ? {
586+ replace_msg_id = None ;
587+ } else if imap:: is_dup_msg (
588+ mime_parser. has_chat_version ( ) ,
589+ mime_parser. timestamp_sent ,
590+ old_ts_sent,
591+ ) {
592+ info ! ( context, "Deleting duplicate message {rfc724_mid_orig}." ) ;
593+ let target = context. get_delete_msgs_target ( ) . await ?;
594+ context
595+ . sql
596+ . execute (
597+ "UPDATE imap SET target=? WHERE folder=? AND uidvalidity=? AND uid=?" ,
598+ ( target, folder, uidvalidity, uid) ,
599+ )
600+ . await ?;
601+ replace_msg_id = Some ( old_msg_id) ;
595602 } else {
596- None
597- } ;
603+ replace_msg_id = Some ( old_msg_id) ;
604+ }
605+ replace_chat_id = None ;
606+ } else {
607+ replace_msg_id = None ;
598608 replace_chat_id = None ;
599609 }
600610
0 commit comments