diff --git a/src/chat.rs b/src/chat.rs index 80976dde6..7113f97be 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 }; @@ -4963,15 +4927,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 37689f30a..f7ba9bc2f 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -1840,6 +1840,16 @@ async fn add_parts( } } + // Sort message to the bottom if we are not in the chat + // so if we are added via QR code scan + // the message about our addition goes after all the info messages. + // Info messages are sorted by local smeared_timestamp() + // which advances quickly during SecureJoin, + // while "member added" message may have older timestamp + // corresponding to the sender clock. + // In practice inviter clock may even be slightly in the past. + let sort_to_bottom = !chat.is_self_in_chat(context).await?; + let is_location_kml = mime_parser.location_kml.is_some(); let mut group_changes = match chat.typ { _ if chat.id.is_special() => GroupChangesInfo::default(), @@ -1890,16 +1900,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/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_sync_broadcast_alice1 b/test-data/golden/test_sync_broadcast_alice1 index 7d450fb71..82ce056e5 100644 --- a/test-data/golden/test_sync_broadcast_alice1 +++ b/test-data/golden/test_sync_broadcast_alice1 @@ -1,7 +1,7 @@ OutBroadcast#Chat#1001: Channel [0 member(s)] -------------------------------------------------------------------------------- Msg#1001: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO] -Msg#1006🔒: Me (Contact#Contact#Self): Member bob@example.net added. [INFO] √ Msg#1008🔒: Me (Contact#Contact#Self): hi √ +Msg#1006🔒: Me (Contact#Contact#Self): Member bob@example.net added. [INFO] √ Msg#1009🔒: Me (Contact#Contact#Self): You removed member bob@example.net. [INFO] √ --------------------------------------------------------------------------------