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,44 @@ 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- } ) ;
354+ let can_call_me = match who_can_call_me ( self ) . await ? {
355+ WhoCanCallMe :: Contacts => {
356+ if let Some ( chat_id_blocked) =
357+ ChatIdBlocked :: lookup_by_contact ( self , from_id) . await ?
358+ {
359+ match chat_id_blocked. blocked {
360+ Blocked :: Not => true ,
361+ Blocked :: Yes | Blocked :: Request => {
362+ // Do not notify about incoming calls
363+ // from contact requests and blocked contacts.
364+ //
365+ // User can still access the call and accept it
366+ // via the chat in case of contact requests.
367+ false
368+ }
369+ }
370+ } else {
371+ false
362372 }
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.
373+ }
374+ WhoCanCallMe :: Everybody => {
375+ if let Some ( chat_id_blocked) =
376+ ChatIdBlocked :: lookup_by_contact ( self , from_id) . await ?
377+ {
378+ chat_id_blocked. blocked != Blocked :: Yes
379+ } else {
380+ true
369381 }
370382 }
383+ WhoCanCallMe :: Nobody => false ,
384+ } ;
385+ if can_call_me {
386+ self . emit_event ( EventType :: IncomingCall {
387+ msg_id : call. msg . id ,
388+ chat_id : call. msg . chat_id ,
389+ place_call_info : call. place_call_info . to_string ( ) ,
390+ has_video,
391+ } ) ;
371392 }
372393 let wait = call. remaining_ring_seconds ( ) ;
373394 let context = self . get_weak_context ( ) ;
@@ -712,5 +733,32 @@ pub async fn ice_servers(context: &Context) -> Result<String> {
712733 }
713734}
714735
736+ /// "Who can call me" config options.
737+ #[ derive(
738+ Debug , Default , Display , Clone , Copy , PartialEq , Eq , FromPrimitive , ToPrimitive , FromSql , ToSql ,
739+ ) ]
740+ #[ repr( u8 ) ]
741+ pub enum WhoCanCallMe {
742+ /// Everybody can call me if they are not blocked.
743+ ///
744+ /// This includes contact requests.
745+ Everybody = 0 ,
746+
747+ /// Every contact who is not blocked and not a contact request, can call.
748+ #[ default]
749+ Contacts = 1 ,
750+
751+ /// Nobody can call me.
752+ Nobody = 2 ,
753+ }
754+
755+ /// Returns currently configuration of the "who can call me" option.
756+ async fn who_can_call_me ( context : & Context ) -> Result < WhoCanCallMe > {
757+ let who_can_call_me =
758+ WhoCanCallMe :: from_i32 ( context. get_config_int ( Config :: WhoCanCallMe ) . await ?)
759+ . unwrap_or_default ( ) ;
760+ Ok ( who_can_call_me)
761+ }
762+
715763#[ cfg( test) ]
716764mod calls_tests;
0 commit comments