@@ -102,6 +102,10 @@ pub enum Action {
102
102
MoveMsg = 200 ,
103
103
DeleteMsgOnImap = 210 ,
104
104
105
+ // UID synchronization is high-priority to make sure correct UIDs
106
+ // are used by message moving/deletion.
107
+ ResyncFolders = 300 ,
108
+
105
109
// Jobs in the SMTP-thread, range from DC_SMTP_THREAD..DC_SMTP_THREAD+999
106
110
MaybeSendLocations = 5005 , // low priority ...
107
111
MaybeSendLocationsEnded = 5007 ,
@@ -124,6 +128,7 @@ impl From<Action> for Thread {
124
128
125
129
Housekeeping => Thread :: Imap ,
126
130
DeleteMsgOnImap => Thread :: Imap ,
131
+ ResyncFolders => Thread :: Imap ,
127
132
EmptyServer => Thread :: Imap ,
128
133
MarkseenMsgOnImap => Thread :: Imap ,
129
134
MoveMsg => Thread :: Imap ,
@@ -619,6 +624,44 @@ impl Job {
619
624
}
620
625
}
621
626
627
+ /// Synchronizes UIDs for sentbox, inbox and mvbox, in this order.
628
+ ///
629
+ /// If a copy of the message is present in multiple folders, mvbox
630
+ /// is preferred to inbox, which is in turn preferred to
631
+ /// sentbox. This is because in the database it is impossible to
632
+ /// store multiple UIDs for one message, so we prefer to
633
+ /// automatically delete messages in the folders managed by Delta
634
+ /// Chat in contrast to the Sent folder, which is normally managed
635
+ /// by the user via webmail or another email client.
636
+ async fn resync_folders ( & mut self , context : & Context , imap : & mut Imap ) -> Status {
637
+ if let Err ( err) = imap. connect_configured ( context) . await {
638
+ warn ! ( context, "could not connect: {:?}" , err) ;
639
+ return Status :: RetryLater ;
640
+ }
641
+
642
+ if let Some ( sentbox_folder) = & context. get_config ( Config :: ConfiguredSentboxFolder ) . await {
643
+ job_try ! (
644
+ imap. resync_folder_uids( context, sentbox_folder. to_string( ) )
645
+ . await
646
+ ) ;
647
+ }
648
+
649
+ if let Some ( inbox_folder) = & context. get_config ( Config :: ConfiguredInboxFolder ) . await {
650
+ job_try ! (
651
+ imap. resync_folder_uids( context, inbox_folder. to_string( ) )
652
+ . await
653
+ ) ;
654
+ }
655
+
656
+ if let Some ( mvbox_folder) = & context. get_config ( Config :: ConfiguredMvboxFolder ) . await {
657
+ job_try ! (
658
+ imap. resync_folder_uids( context, mvbox_folder. to_string( ) )
659
+ . await
660
+ ) ;
661
+ }
662
+ Status :: Finished ( Ok ( ( ) ) )
663
+ }
664
+
622
665
async fn empty_server ( & mut self , context : & Context , imap : & mut Imap ) -> Status {
623
666
if let Err ( err) = imap. connect_configured ( context) . await {
624
667
warn ! ( context, "could not connect: {:?}" , err) ;
@@ -986,6 +1029,7 @@ async fn perform_job_action(
986
1029
}
987
1030
Action :: EmptyServer => job. empty_server ( context, connection. inbox ( ) ) . await ,
988
1031
Action :: DeleteMsgOnImap => job. delete_msg_on_imap ( context, connection. inbox ( ) ) . await ,
1032
+ Action :: ResyncFolders => job. resync_folders ( context, connection. inbox ( ) ) . await ,
989
1033
Action :: MarkseenMsgOnImap => job. markseen_msg_on_imap ( context, connection. inbox ( ) ) . await ,
990
1034
Action :: MoveMsg => job. move_msg ( context, connection. inbox ( ) ) . await ,
991
1035
Action :: Housekeeping => {
@@ -1043,6 +1087,7 @@ pub async fn add(context: &Context, job: Job) {
1043
1087
Action :: Housekeeping
1044
1088
| Action :: EmptyServer
1045
1089
| Action :: DeleteMsgOnImap
1090
+ | Action :: ResyncFolders
1046
1091
| Action :: MarkseenMsgOnImap
1047
1092
| Action :: MoveMsg => {
1048
1093
info ! ( context, "interrupt: imap" ) ;
0 commit comments