@@ -36,7 +36,7 @@ use crate::mimefactory::MimeFactory;
36
36
use crate :: mimeparser:: SystemMessage ;
37
37
use crate :: param:: { Param , Params } ;
38
38
use crate :: peerstate:: Peerstate ;
39
- use crate :: receive_imf:: { calc_sort_timestamp , ReceivedMsg } ;
39
+ use crate :: receive_imf:: ReceivedMsg ;
40
40
use crate :: smtp:: send_msg_to_smtp;
41
41
use crate :: sql;
42
42
use crate :: stock_str;
@@ -611,7 +611,9 @@ impl ChatId {
611
611
contact_id : Option < ContactId > ,
612
612
) -> Result < ( ) > {
613
613
let sort_to_bottom = true ;
614
- let ts = calc_sort_timestamp ( context, timestamp_sent, self , sort_to_bottom, false ) . await ?;
614
+ let ts = self
615
+ . calc_sort_timestamp ( context, timestamp_sent, sort_to_bottom, false )
616
+ . await ?;
615
617
self . set_protection_for_timestamp_sort ( context, protect, ts, contact_id)
616
618
. await
617
619
}
@@ -1335,6 +1337,64 @@ impl ChatId {
1335
1337
. unwrap_or_default ( ) ;
1336
1338
Ok ( protection_status)
1337
1339
}
1340
+
1341
+ /// Returns the sort timestamp for a new message in the chat.
1342
+ ///
1343
+ /// `message_timestamp` should be either the message "sent" timestamp or a timestamp of the
1344
+ /// corresponding event in case of a system message (usually the current system time).
1345
+ /// `always_sort_to_bottom` makes this ajust the returned timestamp up so that the message goes
1346
+ /// to the chat bottom.
1347
+ /// `incoming` -- whether the message is incoming.
1348
+ pub ( crate ) async fn calc_sort_timestamp (
1349
+ self ,
1350
+ context : & Context ,
1351
+ message_timestamp : i64 ,
1352
+ always_sort_to_bottom : bool ,
1353
+ incoming : bool ,
1354
+ ) -> Result < i64 > {
1355
+ let mut sort_timestamp = cmp:: min ( message_timestamp, smeared_time ( context) ) ;
1356
+
1357
+ let last_msg_time: Option < i64 > = if always_sort_to_bottom {
1358
+ // get newest message for this chat
1359
+
1360
+ // Let hidden messages also be ordered with protection messages because hidden messages
1361
+ // also can be or not be verified, so let's preserve this information -- even it's not
1362
+ // used currently, it can be useful in the future versions.
1363
+ context
1364
+ . sql
1365
+ . query_get_value (
1366
+ "SELECT MAX(timestamp) FROM msgs WHERE chat_id=? AND state!=?" ,
1367
+ ( self , MessageState :: OutDraft ) ,
1368
+ )
1369
+ . await ?
1370
+ } else if incoming {
1371
+ // get newest non fresh message for this chat.
1372
+
1373
+ // If a user hasn't been online for some time, the Inbox is fetched first and then the
1374
+ // Sentbox. In order for Inbox and Sent messages to be allowed to mingle, outgoing
1375
+ // messages are purely sorted by their sent timestamp. NB: The Inbox must be fetched
1376
+ // first otherwise Inbox messages would be always below old Sentbox messages. We could
1377
+ // take in the query below only incoming messages, but then new incoming messages would
1378
+ // mingle with just sent outgoing ones and apear somewhere in the middle of the chat.
1379
+ context
1380
+ . sql
1381
+ . query_get_value (
1382
+ "SELECT MAX(timestamp) FROM msgs WHERE chat_id=? AND hidden=0 AND state>?" ,
1383
+ ( self , MessageState :: InFresh ) ,
1384
+ )
1385
+ . await ?
1386
+ } else {
1387
+ None
1388
+ } ;
1389
+
1390
+ if let Some ( last_msg_time) = last_msg_time {
1391
+ if last_msg_time > sort_timestamp {
1392
+ sort_timestamp = last_msg_time;
1393
+ }
1394
+ }
1395
+
1396
+ Ok ( sort_timestamp)
1397
+ }
1338
1398
}
1339
1399
1340
1400
impl std:: fmt:: Display for ChatId {
0 commit comments