mirror of
https://github.com/chatmail/core.git
synced 2026-05-04 13:56:30 +03:00
feat: Sync Contact::blocked across devices (#4817)
This commit is contained in:
11
src/chat.rs
11
src/chat.rs
@@ -372,7 +372,7 @@ impl ChatId {
|
||||
context,
|
||||
"Blocking the contact {contact_id} to block 1:1 chat."
|
||||
);
|
||||
Contact::block(context, contact_id).await?;
|
||||
Contact::block(&context.nosync(), contact_id).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,6 +388,7 @@ impl ChatId {
|
||||
}
|
||||
|
||||
if !nosync {
|
||||
// NB: For a 1:1 chat this currently triggers `Contact::block()` on other devices.
|
||||
chat.add_sync_item(context, ChatAction::Block).await?;
|
||||
}
|
||||
Ok(())
|
||||
@@ -401,6 +402,9 @@ impl ChatId {
|
||||
|
||||
if !nosync {
|
||||
let chat = Chat::load_from_db(context, self).await?;
|
||||
// TODO: For a 1:1 chat this currently triggers `Contact::unblock()` on other devices.
|
||||
// Maybe we should unblock the contact locally too, this would also resolve discrepancy
|
||||
// with `block()` which also blocks the contact.
|
||||
chat.add_sync_item(context, ChatAction::Unblock).await?;
|
||||
}
|
||||
Ok(())
|
||||
@@ -4035,6 +4039,11 @@ impl Context {
|
||||
warn!(self, "sync_alter_chat: No contact for addr '{addr}'.");
|
||||
return Ok(());
|
||||
};
|
||||
match &data.action {
|
||||
ChatAction::Block => return Contact::block(self, contact_id).await,
|
||||
ChatAction::Unblock => return Contact::unblock(self, contact_id).await,
|
||||
_ => (),
|
||||
}
|
||||
let Some(chat_id) = ChatId::lookup_by_contact(self, contact_id).await? else {
|
||||
warn!(self, "sync_alter_chat: No chat for addr '{addr}'.");
|
||||
return Ok(());
|
||||
|
||||
@@ -32,6 +32,7 @@ use crate::mimeparser::AvatarAction;
|
||||
use crate::param::{Param, Params};
|
||||
use crate::peerstate::{Peerstate, PeerstateVerifiedStatus};
|
||||
use crate::sql::{self, params_iter};
|
||||
use crate::sync::{self, SyncData};
|
||||
use crate::tools::{
|
||||
duration_to_str, get_abs_path, improve_single_line_input, strip_rtlo_characters, time,
|
||||
EmailAddress,
|
||||
@@ -494,7 +495,7 @@ impl Contact {
|
||||
}
|
||||
}
|
||||
if blocked {
|
||||
Contact::unblock(context, contact_id).await?;
|
||||
Contact::unblock(&context.nosync(), contact_id).await?;
|
||||
}
|
||||
|
||||
Ok(contact_id)
|
||||
@@ -1393,6 +1394,7 @@ async fn set_block_contact(
|
||||
"Can't block special contact {}",
|
||||
contact_id
|
||||
);
|
||||
let (context, nosync) = &context.unwrap_nosync();
|
||||
|
||||
let contact = Contact::get_by_id(context, contact_id).await?;
|
||||
|
||||
@@ -1438,6 +1440,19 @@ WHERE type=? AND id IN (
|
||||
chat_id.unblock(&context.nosync()).await?;
|
||||
}
|
||||
}
|
||||
|
||||
if !nosync {
|
||||
let action = match new_blocking {
|
||||
true => sync::ChatAction::Block,
|
||||
false => sync::ChatAction::Unblock,
|
||||
};
|
||||
context
|
||||
.add_sync_item(SyncData::AlterChat(sync::AlterChatData {
|
||||
id: sync::ChatId::ContactAddr(contact.addr.clone()),
|
||||
action,
|
||||
}))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
20
src/sync.rs
20
src/sync.rs
@@ -36,15 +36,7 @@ pub(crate) enum ChatId {
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub(crate) enum ChatAction {
|
||||
Block,
|
||||
// TODO: Actually unblocking a chat is not a public API. `Contact::unblock()` is what a user
|
||||
// does actually, but it doesn't call `chat::ChatId::unblock()`. So, unblocking chats sync
|
||||
// doesn't work now, but let it be implemented on chats nevertheless. The straightforward fix is
|
||||
// to call `chat::ChatId::unblock()` in a context of user action.
|
||||
//
|
||||
// But it still works if a message is sent to a blocked contact because
|
||||
// `chat::ChatId::unblock()` is called then.
|
||||
Unblock,
|
||||
|
||||
Accept,
|
||||
SetVisibility(ChatVisibility),
|
||||
SetMuted(chat::MuteDuration),
|
||||
@@ -604,6 +596,18 @@ mod tests {
|
||||
sync(&alices).await?;
|
||||
assert_eq!(alices[1].get_chat(&bob).await.blocked, Blocked::Not);
|
||||
|
||||
// Unblocking a 1:1 chat doesn't unblock the contact currently.
|
||||
let a0b_contact_id = alices[0].add_or_lookup_contact(&bob).await.id;
|
||||
Contact::unblock(&alices[0], a0b_contact_id).await?;
|
||||
|
||||
assert!(!alices[1].add_or_lookup_contact(&bob).await.is_blocked());
|
||||
Contact::block(&alices[0], a0b_contact_id).await?;
|
||||
sync(&alices).await?;
|
||||
assert!(alices[1].add_or_lookup_contact(&bob).await.is_blocked());
|
||||
Contact::unblock(&alices[0], a0b_contact_id).await?;
|
||||
sync(&alices).await?;
|
||||
assert!(!alices[1].add_or_lookup_contact(&bob).await.is_blocked());
|
||||
|
||||
assert_eq!(
|
||||
alices[1].get_chat(&bob).await.get_visibility(),
|
||||
ChatVisibility::Normal
|
||||
|
||||
Reference in New Issue
Block a user