mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
Sort message replies after parent message
This commit is contained in:
committed by
link2xt
parent
be922eef0f
commit
763334d0aa
@@ -698,6 +698,20 @@ async fn add_parts(
|
|||||||
let in_fresh = state == MessageState::InFresh;
|
let in_fresh = state == MessageState::InFresh;
|
||||||
let rcvd_timestamp = time();
|
let rcvd_timestamp = time();
|
||||||
let sort_timestamp = calc_sort_timestamp(context, *sent_timestamp, *chat_id, in_fresh).await;
|
let sort_timestamp = calc_sort_timestamp(context, *sent_timestamp, *chat_id, in_fresh).await;
|
||||||
|
|
||||||
|
// Ensure replies to messages are sorted after the parent message.
|
||||||
|
//
|
||||||
|
// This is useful in a case where sender clocks are not
|
||||||
|
// synchronized and parent message has a Date: header with a
|
||||||
|
// timestamp higher than reply timestamp.
|
||||||
|
//
|
||||||
|
// This does not help if parent message arrives later than the
|
||||||
|
// reply.
|
||||||
|
let parent_timestamp = mime_parser.get_parent_timestamp(context).await?;
|
||||||
|
let sort_timestamp = parent_timestamp.map_or(sort_timestamp, |parent_timestamp| {
|
||||||
|
std::cmp::max(sort_timestamp, parent_timestamp)
|
||||||
|
});
|
||||||
|
|
||||||
*sent_timestamp = std::cmp::min(*sent_timestamp, rcvd_timestamp);
|
*sent_timestamp = std::cmp::min(*sent_timestamp, rcvd_timestamp);
|
||||||
|
|
||||||
// unarchive chat
|
// unarchive chat
|
||||||
|
|||||||
@@ -1044,6 +1044,28 @@ impl MimeMessage {
|
|||||||
message::handle_ndn(context, failure_report, error).await
|
message::handle_ndn(context, failure_report, error).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns timestamp of the parent message.
|
||||||
|
///
|
||||||
|
/// If there is no parent message or it is not found in the
|
||||||
|
/// database, returns None.
|
||||||
|
pub async fn get_parent_timestamp(&self, context: &Context) -> Result<Option<i64>> {
|
||||||
|
let parent_timestamp = if let Some(field) = self
|
||||||
|
.get(HeaderDef::InReplyTo)
|
||||||
|
.and_then(|msgid| parse_message_id(msgid).ok())
|
||||||
|
{
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.query_get_value_result(
|
||||||
|
"SELECT timestamp FROM msgs WHERE rfc724_mid=?",
|
||||||
|
paramsv![field],
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok(parent_timestamp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_gossip_peerstates(
|
async fn update_gossip_peerstates(
|
||||||
@@ -1413,6 +1435,39 @@ mod tests {
|
|||||||
assert!(mimeparser.chat_disposition_notification_to.is_none());
|
assert!(mimeparser.chat_disposition_notification_to.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_get_parent_timestamp() {
|
||||||
|
let context = TestContext::new().await;
|
||||||
|
let raw = b"From: foo@example.org\n\
|
||||||
|
Content-Type: text/plain\n\
|
||||||
|
Chat-Version: 1.0\n\
|
||||||
|
In-Reply-To: <Gr.beZgAF2Nn0-.oyaJOpeuT70@example.org>\n\
|
||||||
|
\n\
|
||||||
|
Some reply\n\
|
||||||
|
";
|
||||||
|
let mimeparser = MimeMessage::from_bytes(&context.ctx, &raw[..])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
mimeparser.get_parent_timestamp(&context.ctx).await.unwrap(),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
let timestamp = 1570435529;
|
||||||
|
context
|
||||||
|
.ctx
|
||||||
|
.sql
|
||||||
|
.execute(
|
||||||
|
"INSERT INTO msgs (rfc724_mid, timestamp) VALUES(?,?)",
|
||||||
|
paramsv!["Gr.beZgAF2Nn0-.oyaJOpeuT70@example.org", timestamp],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("Failed to write to the database");
|
||||||
|
assert_eq!(
|
||||||
|
mimeparser.get_parent_timestamp(&context.ctx).await.unwrap(),
|
||||||
|
Some(timestamp)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[async_std::test]
|
#[async_std::test]
|
||||||
async fn test_mimeparser_with_context() {
|
async fn test_mimeparser_with_context() {
|
||||||
let context = TestContext::new().await;
|
let context = TestContext::new().await;
|
||||||
|
|||||||
Reference in New Issue
Block a user