mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 19:06:35 +03:00
contact: synchronize status between devices
This feature is similar to existing avatar synchronization. Whenever encrypted BCC-to-self copy of chat message is received, status setting is updated with the signature of the message.
This commit is contained in:
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
- fix creation of many delete jobs when being offline #2372
|
- fix creation of many delete jobs when being offline #2372
|
||||||
|
|
||||||
|
- synchronize status between devices #2386
|
||||||
|
|
||||||
- deaddrop (contact requests) chat improvements #2373
|
- deaddrop (contact requests) chat improvements #2373
|
||||||
|
|
||||||
- add "Forwarded:" to notification and chatlist summaries #2310
|
- add "Forwarded:" to notification and chatlist summaries #2310
|
||||||
|
|||||||
@@ -1300,13 +1300,31 @@ pub(crate) async fn set_profile_image(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets contact status.
|
/// Sets contact status.
|
||||||
pub(crate) async fn set_status(context: &Context, contact_id: u32, status: String) -> Result<()> {
|
///
|
||||||
let mut contact = Contact::load_from_db(context, contact_id).await?;
|
/// For contact SELF, the status is not saved in the contact table, but as Config::Selfstatus. This
|
||||||
|
/// is only done if message is sent from Delta Chat and it is encrypted, to synchronize signature
|
||||||
|
/// between Delta Chat devices.
|
||||||
|
pub(crate) async fn set_status(
|
||||||
|
context: &Context,
|
||||||
|
contact_id: u32,
|
||||||
|
status: String,
|
||||||
|
encrypted: bool,
|
||||||
|
has_chat_version: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
if contact_id == DC_CONTACT_ID_SELF {
|
||||||
|
if encrypted && has_chat_version {
|
||||||
|
context
|
||||||
|
.set_config(Config::Selfstatus, Some(&status))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut contact = Contact::load_from_db(context, contact_id).await?;
|
||||||
|
|
||||||
if contact.status != status {
|
if contact.status != status {
|
||||||
contact.status = status;
|
contact.status = status;
|
||||||
contact.update_status(context).await?;
|
contact.update_status(context).await?;
|
||||||
context.emit_event(EventType::ContactsChanged(Some(contact_id)));
|
context.emit_event(EventType::ContactsChanged(Some(contact_id)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1397,6 +1415,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::chat::send_text_msg;
|
use crate::chat::send_text_msg;
|
||||||
|
use crate::message::Message;
|
||||||
use crate::test_utils::TestContext;
|
use crate::test_utils::TestContext;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1902,4 +1921,70 @@ CCCB 5AA9 F6E1 141C 9431
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests that status is synchronized when sending encrypted BCC-self messages and not
|
||||||
|
/// synchronized when the message is not encrypted.
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_synchronize_status() -> Result<()> {
|
||||||
|
// Alice has two devices.
|
||||||
|
let alice1 = TestContext::new_alice().await;
|
||||||
|
let alice2 = TestContext::new_alice().await;
|
||||||
|
|
||||||
|
// Bob has one device.
|
||||||
|
let bob = TestContext::new_bob().await;
|
||||||
|
|
||||||
|
let default_status = alice1.get_config(Config::Selfstatus).await?;
|
||||||
|
|
||||||
|
alice1
|
||||||
|
.set_config(Config::Selfstatus, Some("New status"))
|
||||||
|
.await?;
|
||||||
|
let chat = alice1
|
||||||
|
.create_chat_with_contact("Bob", "bob@example.net")
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Alice sends a message to Bob from the first device.
|
||||||
|
send_text_msg(&alice1, chat.id, "Hello".to_string()).await?;
|
||||||
|
let sent_msg = alice1.pop_sent_msg().await;
|
||||||
|
|
||||||
|
// Message is not encrypted.
|
||||||
|
let message = Message::load_from_db(&alice1, sent_msg.sender_msg_id).await?;
|
||||||
|
assert!(!message.get_showpadlock());
|
||||||
|
|
||||||
|
// Alice's second devices receives a copy of outgoing message.
|
||||||
|
alice2.recv_msg(&sent_msg).await;
|
||||||
|
|
||||||
|
// Bob receives message.
|
||||||
|
bob.recv_msg(&sent_msg).await;
|
||||||
|
|
||||||
|
// Message was not encrypted, so status is not copied.
|
||||||
|
assert_eq!(alice2.get_config(Config::Selfstatus).await?, default_status);
|
||||||
|
|
||||||
|
// Bob replies.
|
||||||
|
let chat = bob
|
||||||
|
.create_chat_with_contact("Alice", "alice@example.com")
|
||||||
|
.await;
|
||||||
|
|
||||||
|
send_text_msg(&bob, chat.id, "Reply".to_string()).await?;
|
||||||
|
let sent_msg = bob.pop_sent_msg().await;
|
||||||
|
alice1.recv_msg(&sent_msg).await;
|
||||||
|
alice2.recv_msg(&sent_msg).await;
|
||||||
|
|
||||||
|
// Alice sends second message.
|
||||||
|
send_text_msg(&alice1, chat.id, "Hello".to_string()).await?;
|
||||||
|
let sent_msg = alice1.pop_sent_msg().await;
|
||||||
|
|
||||||
|
// Second message is encrypted.
|
||||||
|
let message = Message::load_from_db(&alice1, sent_msg.sender_msg_id).await?;
|
||||||
|
assert!(message.get_showpadlock());
|
||||||
|
|
||||||
|
// Alice's second devices receives a copy of second outgoing message.
|
||||||
|
alice2.recv_msg(&sent_msg).await;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
alice2.get_config(Config::Selfstatus).await?,
|
||||||
|
Some("New status".to_string())
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,6 +243,8 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
context,
|
context,
|
||||||
from_id,
|
from_id,
|
||||||
mime_parser.footer.clone().unwrap_or_default(),
|
mime_parser.footer.clone().unwrap_or_default(),
|
||||||
|
mime_parser.was_encrypted(),
|
||||||
|
mime_parser.has_chat_version(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user