Skip to content

Commit

Permalink
fix: Order of messages if Sentbox is synced before Inbox
Browse files Browse the repository at this point in the history
This fixes a Gmail-like scenario when outgoing messages are saved to Sentbox as well and it is
fetched before Inbox by chance, by adding a new `OutRcvd` message state for received outgoing
messages so that they can mingle with fresh incoming ones and appear after them in chats. As for
`OutPending`, `OutDelivered` etc. messages, they are sent locally by the user and there's no need to
make them more noticeable even if they are newer.
  • Loading branch information
iequidoo committed Oct 12, 2024
1 parent 716e908 commit ce4be1d
Show file tree
Hide file tree
Showing 11 changed files with 29 additions and 19 deletions.
2 changes: 1 addition & 1 deletion deltachat-ffi/src/lot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl From<MessageState> for LotState {
OutDraft => LotState::MsgOutDraft,
OutPending => LotState::MsgOutPending,
OutFailed => LotState::MsgOutFailed,
OutDelivered => LotState::MsgOutDelivered,
OutDelivered | OutRcvd => LotState::MsgOutDelivered,
OutMdnRcvd => LotState::MsgOutMdnRcvd,
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1437,9 +1437,14 @@ impl ChatId {
.query_row_optional(
"SELECT MAX(timestamp), MAX(IIF(state=?,timestamp_sent,0))
FROM msgs
WHERE chat_id=? AND hidden=0 AND state>?
WHERE chat_id=? AND hidden=0 AND state>? AND state!=?
HAVING COUNT(*) > 0",
(MessageState::InSeen, self, MessageState::InFresh),
(
MessageState::InSeen,
self,
MessageState::InFresh,
MessageState::OutRcvd,
),
|row| {
let ts: i64 = row.get(0)?;
let ts_sent_incoming: i64 = row.get(1)?;
Expand Down Expand Up @@ -4247,6 +4252,7 @@ pub async fn resend_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> {
MessageState::OutPending
| MessageState::OutFailed
| MessageState::OutDelivered
| MessageState::OutRcvd
| MessageState::OutMdnRcvd => {
message::update_msg_state(context, msg.id, MessageState::OutPending).await?
}
Expand Down
12 changes: 9 additions & 3 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,9 @@ pub enum MessageState {
/// the OutFailed state if we get such a hint from the server.
OutDelivered = 26,

/// Received outgoing message sent by another MUA or device.
OutRcvd = 27,

/// Outgoing message read by the recipient (two checkmarks; this
/// requires goodwill on the receiver's side). Not used in the db for new messages.
OutMdnRcvd = 28,
Expand All @@ -1402,6 +1405,7 @@ impl std::fmt::Display for MessageState {
Self::OutPending => "Pending",
Self::OutFailed => "Failed",
Self::OutDelivered => "Delivered",
Self::OutRcvd => "Other MUA",
Self::OutMdnRcvd => "Read",
}
)
Expand All @@ -1414,7 +1418,9 @@ impl MessageState {
use MessageState::*;
matches!(
self,
OutPreparing | OutPending | OutDelivered | OutMdnRcvd // OutMdnRcvd can still fail because it could be a group message and only some recipients failed.
// OutMdnRcvd can still fail because it could be a group message and only some
// recipients failed.
OutPreparing | OutPending | OutDelivered | OutRcvd | OutMdnRcvd
)
}

Expand All @@ -1423,13 +1429,13 @@ impl MessageState {
use MessageState::*;
matches!(
self,
OutPreparing | OutDraft | OutPending | OutFailed | OutDelivered | OutMdnRcvd
OutPreparing | OutDraft | OutPending | OutFailed | OutDelivered | OutRcvd | OutMdnRcvd
)
}

/// Returns adjusted message state if the message has MDNs.
pub(crate) fn with_mdns(self, has_mdns: bool) -> Self {
if self == MessageState::OutDelivered && has_mdns {
if has_mdns && self >= MessageState::OutDelivered {
return MessageState::OutMdnRcvd;
}
self
Expand Down
4 changes: 2 additions & 2 deletions src/mimeparser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3765,7 +3765,7 @@ Message.
)
.await?;
let msg = alice.get_last_msg().await;
assert_eq!(msg.state, MessageState::OutDelivered);
assert_eq!(msg.state, MessageState::OutRcvd);

// Due to a bug in the old version running on the other device, Alice receives a read
// receipt from self.
Expand Down Expand Up @@ -3804,7 +3804,7 @@ Message.

// Check that the state has not changed to `MessageState::OutMdnRcvd`.
let msg = Message::load_from_db(&alice, msg.id).await?;
assert_eq!(msg.state, MessageState::OutDelivered);
assert_eq!(msg.state, MessageState::OutRcvd);

Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion src/reaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ Can we chat at 1pm pacific, today?"
)
.await?;
let msg = alice.get_last_msg().await;
assert_eq!(msg.state, MessageState::OutDelivered);
assert_eq!(msg.state, MessageState::OutRcvd);
let reactions = get_msg_reactions(&alice, msg.id).await?;
let contacts = reactions.contacts();
assert_eq!(contacts.len(), 0);
Expand Down
4 changes: 1 addition & 3 deletions src/receive_imf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,9 +1027,7 @@ async fn add_parts(
} else {
// Outgoing

// the mail is on the IMAP server, probably it is also delivered.
// We cannot recreate other states (read, error).
state = MessageState::OutDelivered;
state = MessageState::OutRcvd;
to_id = to_ids.first().copied().unwrap_or_default();

let self_sent =
Expand Down
6 changes: 3 additions & 3 deletions src/receive_imf/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ async fn test_read_receipt_and_unarchive() -> Result<()> {
let msg = get_chat_msg(&t, group_id, 0, 1).await;
assert_eq!(msg.is_dc_message, MessengerMessage::Yes);
assert_eq!(msg.text, "hello");
assert_eq!(msg.state, MessageState::OutDelivered);
assert_eq!(msg.state, MessageState::OutRcvd);
let group = Chat::load_from_db(&t, group_id).await?;
assert!(group.get_visibility() == ChatVisibility::Normal);

Expand Down Expand Up @@ -793,7 +793,7 @@ async fn test_parse_ndn(
if error_msg.is_some() {
MessageState::OutFailed
} else {
MessageState::OutDelivered
MessageState::OutRcvd
}
);

Expand Down Expand Up @@ -4537,7 +4537,7 @@ async fn test_outgoing_msg_forgery() -> Result<()> {

let sent_msg = malice.send_text(malice_chat_id, "hi from malice").await;
let msg = alice.recv_msg(&sent_msg).await;
assert_eq!(msg.state, MessageState::OutDelivered);
assert_eq!(msg.state, MessageState::OutRcvd);
assert!(!msg.get_showpadlock());

Ok(())
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 @@ -539,7 +539,7 @@ async fn test_old_message_5() -> Result<()> {
.await?
.unwrap();

assert!(msg_sent.sort_timestamp == msg_incoming.sort_timestamp);
assert!(msg_incoming.sort_timestamp < msg_sent.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/receive_imf_older_message_from_2nd_device
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Single#Chat#10: [email protected] [[email protected]]
--------------------------------------------------------------------------------
Msg#10: Me (Contact#Contact#Self): We share this account √
Msg#11: Me (Contact#Contact#Self): I'm Alice too
Msg#11: Me (Contact#Contact#Self): I'm Alice too
--------------------------------------------------------------------------------
2 changes: 1 addition & 1 deletion test-data/golden/test_old_message_5
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Single#Chat#10: Bob [[email protected]]
--------------------------------------------------------------------------------
Msg#10: Me (Contact#Contact#Self): Happy birthday, Bob! √
Msg#11: (Contact#Contact#10): Happy birthday to me, Alice! [FRESH]
Msg#10: Me (Contact#Contact#Self): Happy birthday, Bob!
--------------------------------------------------------------------------------
2 changes: 1 addition & 1 deletion test-data/golden/test_outgoing_mua_msg
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ Single#Chat#10: [email protected] [[email protected]] 🛡️
--------------------------------------------------------------------------------
Msg#10: info (Contact#Contact#Info): Messages are guaranteed to be end-to-end encrypted from now on. [NOTICED][INFO 🛡️]
Msg#11🔒: (Contact#Contact#10): Heyho from DC [FRESH]
Msg#12: Me (Contact#Contact#Self): One classical MUA message
Msg#12: Me (Contact#Contact#Self): One classical MUA message
Msg#13🔒: Me (Contact#Contact#Self): Sending with DC again √
--------------------------------------------------------------------------------

0 comments on commit ce4be1d

Please sign in to comment.