@@ -224,6 +224,7 @@ impl Context {
224224 context,
225225 wait. try_into ( ) ?,
226226 call. id ,
227+ true , // Doesn't matter for outgoing calls
227228 ) ) ;
228229
229230 Ok ( call. id )
@@ -317,6 +318,7 @@ impl Context {
317318 context : WeakContext ,
318319 wait : u64 ,
319320 call_id : MsgId ,
321+ can_call_me : bool ,
320322 ) -> Result < ( ) > {
321323 sleep ( Duration :: from_secs ( wait) ) . await ;
322324 let context = context. upgrade ( ) ?;
@@ -333,7 +335,9 @@ impl Context {
333335 call. mark_as_canceled ( & context) . await ?;
334336 let missed_call_str = stock_str:: missed_call ( & context) . await ;
335337 call. update_text ( & context, & missed_call_str) . await ?;
336- context. emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
338+ if can_call_me {
339+ context. emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
340+ }
337341 } else {
338342 call. mark_as_ended ( & context) . await ?;
339343 let canceled_call_str = stock_str:: canceled_call ( & context) . await ;
@@ -345,6 +349,30 @@ impl Context {
345349 Ok ( ( ) )
346350 }
347351
352+ async fn can_call_me ( & self , from_id : ContactId ) -> Result < bool > {
353+ Ok ( match who_can_call_me ( self ) . await ? {
354+ WhoCanCallMe :: Contacts => ChatIdBlocked :: lookup_by_contact ( self , from_id)
355+ . await ?
356+ . is_some_and ( |chat_id_blocked| {
357+ match chat_id_blocked. blocked {
358+ Blocked :: Not => true ,
359+ Blocked :: Yes | Blocked :: Request => {
360+ // Do not notify about incoming calls
361+ // from contact requests and blocked contacts.
362+ //
363+ // User can still access the call and accept it
364+ // via the chat in case of contact requests.
365+ false
366+ }
367+ }
368+ } ) ,
369+ WhoCanCallMe :: Everybody => ChatIdBlocked :: lookup_by_contact ( self , from_id)
370+ . await ?
371+ . is_none_or ( |chat_id_blocked| chat_id_blocked. blocked != Blocked :: Yes ) ,
372+ WhoCanCallMe :: Nobody => false ,
373+ } )
374+ }
375+
348376 pub ( crate ) async fn handle_call_msg (
349377 & self ,
350378 call_id : MsgId ,
@@ -358,53 +386,33 @@ impl Context {
358386 } ;
359387
360388 if call. is_incoming ( ) {
361- if call. is_stale ( ) {
362- let missed_call_str = stock_str:: missed_call ( self ) . await ;
363- call. update_text ( self , & missed_call_str) . await ?;
364- // TODO: Don't notify for blocked contacts
365- let ( msg_id, chat_id) = ( call_id, call. msg . chat_id ) ;
389+ let call_str = match call. is_stale ( ) {
390+ true => stock_str:: missed_call ( self ) . await ,
391+ false => stock_str:: incoming_call ( self , call. has_video_initially ( ) ) . await ,
392+ } ;
393+ call. update_text ( self , & call_str) . await ?;
394+ let ( msg_id, chat_id) = ( call_id, call. msg . chat_id ) ;
395+ let can_call_me = self . can_call_me ( from_id) . await ?;
396+ if !can_call_me {
397+ } else if call. is_stale ( ) {
366398 self . emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
367- self . emit_msgs_changed ( chat_id, msg_id) ;
368399 } else {
369- let incoming_call_str =
370- stock_str:: incoming_call ( self , call. has_video_initially ( ) ) . await ;
371- call. update_text ( self , & incoming_call_str) . await ?;
372- self . emit_msgs_changed ( call. msg . chat_id , call_id) ; // ringing calls are not additionally notified
373- let can_call_me = match who_can_call_me ( self ) . await ? {
374- WhoCanCallMe :: Contacts => ChatIdBlocked :: lookup_by_contact ( self , from_id)
375- . await ?
376- . is_some_and ( |chat_id_blocked| {
377- match chat_id_blocked. blocked {
378- Blocked :: Not => true ,
379- Blocked :: Yes | Blocked :: Request => {
380- // Do not notify about incoming calls
381- // from contact requests and blocked contacts.
382- //
383- // User can still access the call and accept it
384- // via the chat in case of contact requests.
385- false
386- }
387- }
388- } ) ,
389- WhoCanCallMe :: Everybody => ChatIdBlocked :: lookup_by_contact ( self , from_id)
390- . await ?
391- . is_none_or ( |chat_id_blocked| chat_id_blocked. blocked != Blocked :: Yes ) ,
392- WhoCanCallMe :: Nobody => false ,
393- } ;
394- if can_call_me {
395- self . emit_event ( EventType :: IncomingCall {
396- msg_id : call. msg . id ,
397- chat_id : call. msg . chat_id ,
398- place_call_info : call. place_call_info . to_string ( ) ,
399- has_video : call. has_video_initially ( ) ,
400- } ) ;
401- }
400+ self . emit_event ( EventType :: IncomingCall {
401+ msg_id,
402+ chat_id,
403+ place_call_info : call. place_call_info . to_string ( ) ,
404+ has_video : call. has_video_initially ( ) ,
405+ } ) ;
406+ }
407+ self . emit_msgs_changed ( chat_id, msg_id) ;
408+ if !call. is_stale ( ) {
402409 let wait = call. remaining_ring_seconds ( ) ;
403410 let context = self . get_weak_context ( ) ;
404411 task:: spawn ( Context :: emit_end_call_if_unaccepted (
405412 context,
406413 wait. try_into ( ) ?,
407414 call. msg . id ,
415+ can_call_me,
408416 ) ) ;
409417 }
410418 } else {
@@ -468,7 +476,9 @@ impl Context {
468476 call. mark_as_canceled ( self ) . await ?;
469477 let missed_call_str = stock_str:: missed_call ( self ) . await ;
470478 call. update_text ( self , & missed_call_str) . await ?;
471- self . emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
479+ if self . can_call_me ( from_id) . await ? {
480+ self . emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
481+ }
472482 }
473483 } else {
474484 // outgoing
0 commit comments