44//! This means, the "Call ID" is a "Message ID" - similar to Webxdc IDs.
55use crate :: chat:: ChatIdBlocked ;
66use crate :: chat:: { Chat , ChatId , send_msg} ;
7+ use crate :: config:: Config ;
78use crate :: constants:: { Blocked , Chattype } ;
89use crate :: contact:: ContactId ;
910use crate :: context:: { Context , WeakContext } ;
@@ -16,6 +17,8 @@ use crate::net::dns::lookup_host_with_cache;
1617use crate :: param:: Param ;
1718use crate :: tools:: { normalize_text, time} ;
1819use anyhow:: { Context as _, Result , ensure} ;
20+ use deltachat_derive:: { FromSql , ToSql } ;
21+ use num_traits:: FromPrimitive ;
1922use sdp:: SessionDescription ;
2023use serde:: Serialize ;
2124use std:: io:: Cursor ;
@@ -348,26 +351,34 @@ impl Context {
348351 false
349352 }
350353 } ;
351- if let Some ( chat_id_blocked) =
352- ChatIdBlocked :: lookup_by_contact ( self , from_id) . await ?
353- {
354- match chat_id_blocked. blocked {
355- Blocked :: Not => {
356- self . emit_event ( EventType :: IncomingCall {
357- msg_id : call. msg . id ,
358- chat_id : call. msg . chat_id ,
359- place_call_info : call. place_call_info . to_string ( ) ,
360- has_video,
361- } ) ;
362- }
363- Blocked :: Yes | Blocked :: Request => {
364- // Do not notify about incoming calls
365- // from contact requests and blocked contacts.
366- //
367- // User can still access the call and accept it
368- // via the chat in case of contact requests.
369- }
370- }
354+ let can_call_me = match who_can_call_me ( self ) . await ? {
355+ WhoCanCallMe :: Contacts => ChatIdBlocked :: lookup_by_contact ( self , from_id)
356+ . await ?
357+ . is_some_and ( |chat_id_blocked| {
358+ match chat_id_blocked. blocked {
359+ Blocked :: Not => true ,
360+ Blocked :: Yes | Blocked :: Request => {
361+ // Do not notify about incoming calls
362+ // from contact requests and blocked contacts.
363+ //
364+ // User can still access the call and accept it
365+ // via the chat in case of contact requests.
366+ false
367+ }
368+ }
369+ } ) ,
370+ WhoCanCallMe :: Everybody => ChatIdBlocked :: lookup_by_contact ( self , from_id)
371+ . await ?
372+ . is_none_or ( |chat_id_blocked| chat_id_blocked. blocked != Blocked :: Yes ) ,
373+ WhoCanCallMe :: Nobody => false ,
374+ } ;
375+ if can_call_me {
376+ self . emit_event ( EventType :: IncomingCall {
377+ msg_id : call. msg . id ,
378+ chat_id : call. msg . chat_id ,
379+ place_call_info : call. place_call_info . to_string ( ) ,
380+ has_video,
381+ } ) ;
371382 }
372383 let wait = call. remaining_ring_seconds ( ) ;
373384 let context = self . get_weak_context ( ) ;
@@ -712,5 +723,32 @@ pub async fn ice_servers(context: &Context) -> Result<String> {
712723 }
713724}
714725
726+ /// "Who can call me" config options.
727+ #[ derive(
728+ Debug , Default , Display , Clone , Copy , PartialEq , Eq , FromPrimitive , ToPrimitive , FromSql , ToSql ,
729+ ) ]
730+ #[ repr( u8 ) ]
731+ pub enum WhoCanCallMe {
732+ /// Everybody can call me if they are not blocked.
733+ ///
734+ /// This includes contact requests.
735+ Everybody = 0 ,
736+
737+ /// Every contact who is not blocked and not a contact request, can call.
738+ #[ default]
739+ Contacts = 1 ,
740+
741+ /// Nobody can call me.
742+ Nobody = 2 ,
743+ }
744+
745+ /// Returns currently configuration of the "who can call me" option.
746+ async fn who_can_call_me ( context : & Context ) -> Result < WhoCanCallMe > {
747+ let who_can_call_me =
748+ WhoCanCallMe :: from_i32 ( context. get_config_int ( Config :: WhoCanCallMe ) . await ?)
749+ . unwrap_or_default ( ) ;
750+ Ok ( who_can_call_me)
751+ }
752+
715753#[ cfg( test) ]
716754mod calls_tests;
0 commit comments