@@ -218,10 +218,11 @@ impl Context {
218218
219219 let wait = RINGING_SECONDS ;
220220 let context = self . get_weak_context ( ) ;
221- task:: spawn ( Context :: emit_end_call_if_unaccepted (
221+ task:: spawn ( Context :: finalize_call_if_unaccepted (
222222 context,
223223 wait. try_into ( ) ?,
224224 call. id ,
225+ true , // Doesn't matter for outgoing calls
225226 ) ) ;
226227
227228 Ok ( call. id )
@@ -314,39 +315,67 @@ impl Context {
314315 Ok ( ( ) )
315316 }
316317
317- async fn emit_end_call_if_unaccepted (
318+ async fn finalize_call_if_unaccepted (
318319 context : WeakContext ,
319320 wait : u64 ,
320321 call_id : MsgId ,
322+ can_call_me : bool ,
321323 ) -> Result < ( ) > {
322324 sleep ( Duration :: from_secs ( wait) ) . await ;
323325 let context = context. upgrade ( ) ?;
324326 let Some ( mut call) = context. load_call_by_id ( call_id) . await ? else {
325327 warn ! (
326328 context,
327- "emit_end_call_if_unaccepted is called with {call_id} which does not refer to a call."
329+ "finalize_call_if_unaccepted is called with {call_id} which does not refer to a call."
328330 ) ;
329331 return Ok ( ( ) ) ;
330332 } ;
331333 if !call. is_accepted ( ) && !call. is_ended ( ) {
334+ let ( msg_id, chat_id) = ( call_id, call. msg . chat_id ) ;
332335 if call. is_incoming ( ) {
333336 call. mark_as_canceled ( & context) . await ?;
334337 let missed_call_str = stock_str:: missed_call ( & context) ;
335338 call. update_text ( & context, & missed_call_str) . await ?;
339+ if can_call_me {
340+ context. emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
341+ }
336342 } else {
337343 call. mark_as_ended ( & context) . await ?;
338344 let canceled_call_str = stock_str:: canceled_call ( & context) ;
339345 call. update_text ( & context, & canceled_call_str) . await ?;
340346 }
347+ if can_call_me {
348+ context. emit_event ( EventType :: CallEnded { msg_id, chat_id } ) ;
349+ }
341350 context. emit_msgs_changed ( call. msg . chat_id , call_id) ;
342- context. emit_event ( EventType :: CallEnded {
343- msg_id : call. msg . id ,
344- chat_id : call. msg . chat_id ,
345- } ) ;
346351 }
347352 Ok ( ( ) )
348353 }
349354
355+ async fn can_call_me ( & self , from_id : ContactId ) -> Result < bool > {
356+ Ok ( match who_can_call_me ( self ) . await ? {
357+ WhoCanCallMe :: Contacts => ChatIdBlocked :: lookup_by_contact ( self , from_id)
358+ . await ?
359+ . is_some_and ( |chat_id_blocked| {
360+ match chat_id_blocked. blocked {
361+ Blocked :: Not => true ,
362+ Blocked :: Yes | Blocked :: Request => {
363+ // Do not notify about incoming calls
364+ // from contact requests and blocked contacts.
365+ //
366+ // User can still access the call and accept it
367+ // via the chat in case of contact requests.
368+ false
369+ }
370+ }
371+ } ) ,
372+ WhoCanCallMe :: Everybody => ChatIdBlocked :: lookup_by_contact ( self , from_id)
373+ . await ?
374+ . is_none_or ( |chat_id_blocked| chat_id_blocked. blocked != Blocked :: Yes ) ,
375+ WhoCanCallMe :: Nobody => false ,
376+ } )
377+ }
378+
350379 pub ( crate ) async fn handle_call_msg (
351380 & self ,
352381 call_id : MsgId ,
@@ -360,50 +389,33 @@ impl Context {
360389 } ;
361390
362391 if call. is_incoming ( ) {
363- if call. is_stale ( ) {
364- let missed_call_str = stock_str:: missed_call ( self ) ;
365- call. update_text ( self , & missed_call_str) . await ?;
366- self . emit_incoming_msg ( call. msg . chat_id , call_id) ; // notify missed call
392+ let call_str = match call. is_stale ( ) {
393+ true => stock_str:: missed_call ( self ) ,
394+ false => stock_str:: incoming_call ( self , call. has_video_initially ( ) ) ,
395+ } ;
396+ call. update_text ( self , & call_str) . await ?;
397+ let ( msg_id, chat_id) = ( call_id, call. msg . chat_id ) ;
398+ let can_call_me = self . can_call_me ( from_id) . await ?;
399+ if !can_call_me {
400+ } else if call. is_stale ( ) {
401+ self . emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
367402 } else {
368- let incoming_call_str =
369- stock_str:: incoming_call ( self , call. has_video_initially ( ) ) ;
370- call. update_text ( self , & incoming_call_str) . await ?;
371- self . emit_msgs_changed ( call. msg . chat_id , call_id) ; // ringing calls are not additionally notified
372- let can_call_me = match who_can_call_me ( self ) . await ? {
373- WhoCanCallMe :: Contacts => ChatIdBlocked :: lookup_by_contact ( self , from_id)
374- . await ?
375- . is_some_and ( |chat_id_blocked| {
376- match chat_id_blocked. blocked {
377- Blocked :: Not => true ,
378- Blocked :: Yes | Blocked :: Request => {
379- // Do not notify about incoming calls
380- // from contact requests and blocked contacts.
381- //
382- // User can still access the call and accept it
383- // via the chat in case of contact requests.
384- false
385- }
386- }
387- } ) ,
388- WhoCanCallMe :: Everybody => ChatIdBlocked :: lookup_by_contact ( self , from_id)
389- . await ?
390- . is_none_or ( |chat_id_blocked| chat_id_blocked. blocked != Blocked :: Yes ) ,
391- WhoCanCallMe :: Nobody => false ,
392- } ;
393- if can_call_me {
394- self . emit_event ( EventType :: IncomingCall {
395- msg_id : call. msg . id ,
396- chat_id : call. msg . chat_id ,
397- place_call_info : call. place_call_info . to_string ( ) ,
398- has_video : call. has_video_initially ( ) ,
399- } ) ;
400- }
403+ self . emit_event ( EventType :: IncomingCall {
404+ msg_id,
405+ chat_id,
406+ place_call_info : call. place_call_info . to_string ( ) ,
407+ has_video : call. has_video_initially ( ) ,
408+ } ) ;
409+ }
410+ self . emit_msgs_changed ( chat_id, msg_id) ;
411+ if !call. is_stale ( ) {
401412 let wait = call. remaining_ring_seconds ( ) ;
402413 let context = self . get_weak_context ( ) ;
403- task:: spawn ( Context :: emit_end_call_if_unaccepted (
414+ task:: spawn ( Context :: finalize_call_if_unaccepted (
404415 context,
405416 wait. try_into ( ) ?,
406417 call. msg . id ,
418+ can_call_me,
407419 ) ) ;
408420 }
409421 } else {
@@ -455,6 +467,7 @@ impl Context {
455467 return Ok ( ( ) ) ;
456468 }
457469
470+ let ( msg_id, chat_id) = ( call_id, call. msg . chat_id ) ;
458471 if !call. is_accepted ( ) {
459472 if call. is_incoming ( ) {
460473 if from_id == ContactId :: SELF {
@@ -465,6 +478,9 @@ impl Context {
465478 call. mark_as_canceled ( self ) . await ?;
466479 let missed_call_str = stock_str:: missed_call ( self ) ;
467480 call. update_text ( self , & missed_call_str) . await ?;
481+ if self . can_call_me ( from_id) . await ? {
482+ self . emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
483+ }
468484 }
469485 } else {
470486 // outgoing
@@ -482,12 +498,8 @@ impl Context {
482498 call. mark_as_ended ( self ) . await ?;
483499 call. update_text_duration ( self ) . await ?;
484500 }
485-
501+ self . emit_event ( EventType :: CallEnded { msg_id , chat_id } ) ;
486502 self . emit_msgs_changed ( call. msg . chat_id , call_id) ;
487- self . emit_event ( EventType :: CallEnded {
488- msg_id : call. msg . id ,
489- chat_id : call. msg . chat_id ,
490- } ) ;
491503 }
492504 _ => { }
493505 }
0 commit comments