diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index b437da552..99abc7a72 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -1,5 +1,6 @@ //! Internet Message Format reception pipeline. +use std::cmp::min; use std::convert::TryFrom; use anyhow::{bail, ensure, Result}; @@ -18,9 +19,7 @@ use crate::constants::{ }; use crate::contact::{addr_cmp, normalize_name, Contact, Origin, VerifiedStatus}; use crate::context::Context; -use crate::dc_tools::{ - dc_create_smeared_timestamp, dc_extract_grpid_from_rfc724_mid, dc_smeared_time, -}; +use crate::dc_tools::{dc_extract_grpid_from_rfc724_mid, dc_smeared_time}; use crate::download::DownloadState; use crate::ephemeral::{stock_ephemeral_timer_changed, Timer as EphemeralTimer}; use crate::events::EventType; @@ -106,15 +105,6 @@ pub(crate) async fn dc_receive_imf_inner( return Ok(()); } - let mut sent_timestamp = if let Some(value) = mime_parser - .get_header(HeaderDef::Date) - .and_then(|value| mailparse::dateparse(value).ok()) - { - value - } else { - dc_create_smeared_timestamp(context).await - }; - let rfc724_mid = mime_parser.get_rfc724_mid().unwrap_or_else(|| // missing Message-IDs may come if the mail was set from this account with another // client that relies in the SMTP server to generate one. @@ -193,6 +183,12 @@ pub(crate) async fn dc_receive_imf_inner( .await?, ); + let rcvd_timestamp = dc_smeared_time(context).await; + let sent_timestamp = mime_parser + .get_header(HeaderDef::Date) + .and_then(|value| mailparse::dateparse(value).ok()) + .map_or(rcvd_timestamp, |value| min(value, rcvd_timestamp)); + // Add parts let chat_id = add_parts( context, @@ -204,7 +200,8 @@ pub(crate) async fn dc_receive_imf_inner( server_uid, &to_ids, rfc724_mid, - &mut sent_timestamp, + sent_timestamp, + rcvd_timestamp, from_id, &mut hidden, seen || replace_partial_download, @@ -406,7 +403,8 @@ async fn add_parts( server_uid: u32, to_ids: &ContactIds, rfc724_mid: String, - sent_timestamp: &mut i64, + sent_timestamp: i64, + rcvd_timestamp: i64, from_id: u32, hidden: &mut bool, seen: bool, @@ -455,9 +453,6 @@ async fn add_parts( } } - let rcvd_timestamp = dc_smeared_time(context).await; - *sent_timestamp = std::cmp::min(*sent_timestamp, rcvd_timestamp); - // check if the message introduces a new chat: // - outgoing messages introduce a chat with the first to: address if they are sent by a messenger // - incoming messages introduce a chat only for known contacts if they are sent by a messenger @@ -531,7 +526,7 @@ async fn add_parts( if let Some((new_chat_id, new_chat_id_blocked)) = create_or_lookup_group( context, &mut mime_parser, - *sent_timestamp, + sent_timestamp, if test_normal_chat.is_none() { allow_creation } else { @@ -761,7 +756,7 @@ async fn add_parts( if let Some((new_chat_id, new_chat_id_blocked)) = create_or_lookup_group( context, &mut mime_parser, - *sent_timestamp, + sent_timestamp, allow_creation, Blocked::Not, from_id, @@ -857,7 +852,7 @@ async fn add_parts( // correct message_timestamp, it should not be used before, // however, we cannot do this earlier as we need chat_id to be set let in_fresh = state == MessageState::InFresh; - let sort_timestamp = calc_sort_timestamp(context, *sent_timestamp, chat_id, in_fresh).await?; + let sort_timestamp = calc_sort_timestamp(context, sent_timestamp, chat_id, in_fresh).await?; // Apply ephemeral timer changes to the chat. // @@ -896,7 +891,7 @@ async fn add_parts( chat_id ); } else if chat_id - .update_timestamp(context, Param::EphemeralSettingsTimestamp, *sent_timestamp) + .update_timestamp(context, Param::EphemeralSettingsTimestamp, sent_timestamp) .await? { if let Err(err) = chat_id @@ -967,7 +962,7 @@ async fn add_parts( .update_timestamp( context, Param::ProtectionSettingsTimestamp, - *sent_timestamp, + sent_timestamp, ) .await? { @@ -1047,7 +1042,6 @@ async fn add_parts( Vec::new() }; - let sent_timestamp = *sent_timestamp; let is_hidden = *hidden; let mut is_hidden = is_hidden; @@ -1304,11 +1298,7 @@ async fn calc_sort_timestamp( } } - if sort_timestamp >= dc_smeared_time(context).await { - sort_timestamp = dc_create_smeared_timestamp(context).await; - } - - Ok(sort_timestamp) + Ok(min(sort_timestamp, dc_smeared_time(context).await)) } async fn lookup_chat_by_reply( diff --git a/src/dc_tools.rs b/src/dc_tools.rs index b480973cc..cd7b1ebd2 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -84,9 +84,9 @@ pub(crate) fn dc_gm2local_offset() -> i64 { // but at max `MAX_SECONDS_TO_LEND_FROM_FUTURE` const MAX_SECONDS_TO_LEND_FROM_FUTURE: i64 = 5; -// returns the currently smeared timestamp, -// may be used to check if call to dc_create_smeared_timestamp() is needed or not. -// the returned timestamp MUST NOT be used to be sent out or saved in the database! +/// Returns the current smeared timestamp, +/// +/// The returned timestamp MUST NOT be sent out. pub(crate) async fn dc_smeared_time(context: &Context) -> i64 { let mut now = time(); let ts = *context.last_smeared_timestamp.read().await; @@ -97,7 +97,7 @@ pub(crate) async fn dc_smeared_time(context: &Context) -> i64 { now } -// returns a timestamp that is guaranteed to be unique. +/// Returns a timestamp that is guaranteed to be unique. pub(crate) async fn dc_create_smeared_timestamp(context: &Context) -> i64 { let now = time(); let mut ret = now;