Resultify Contact::block

This commit is contained in:
link2xt
2021-06-13 01:33:54 +03:00
parent b16785bb62
commit ad7c7e90b3
5 changed files with 62 additions and 50 deletions

View File

@@ -1737,9 +1737,13 @@ pub unsafe extern "C" fn dc_block_contact(
let ctx = &*context;
block_on(async move {
if block == 0 {
Contact::unblock(&ctx, contact_id).await;
Contact::unblock(&ctx, contact_id)
.await
.ok_or_log_msg(&ctx, "Can't unblock contact");
} else {
Contact::block(&ctx, contact_id).await;
Contact::block(&ctx, contact_id)
.await
.ok_or_log_msg(&ctx, "Can't block contact");
}
});
}

View File

@@ -1137,12 +1137,12 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
"block" => {
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
let contact_id = arg1.parse()?;
Contact::block(&context, contact_id).await;
Contact::block(&context, contact_id).await?;
}
"unblock" => {
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
let contact_id = arg1.parse()?;
Contact::unblock(&context, contact_id).await;
Contact::unblock(&context, contact_id).await?;
}
"listblocked" => {
let contacts = Contact::get_all_blocked(&context).await?;

View File

@@ -236,13 +236,13 @@ impl Contact {
}
/// Block the given contact.
pub async fn block(context: &Context, id: u32) {
set_block_contact(context, id, true).await;
pub async fn block(context: &Context, id: u32) -> Result<()> {
set_block_contact(context, id, true).await
}
/// Unblock the given contact.
pub async fn unblock(context: &Context, id: u32) {
set_block_contact(context, id, false).await;
pub async fn unblock(context: &Context, id: u32) -> Result<()> {
set_block_contact(context, id, false).await
}
/// Add a single contact as a result of an _explicit_ user action.
@@ -270,7 +270,7 @@ impl Contact {
}
}
if blocked {
Contact::unblock(context, contact_id).await;
Contact::unblock(context, contact_id).await?;
}
Ok(contact_id)
@@ -1162,56 +1162,58 @@ fn sanitize_name_and_addr(name: &str, addr: &str) -> (String, String) {
}
}
async fn set_block_contact(context: &Context, contact_id: u32, new_blocking: bool) {
if contact_id <= DC_CONTACT_ID_LAST_SPECIAL {
return;
}
async fn set_block_contact(context: &Context, contact_id: u32, new_blocking: bool) -> Result<()> {
ensure!(
contact_id > DC_CONTACT_ID_LAST_SPECIAL,
"Can't block special contact {}",
contact_id
);
if let Ok(contact) = Contact::load_from_db(context, contact_id).await {
if contact.blocked != new_blocking
&& context
.sql
.execute(
"UPDATE contacts SET blocked=? WHERE id=?;",
paramsv![new_blocking as i32, contact_id as i32],
)
.await
.is_ok()
{
// also (un)block all chats with _only_ this contact - we do not delete them to allow a
// non-destructive blocking->unblocking.
// (Maybe, beside normal chats (type=100) we should also block group chats with only this user.
// However, I'm not sure about this point; it may be confusing if the user wants to add other people;
// this would result in recreating the same group...)
if context
.sql
.execute(
r#"
let contact = Contact::load_from_db(context, contact_id).await?;
if contact.blocked != new_blocking {
context
.sql
.execute(
"UPDATE contacts SET blocked=? WHERE id=?;",
paramsv![new_blocking as i32, contact_id as i32],
)
.await?;
// also (un)block all chats with _only_ this contact - we do not delete them to allow a
// non-destructive blocking->unblocking.
// (Maybe, beside normal chats (type=100) we should also block group chats with only this user.
// However, I'm not sure about this point; it may be confusing if the user wants to add other people;
// this would result in recreating the same group...)
if context
.sql
.execute(
r#"
UPDATE chats
SET blocked=?
WHERE type=? AND id IN (
SELECT chat_id FROM chats_contacts WHERE contact_id=?
);
"#,
paramsv![new_blocking, Chattype::Single, contact_id],
)
.await
.is_ok()
{
Contact::mark_noticed(context, contact_id).await;
context.emit_event(EventType::ContactsChanged(Some(contact_id)));
}
paramsv![new_blocking, Chattype::Single, contact_id],
)
.await
.is_ok()
{
Contact::mark_noticed(context, contact_id).await;
context.emit_event(EventType::ContactsChanged(Some(contact_id)));
}
// also unblock mailinglist
// if the contact is a mailinglist address explicitly created to allow unblocking
if !new_blocking && contact.origin == Origin::MailinglistAddress {
if let Ok((chat_id, _, _)) = chat::get_chat_id_by_grpid(context, contact.addr).await
{
chat_id.set_blocked(context, Blocked::Not).await;
}
// also unblock mailinglist
// if the contact is a mailinglist address explicitly created to allow unblocking
if !new_blocking && contact.origin == Origin::MailinglistAddress {
if let Ok((chat_id, _, _)) = chat::get_chat_id_by_grpid(context, contact.addr).await {
chat_id.set_blocked(context, Blocked::Not).await;
}
}
}
Ok(())
}
/// Set profile image for a contact.

View File

@@ -3018,7 +3018,9 @@ mod tests {
assert_eq!(msgs.len(), 0);
// Unblock contact and check if the next message arrives in real chat
Contact::unblock(&t, *blocked.first().unwrap()).await;
Contact::unblock(&t, *blocked.first().unwrap())
.await
.unwrap();
let blocked = Contact::get_all_blocked(&t).await.unwrap();
assert_eq!(blocked.len(), 0);

View File

@@ -1196,7 +1196,11 @@ pub async fn decide_on_contact_request(
Err(e) => warn!(context, "decide_on_contact_request error: {}", e),
},
(Block, false) => Contact::block(context, msg.from_id).await,
(Block, false) => {
if let Err(e) = Contact::block(context, msg.from_id).await {
warn!(context, "Can't block contact: {}", e);
}
}
(Block, true) => {
if !msg.chat_id.set_blocked(context, Blocked::Manually).await {
warn!(context, "Block mailing list failed.")