+
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
35 changes: 16 additions & 19 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1218,37 +1218,34 @@ 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.
let states = match incoming {
true => "13, 16, 18, 20, 24, 26", // `> MessageState::InFresh`
false => "18, 20, 24, 26", // `> MessageState::InSeen`
};
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),
&format!(
"SELECT MAX(timestamp) FROM msgs
WHERE state IN ({states}) AND hidden=0 AND chat_id=?
HAVING COUNT(*) > 0"
),
(self,),
|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 src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1366,7 +1366,7 @@ pub enum MessageState {
OutDelivered = 26,

/// Outgoing message read by the recipient (two checkmarks; this
/// requires goodwill on the receiver's side). Not used in the db for new messages.
/// requires goodwill on the receiver's side). API-only, not used in the db.
OutMdnRcvd = 28,
}

Expand Down
12 changes: 12 additions & 0 deletions src/sql/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,18 @@ CREATE INDEX gossip_timestamp_index ON gossip_timestamp (chat_id, fingerprint);
.await?;
}

inc_and_check(&mut migration_version, 135)?;
if dbversion < migration_version {
// Tweak the index for `chat::calc_sort_timestamp()`.
sql.execute_migration(
"UPDATE msgs SET state=26 WHERE state=28;
DROP INDEX IF EXISTS msgs_index7;
CREATE INDEX msgs_index7 ON msgs (state, hidden, chat_id, timestamp);",
migration_version,
)
.await?;
}

let new_version = sql
.get_raw_config_int(VERSION_CFG)
.await?
Expand Down
2 changes: 1 addition & 1 deletion src/tests/verified_chats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ async fn test_old_message_5() -> Result<()> {
.await?
.unwrap();

assert!(msg_sent.sort_timestamp == msg_incoming.sort_timestamp);
assert_eq!(msg_sent.sort_timestamp, msg_incoming.sort_timestamp);
alice
.golden_test_chat(msg_sent.chat_id, "test_old_message_5")
.await;
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: bob@example.net [KEY bob@example.net]
--------------------------------------------------------------------------------
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]
--------------------------------------------------------------------------------
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载