From e030237f7793a7d0e0906e431327df17e5110485 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Fri, 8 Dec 2023 23:02:43 -0300 Subject: [PATCH] refactor: Move calc_{protection_msg_,}sort_timestamp() to `impl ChatId` --- src/chat.rs | 74 +++++++++++++++++++++++++++++++++++++++++-- src/receive_imf.rs | 78 ++++++---------------------------------------- 2 files changed, 82 insertions(+), 70 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 9be6d9e980..6d0622b023 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -36,7 +36,7 @@ use crate::mimefactory::MimeFactory; use crate::mimeparser::SystemMessage; use crate::param::{Param, Params}; use crate::peerstate::Peerstate; -use crate::receive_imf::{calc_protection_msg_sort_timestamp, ReceivedMsg}; +use crate::receive_imf::ReceivedMsg; use crate::smtp::send_msg_to_smtp; use crate::sql; use crate::stock_str; @@ -582,7 +582,9 @@ impl ChatId { timestamp_sent: i64, contact_id: Option, ) -> Result<()> { - let ts = calc_protection_msg_sort_timestamp(context, timestamp_sent, self).await?; + let ts = self + .calc_protection_msg_sort_timestamp(context, timestamp_sent) + .await?; self.set_protection(context, protect, ts, contact_id).await } @@ -1306,6 +1308,74 @@ impl ChatId { .unwrap_or_default(); Ok(protection_status) } + + /// Returns the sort timestamp for a protection message. + /// + /// `timestamp` should be normally the "sent" timestamp of the message caused the chat + /// protection state change. + pub(crate) async fn calc_protection_msg_sort_timestamp( + self, + context: &Context, + timestamp: i64, + ) -> Result { + let sort_to_bottom = true; + self.calc_sort_timestamp(context, timestamp, sort_to_bottom, false) + .await + } + + /// Returns the sort timestamp for a new message in the chat. + /// + /// `message_timestamp` should be either the message "sent" timestamp or a timestamp of the + /// corresponding event in case of a system message (usually the current system time). + /// `always_sort_to_bottom` makes this ajust the returned timestamp up so that the message goes + /// to the chat bottom. + /// `incoming` -- whether the message is incoming. + pub(crate) async fn calc_sort_timestamp( + self, + context: &Context, + message_timestamp: i64, + always_sort_to_bottom: bool, + incoming: bool, + ) -> Result { + let mut sort_timestamp = cmp::min(message_timestamp, smeared_time(context)); + + let last_msg_time: Option = if always_sort_to_bottom { + // get newest message for this chat + context + .sql + .query_get_value( + "SELECT MAX(timestamp) FROM msgs WHERE chat_id=? AND state!=?", + (self, MessageState::OutDraft), + ) + .await? + } else if incoming { + // get newest non fresh message for this chat. + + // If a user hasn't been online for some time, the Inbox is fetched first and then the + // Sentbox. In order for Inbox and Sent messages to be allowed to mingle, outgoing + // messages are purely sorted by their sent timestamp. NB: The Inbox must be fetched + // first otherwise Inbox messages would be always below old Sentbox messages. We could + // take in the query below only incoming messages, but then new incoming messages would + // mingle with just sent outgoing ones and apear somewhere in the middle of the chat. + context + .sql + .query_get_value( + "SELECT MAX(timestamp) FROM msgs WHERE chat_id=? AND hidden=0 AND state>?", + (self, MessageState::InFresh), + ) + .await? + } else { + None + }; + + if let Some(last_msg_time) = last_msg_time { + if last_msg_time > sort_timestamp { + sort_timestamp = last_msg_time; + } + } + + Ok(sort_timestamp) + } } impl std::fmt::Display for ChatId { diff --git a/src/receive_imf.rs b/src/receive_imf.rs index cc42b8aad8..8ad56c0841 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -1,6 +1,5 @@ //! Internet Message Format reception pipeline. -use std::cmp::min; use std::collections::HashSet; use std::convert::TryFrom; @@ -39,9 +38,7 @@ use crate::simplify; use crate::sql; use crate::stock_str; use crate::sync::Sync::*; -use crate::tools::{ - buf_compress, extract_grpid_from_rfc724_mid, smeared_time, strip_rtlo_characters, -}; +use crate::tools::{buf_compress, extract_grpid_from_rfc724_mid, strip_rtlo_characters}; use crate::{contact, imap}; /// This is the struct that is returned after receiving one email (aka MIME message). @@ -1017,14 +1014,15 @@ async fn add_parts( }; let in_fresh = state == MessageState::InFresh; - let sort_timestamp = calc_sort_timestamp( - context, - mime_parser.timestamp_sent, - chat_id, - false, - incoming, - ) - .await?; + let sort_to_bottom = false; + let sort_timestamp = chat_id + .calc_sort_timestamp( + context, + mime_parser.timestamp_sent, + sort_to_bottom, + incoming, + ) + .await?; // Apply ephemeral timer changes to the chat. // @@ -1487,62 +1485,6 @@ async fn save_locations( Ok(()) } -pub(crate) async fn calc_protection_msg_sort_timestamp( - context: &Context, - timestamp: i64, - chat_id: ChatId, -) -> Result { - let sort_to_bottom = true; - calc_sort_timestamp(context, timestamp, chat_id, sort_to_bottom, false).await -} - -async fn calc_sort_timestamp( - context: &Context, - message_timestamp: i64, - chat_id: ChatId, - always_sort_to_bottom: bool, - incoming: bool, -) -> Result { - let mut sort_timestamp = min(message_timestamp, smeared_time(context)); - - let last_msg_time: Option = if always_sort_to_bottom { - // get newest message for this chat - context - .sql - .query_get_value( - "SELECT MAX(timestamp) FROM msgs WHERE chat_id=? AND state!=?", - (chat_id, MessageState::OutDraft), - ) - .await? - } else if incoming { - // get newest non fresh message for this chat. - - // If a user hasn't been online for some time, the Inbox is fetched first and then the - // Sentbox. In order for Inbox and Sent messages to be allowed to mingle, outgoing messages - // are purely sorted by their sent timestamp. NB: The Inbox must be fetched first otherwise - // Inbox messages would be always below old Sentbox messages. We could take in the query - // below only incoming messages, but then new incoming messages would mingle with just sent - // outgoing ones and apear somewhere in the middle of the chat. - context - .sql - .query_get_value( - "SELECT MAX(timestamp) FROM msgs WHERE chat_id=? AND hidden=0 AND state>?", - (chat_id, MessageState::InFresh), - ) - .await? - } else { - None - }; - - if let Some(last_msg_time) = last_msg_time { - if last_msg_time > sort_timestamp { - sort_timestamp = last_msg_time; - } - } - - Ok(sort_timestamp) -} - async fn lookup_chat_by_reply( context: &Context, mime_parser: &MimeMessage,