Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: calc_sort_timestamp(): Don't look at existing messages' timesta…
…mp_sent

This makes `calc_sort_timestamp()` a continuous function of the message timestamp, simplifies the
SQL query and prepares for creation of a db index for it so that it's fast. Currently it doesn't
uses indexes effectively; if a chat has many messages, it's slow, i.e. O(n).
  • Loading branch information
iequidoo authored and link2xt committed Oct 19, 2025
commit e286d72614a88bf26da9db0d23c4ebe41c0f1371
30 changes: 14 additions & 16 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1218,37 +1218,35 @@ impl ChatId {
)
.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.
// Received incoming 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. Received
// outgoing messages are allowed to mingle with seen messages though to avoid seen
// replies appearing before messages sent from another device (cases like the user
// sharing the account with others or bots are rare, so let them break sometimes).
//
// 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))
"SELECT MAX(timestamp)
FROM msgs
WHERE chat_id=? AND hidden=0 AND state>?
HAVING COUNT(*) > 0",
(MessageState::InSeen, self, MessageState::InFresh),
(
self,
match incoming {
true => MessageState::InFresh,
false => MessageState::InSeen,
},
),
|row| {
let ts: i64 = row.get(0)?;
let ts_sent_seen: i64 = row.get(1)?;
Ok((ts, ts_sent_seen))
Ok(ts)
},
)
.await?
.and_then(|(ts, ts_sent_seen)| {
match incoming || ts_sent_seen <= message_timestamp {
true => Some(ts),
false => None,
}
})
} else {
None
};
Expand Down
2 changes: 1 addition & 1 deletion test-data/golden/test_outgoing_encrypted_msg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Single#Chat#10: [email protected] [KEY [email protected]]
--------------------------------------------------------------------------------
Msg#10: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO]
Msg#11🔒: Me (Contact#Contact#Self): Test – This is encrypted, signed, and has an Autocrypt Header without prefer-encrypt=mutual. √
Msg#10: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO]
--------------------------------------------------------------------------------