From 6939d22fc7b6b452ccfba3d9a9bffb580cb6540f Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 25 Mar 2026 02:09:28 +0100 Subject: [PATCH] fix: do not sort received messages below the last seen one --- src/chat.rs | 45 +------------------ src/receive_imf.rs | 9 +--- src/tests/verified_chats.rs | 40 ----------------- src/tools/tools_tests.rs | 8 ++-- .../receive_imf_delayed_removal_is_ignored | 2 +- .../receive_imf_older_message_from_2nd_device | 2 +- test-data/golden/test_old_message_5 | 5 --- 7 files changed, 9 insertions(+), 102 deletions(-) delete mode 100644 test-data/golden/test_old_message_5 diff --git a/src/chat.rs b/src/chat.rs index 7350dd409..cd163cee6 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1228,15 +1228,11 @@ SELECT id, rfc724_mid, pre_rfc724_mid, timestamp, ?, 1 FROM msgs WHERE chat_id=? /// corresponding event in case of a system message (usually the current system time). /// `always_sort_to_bottom` makes this adjust the returned timestamp up so that the message goes /// to the chat bottom. - /// `received` -- whether the message is received. Otherwise being sent. - /// `incoming` -- whether the message is incoming. pub(crate) async fn calc_sort_timestamp( self, context: &Context, message_timestamp: i64, always_sort_to_bottom: bool, - received: bool, - incoming: bool, ) -> Result { let mut sort_timestamp = cmp::min(message_timestamp, smeared_time(context)); @@ -1256,38 +1252,6 @@ SELECT id, rfc724_mid, pre_rfc724_mid, timestamp, ?, 1 FROM msgs WHERE chat_id=? (self, MessageState::OutDraft), ) .await? - } else if received { - // Received messages shouldn't mingle with just sent ones and appear somewhere in the - // middle of the chat, so we go after the newest non fresh message. - // - // But if a received outgoing message is older than some seen message, better sort the - // received message purely by timestamp. We could place it just before that seen - // message, but anyway the user may not notice it. - // - // NB: Received outgoing messages may break sorting of fresh incoming ones, but this - // shouldn't happen frequently. Seen incoming messages don't really break sorting of - // fresh ones, they rather mean that older incoming messages are actually seen as well. - context - .sql - .query_row_optional( - "SELECT MAX(timestamp), MAX(IIF(state=?,timestamp_sent,0)) - FROM msgs - WHERE chat_id=? AND hidden=0 AND state>? - HAVING COUNT(*) > 0", - (MessageState::InSeen, self, MessageState::InFresh), - |row| { - let ts: i64 = row.get(0)?; - let ts_sent_seen: i64 = row.get(1)?; - Ok((ts, ts_sent_seen)) - }, - ) - .await? - .and_then(|(ts, ts_sent_seen)| { - match incoming || ts_sent_seen <= message_timestamp { - true => Some(ts), - false => None, - } - }) } else { None }; @@ -4958,15 +4922,8 @@ pub(crate) async fn add_info_msg_with_cmd( ts } else { let sort_to_bottom = true; - let (received, incoming) = (false, false); chat_id - .calc_sort_timestamp( - context, - smeared_time(context), - sort_to_bottom, - received, - incoming, - ) + .calc_sort_timestamp(context, smeared_time(context), sort_to_bottom) .await? }; diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 55c98da76..7468f6562 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -1886,15 +1886,8 @@ async fn add_parts( let in_fresh = state == MessageState::InFresh; let sort_to_bottom = false; - let received = true; let sort_timestamp = chat_id - .calc_sort_timestamp( - context, - mime_parser.timestamp_sent, - sort_to_bottom, - received, - mime_parser.incoming, - ) + .calc_sort_timestamp(context, mime_parser.timestamp_sent, sort_to_bottom) .await?; // Apply ephemeral timer changes to the chat. diff --git a/src/tests/verified_chats.rs b/src/tests/verified_chats.rs index 0c211c2af..427cc3088 100644 --- a/src/tests/verified_chats.rs +++ b/src/tests/verified_chats.rs @@ -246,46 +246,6 @@ async fn test_old_message_4() -> Result<()> { Ok(()) } -/// Alice is offline for some time. -/// When they come online, first their mvbox is synced and then their inbox. -/// This test tests that the messages are still in the right order. -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_old_message_5() -> Result<()> { - let alice = TestContext::new_alice().await; - let msg_sent = receive_imf( - &alice, - b"From: alice@example.org\n\ - To: Bob \n\ - Message-ID: <1234-2-4@example.org>\n\ - Date: Sat, 07 Dec 2019 19:00:27 +0000\n\ - \n\ - Happy birthday, Bob!\n", - true, - ) - .await? - .unwrap(); - - let msg_incoming = receive_imf( - &alice, - b"From: Bob \n\ - To: alice@example.org\n\ - Message-ID: <1234-2-3@example.org>\n\ - Date: Sun, 07 Dec 2019 19:00:26 +0000\n\ - \n\ - Happy birthday to me, Alice!\n", - false, - ) - .await? - .unwrap(); - - assert!(msg_sent.sort_timestamp == msg_incoming.sort_timestamp); - alice - .golden_test_chat(msg_sent.chat_id, "test_old_message_5") - .await; - - Ok(()) -} - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_mdn_doesnt_disable_verification() -> Result<()> { let mut tcm = TestContextManager::new(); diff --git a/src/tools/tools_tests.rs b/src/tools/tools_tests.rs index 907af1868..3c121dcb8 100644 --- a/src/tools/tools_tests.rs +++ b/src/tools/tools_tests.rs @@ -64,9 +64,11 @@ DKIM Results: Passed=true"; async fn check_parse_receive_headers_integration(raw: &[u8], expected: &str) { let t = TestContext::new_alice().await; - receive_imf(&t, raw, false).await.unwrap(); - let msg = t.get_last_msg().await; - let msg_info = msg.id.get_info(&t).await.unwrap(); + let received = receive_imf(&t, raw, false).await.unwrap().unwrap(); + + assert_eq!(received.msg_ids.len(), 1); + let msg_id = received.msg_ids[0]; + let msg_info = msg_id.get_info(&t).await.unwrap(); // Ignore the first rows of the msg_info because they contain a // received time that depends on the test time which makes it impossible to diff --git a/test-data/golden/receive_imf_delayed_removal_is_ignored b/test-data/golden/receive_imf_delayed_removal_is_ignored index 3333fb833..22c60c966 100644 --- a/test-data/golden/receive_imf_delayed_removal_is_ignored +++ b/test-data/golden/receive_imf_delayed_removal_is_ignored @@ -2,9 +2,9 @@ Group#Chat#1001: Group [5 member(s)] -------------------------------------------------------------------------------- Msg#1001: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO] Msg#1002🔒: Me (Contact#Contact#Self): populate √ +Msg#1007🔒: (Contact#Contact#1001): Member fiona@example.net removed by bob@example.net. [FRESH][INFO] Msg#1003: info (Contact#Contact#Info): Member dom@example.net added. [NOTICED][INFO] Msg#1004: info (Contact#Contact#Info): Member fiona@example.net removed. [NOTICED][INFO] Msg#1005🔒: (Contact#Contact#1001): Member elena@example.net added by bob@example.net. [FRESH][INFO] Msg#1006🔒: Me (Contact#Contact#Self): You added member fiona@example.net. [INFO] o -Msg#1007🔒: (Contact#Contact#1001): Member fiona@example.net removed by bob@example.net. [FRESH][INFO] -------------------------------------------------------------------------------- diff --git a/test-data/golden/receive_imf_older_message_from_2nd_device b/test-data/golden/receive_imf_older_message_from_2nd_device index b83343287..a89a4f685 100644 --- a/test-data/golden/receive_imf_older_message_from_2nd_device +++ b/test-data/golden/receive_imf_older_message_from_2nd_device @@ -1,5 +1,5 @@ Single#Chat#1001: bob@example.net [bob@example.net] Icon: 4138c52e5bc1c576cda7dd44d088c07.png -------------------------------------------------------------------------------- -Msg#1001: Me (Contact#Contact#Self): We share this account √ Msg#1002: Me (Contact#Contact#Self): I'm Alice too √ +Msg#1001: Me (Contact#Contact#Self): We share this account √ -------------------------------------------------------------------------------- diff --git a/test-data/golden/test_old_message_5 b/test-data/golden/test_old_message_5 deleted file mode 100644 index 92bd8ac86..000000000 --- a/test-data/golden/test_old_message_5 +++ /dev/null @@ -1,5 +0,0 @@ -Single#Chat#11001: Bob [bob@example.net] Icon: 4138c52e5bc1c576cda7dd44d088c07.png --------------------------------------------------------------------------------- -Msg#11001: Me (Contact#Contact#Self): Happy birthday, Bob! √ -Msg#11002: (Contact#Contact#11001): Happy birthday to me, Alice! [FRESH] ---------------------------------------------------------------------------------