mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 17:36:29 +03:00
fix!: Download outgoing messages only from Sentbox and if SentboxWatch is set (#7169)
Download outgoing messages only from Inbox and Mvbox (and Sent -- until `Config::SentboxWatch` is dropped) to ensure they are sorted correctly with incoming messages. This way we actually do server-side sorting. Otherwise it's possible that outgoing replies from other devices appear before incoming messages. Users should CC/BCC/To themselves to see sent messages in Delta Chat.
This commit is contained in:
@@ -846,6 +846,7 @@ def test_dont_show_emails(acfactory, lp):
|
|||||||
ac1.direct_imap.create_folder("Sent")
|
ac1.direct_imap.create_folder("Sent")
|
||||||
ac1.direct_imap.create_folder("Spam")
|
ac1.direct_imap.create_folder("Spam")
|
||||||
ac1.direct_imap.create_folder("Junk")
|
ac1.direct_imap.create_folder("Junk")
|
||||||
|
ac1.set_config("sentbox_watch", "1")
|
||||||
|
|
||||||
acfactory.bring_accounts_online()
|
acfactory.bring_accounts_online()
|
||||||
ac1.stop_io()
|
ac1.stop_io()
|
||||||
@@ -955,7 +956,10 @@ def test_dont_show_emails(acfactory, lp):
|
|||||||
|
|
||||||
msg = ac1._evtracker.wait_next_messages_changed()
|
msg = ac1._evtracker.wait_next_messages_changed()
|
||||||
|
|
||||||
# Wait until each folder was scanned, this is necessary for this test to test what it should test:
|
# Wait until each folder was scanned, this is necessary for this test to test what it should
|
||||||
|
# test. Need to wait two times because of "sentbox_watch" set (the same event is emitted for
|
||||||
|
# Sentbox currently).
|
||||||
|
ac1._evtracker.wait_idle_inbox_ready()
|
||||||
ac1._evtracker.wait_idle_inbox_ready()
|
ac1._evtracker.wait_idle_inbox_ready()
|
||||||
|
|
||||||
assert msg.text == "subj – message in Sent"
|
assert msg.text == "subj – message in Sent"
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ pub enum EventType {
|
|||||||
/// Emitted when an IMAP message has been moved
|
/// Emitted when an IMAP message has been moved
|
||||||
ImapMessageMoved(String),
|
ImapMessageMoved(String),
|
||||||
|
|
||||||
/// Emitted before going into IDLE on the Inbox folder.
|
/// Emitted before going into IDLE on any folder.
|
||||||
ImapInboxIdle,
|
ImapInboxIdle,
|
||||||
|
|
||||||
/// Emitted when an new file in the $BLOBDIR was created
|
/// Emitted when an new file in the $BLOBDIR was created
|
||||||
|
|||||||
33
src/imap.rs
33
src/imap.rs
@@ -665,18 +665,15 @@ impl Imap {
|
|||||||
// message, move it to the movebox and then download the second message before
|
// message, move it to the movebox and then download the second message before
|
||||||
// downloading the first one, if downloading from inbox before moving is allowed.
|
// downloading the first one, if downloading from inbox before moving is allowed.
|
||||||
if folder == target
|
if folder == target
|
||||||
// Never download messages directly from the spam folder.
|
|
||||||
// If the sender is known, the message will be moved to the Inbox or Mvbox
|
|
||||||
// and then we download the message from there.
|
|
||||||
// Also see `spam_target_folder_cfg()`.
|
|
||||||
&& folder_meaning != FolderMeaning::Spam
|
|
||||||
&& prefetch_should_download(
|
&& prefetch_should_download(
|
||||||
context,
|
context,
|
||||||
|
folder_meaning,
|
||||||
&headers,
|
&headers,
|
||||||
&message_id,
|
&message_id,
|
||||||
fetch_response.flags(),
|
fetch_response.flags(),
|
||||||
)
|
)
|
||||||
.await.context("prefetch_should_download")?
|
.await
|
||||||
|
.context("prefetch_should_download")?
|
||||||
{
|
{
|
||||||
match download_limit {
|
match download_limit {
|
||||||
Some(download_limit) => uids_fetch.push((
|
Some(download_limit) => uids_fetch.push((
|
||||||
@@ -2244,10 +2241,34 @@ async fn prefetch_get_chat(
|
|||||||
/// Determines whether the message should be downloaded based on prefetched headers.
|
/// Determines whether the message should be downloaded based on prefetched headers.
|
||||||
pub(crate) async fn prefetch_should_download(
|
pub(crate) async fn prefetch_should_download(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
|
folder_meaning: FolderMeaning,
|
||||||
headers: &[mailparse::MailHeader<'_>],
|
headers: &[mailparse::MailHeader<'_>],
|
||||||
message_id: &str,
|
message_id: &str,
|
||||||
mut flags: impl Iterator<Item = Flag<'_>>,
|
mut flags: impl Iterator<Item = Flag<'_>>,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
|
// Never download messages directly from the spam folder.
|
||||||
|
// If the sender is known, the message will be moved to the Inbox or Mvbox
|
||||||
|
// and then we download the message from there.
|
||||||
|
// Also see `spam_target_folder_cfg()`.
|
||||||
|
if folder_meaning == FolderMeaning::Spam {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download outgoing messages only from Inbox and Mvbox (and Sent -- until
|
||||||
|
// `Config::SentboxWatch` is dropped) to ensure they are sorted correctly with incoming
|
||||||
|
// messages. This way we actually do server-side sorting. Otherwise it's possible that outgoing
|
||||||
|
// replies from other devices appear before incoming messages. Users should CC/BCC/To themselves
|
||||||
|
// to see sent messages in Delta Chat.
|
||||||
|
if matches!(
|
||||||
|
folder_meaning,
|
||||||
|
FolderMeaning::Inbox | FolderMeaning::Mvbox | FolderMeaning::Sent
|
||||||
|
) {
|
||||||
|
} else if let Some(from) = mimeparser::get_from(headers) {
|
||||||
|
if context.is_self_addr(&from.addr).await? {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if message::rfc724_mid_exists(context, message_id)
|
if message::rfc724_mid_exists(context, message_id)
|
||||||
.await?
|
.await?
|
||||||
.is_some()
|
.is_some()
|
||||||
|
|||||||
@@ -71,10 +71,14 @@ impl Imap {
|
|||||||
_ => folder_meaning,
|
_ => folder_meaning,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Scan folders for incoming messages. As for outgoing ones, users should CC/BCC/To
|
||||||
|
// themselves so that Delta Chat sees such messages in Inbox.
|
||||||
|
//
|
||||||
// Don't scan folders that are watched anyway
|
// Don't scan folders that are watched anyway
|
||||||
if !watched_folders.contains(&folder.name().to_string())
|
if !watched_folders.contains(&folder.name().to_string())
|
||||||
&& folder_meaning != FolderMeaning::Drafts
|
&& folder_meaning != FolderMeaning::Drafts
|
||||||
&& folder_meaning != FolderMeaning::Trash
|
&& folder_meaning != FolderMeaning::Trash
|
||||||
|
&& folder_meaning != FolderMeaning::Sent
|
||||||
{
|
{
|
||||||
self.fetch_move_delete(context, session, folder.name(), folder_meaning)
|
self.fetch_move_delete(context, session, folder.name(), folder_meaning)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::chatlist::Chatlist;
|
|||||||
use crate::constants::DC_GCL_FOR_FORWARDING;
|
use crate::constants::DC_GCL_FOR_FORWARDING;
|
||||||
use crate::contact;
|
use crate::contact;
|
||||||
use crate::download::MIN_DOWNLOAD_LIMIT;
|
use crate::download::MIN_DOWNLOAD_LIMIT;
|
||||||
use crate::imap::prefetch_should_download;
|
use crate::imap::{FolderMeaning, prefetch_should_download};
|
||||||
use crate::imex::{ImexMode, imex};
|
use crate::imex::{ImexMode, imex};
|
||||||
use crate::securejoin::get_securejoin_qr;
|
use crate::securejoin::get_securejoin_qr;
|
||||||
use crate::test_utils::{
|
use crate::test_utils::{
|
||||||
@@ -672,7 +672,13 @@ async fn test_parse_ndn(
|
|||||||
// Check that the ndn would be downloaded:
|
// Check that the ndn would be downloaded:
|
||||||
let headers = mailparse::parse_mail(raw_ndn).unwrap().headers;
|
let headers = mailparse::parse_mail(raw_ndn).unwrap().headers;
|
||||||
assert!(
|
assert!(
|
||||||
prefetch_should_download(&t, &headers, "some-other-message-id", std::iter::empty(),)
|
prefetch_should_download(
|
||||||
|
&t,
|
||||||
|
FolderMeaning::Inbox,
|
||||||
|
&headers,
|
||||||
|
"some-other-message-id",
|
||||||
|
std::iter::empty(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -661,6 +661,7 @@ async fn fetch_idle(
|
|||||||
|
|
||||||
connection.connectivity.set_idle(ctx);
|
connection.connectivity.set_idle(ctx);
|
||||||
|
|
||||||
|
// Maybe we'll remove watching other folders soon, so use this event for all folders for now.
|
||||||
ctx.emit_event(EventType::ImapInboxIdle);
|
ctx.emit_event(EventType::ImapInboxIdle);
|
||||||
|
|
||||||
if !session.can_idle() {
|
if !session.can_idle() {
|
||||||
|
|||||||
Reference in New Issue
Block a user