@@ -220,10 +220,11 @@ impl Context {
220220
221221 let wait = RINGING_SECONDS ;
222222 let context = self . get_weak_context ( ) ;
223- task:: spawn ( Context :: emit_end_call_if_unaccepted (
223+ task:: spawn ( Context :: finalize_call_if_unaccepted (
224224 context,
225225 wait. try_into ( ) ?,
226226 call. id ,
227+ true , // Doesn't matter for outgoing calls
227228 ) ) ;
228229
229230 Ok ( call. id )
@@ -313,39 +314,67 @@ impl Context {
313314 Ok ( ( ) )
314315 }
315316
316- async fn emit_end_call_if_unaccepted (
317+ async fn finalize_call_if_unaccepted (
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 ( ) ?;
323325 let Some ( mut call) = context. load_call_by_id ( call_id) . await ? else {
324326 warn ! (
325327 context,
326- "emit_end_call_if_unaccepted is called with {call_id} which does not refer to a call."
328+ "finalize_call_if_unaccepted is called with {call_id} which does not refer to a call."
327329 ) ;
328330 return Ok ( ( ) ) ;
329331 } ;
330332 if !call. is_accepted ( ) && !call. is_ended ( ) {
333+ let ( msg_id, chat_id) = ( call_id, call. msg . chat_id ) ;
331334 if call. is_incoming ( ) {
332335 call. mark_as_canceled ( & context) . await ?;
333336 let missed_call_str = stock_str:: missed_call ( & context) . await ;
334337 call. update_text ( & context, & missed_call_str) . await ?;
338+ if can_call_me {
339+ context. emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
340+ }
335341 } else {
336342 call. mark_as_ended ( & context) . await ?;
337343 let canceled_call_str = stock_str:: canceled_call ( & context) . await ;
338344 call. update_text ( & context, & canceled_call_str) . await ?;
339345 }
346+ if can_call_me {
347+ context. emit_event ( EventType :: CallEnded { msg_id, chat_id } ) ;
348+ }
340349 context. emit_msgs_changed ( call. msg . chat_id , call_id) ;
341- context. emit_event ( EventType :: CallEnded {
342- msg_id : call. msg . id ,
343- chat_id : call. msg . chat_id ,
344- } ) ;
345350 }
346351 Ok ( ( ) )
347352 }
348353
354+ async fn can_call_me ( & self , from_id : ContactId ) -> Result < bool > {
355+ Ok ( match who_can_call_me ( self ) . await ? {
356+ WhoCanCallMe :: Contacts => ChatIdBlocked :: lookup_by_contact ( self , from_id)
357+ . await ?
358+ . is_some_and ( |chat_id_blocked| {
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+ } ) ,
371+ WhoCanCallMe :: Everybody => ChatIdBlocked :: lookup_by_contact ( self , from_id)
372+ . await ?
373+ . is_none_or ( |chat_id_blocked| chat_id_blocked. blocked != Blocked :: Yes ) ,
374+ WhoCanCallMe :: Nobody => false ,
375+ } )
376+ }
377+
349378 pub ( crate ) async fn handle_call_msg (
350379 & self ,
351380 call_id : MsgId ,
@@ -359,50 +388,33 @@ impl Context {
359388 } ;
360389
361390 if call. is_incoming ( ) {
362- if call. is_stale ( ) {
363- let missed_call_str = stock_str:: missed_call ( self ) . await ;
364- call. update_text ( self , & missed_call_str) . await ?;
365- self . emit_incoming_msg ( call. msg . chat_id , call_id) ; // notify missed call
391+ let call_str = match call. is_stale ( ) {
392+ true => stock_str:: missed_call ( self ) . await ,
393+ false => stock_str:: incoming_call ( self , call. has_video_initially ( ) ) . await ,
394+ } ;
395+ call. update_text ( self , & call_str) . await ?;
396+ let ( msg_id, chat_id) = ( call_id, call. msg . chat_id ) ;
397+ let can_call_me = self . can_call_me ( from_id) . await ?;
398+ if !can_call_me {
399+ } else if call. is_stale ( ) {
400+ self . emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
366401 } else {
367- let incoming_call_str =
368- stock_str:: incoming_call ( self , call. has_video_initially ( ) ) . await ;
369- call. update_text ( self , & incoming_call_str) . await ?;
370- self . emit_msgs_changed ( call. msg . chat_id , call_id) ; // ringing calls are not additionally notified
371- let can_call_me = match who_can_call_me ( self ) . await ? {
372- WhoCanCallMe :: Contacts => ChatIdBlocked :: lookup_by_contact ( self , from_id)
373- . await ?
374- . is_some_and ( |chat_id_blocked| {
375- match chat_id_blocked. blocked {
376- Blocked :: Not => true ,
377- Blocked :: Yes | Blocked :: Request => {
378- // Do not notify about incoming calls
379- // from contact requests and blocked contacts.
380- //
381- // User can still access the call and accept it
382- // via the chat in case of contact requests.
383- false
384- }
385- }
386- } ) ,
387- WhoCanCallMe :: Everybody => ChatIdBlocked :: lookup_by_contact ( self , from_id)
388- . await ?
389- . is_none_or ( |chat_id_blocked| chat_id_blocked. blocked != Blocked :: Yes ) ,
390- WhoCanCallMe :: Nobody => false ,
391- } ;
392- if can_call_me {
393- self . emit_event ( EventType :: IncomingCall {
394- msg_id : call. msg . id ,
395- chat_id : call. msg . chat_id ,
396- place_call_info : call. place_call_info . to_string ( ) ,
397- has_video : call. has_video_initially ( ) ,
398- } ) ;
399- }
402+ self . emit_event ( EventType :: IncomingCall {
403+ msg_id,
404+ chat_id,
405+ place_call_info : call. place_call_info . to_string ( ) ,
406+ has_video : call. has_video_initially ( ) ,
407+ } ) ;
408+ }
409+ self . emit_msgs_changed ( chat_id, msg_id) ;
410+ if !call. is_stale ( ) {
400411 let wait = call. remaining_ring_seconds ( ) ;
401412 let context = self . get_weak_context ( ) ;
402- task:: spawn ( Context :: emit_end_call_if_unaccepted (
413+ task:: spawn ( Context :: finalize_call_if_unaccepted (
403414 context,
404415 wait. try_into ( ) ?,
405416 call. msg . id ,
417+ can_call_me,
406418 ) ) ;
407419 }
408420 } else {
@@ -454,6 +466,7 @@ impl Context {
454466 return Ok ( ( ) ) ;
455467 }
456468
469+ let ( msg_id, chat_id) = ( call_id, call. msg . chat_id ) ;
457470 if !call. is_accepted ( ) {
458471 if call. is_incoming ( ) {
459472 if from_id == ContactId :: SELF {
@@ -464,6 +477,9 @@ impl Context {
464477 call. mark_as_canceled ( self ) . await ?;
465478 let missed_call_str = stock_str:: missed_call ( self ) . await ;
466479 call. update_text ( self , & missed_call_str) . await ?;
480+ if self . can_call_me ( from_id) . await ? {
481+ self . emit_event ( EventType :: CallMissed { msg_id, chat_id } ) ;
482+ }
467483 }
468484 } else {
469485 // outgoing
@@ -481,12 +497,8 @@ impl Context {
481497 call. mark_as_ended ( self ) . await ?;
482498 call. update_text_duration ( self ) . await ?;
483499 }
484-
500+ self . emit_event ( EventType :: CallEnded { msg_id , chat_id } ) ;
485501 self . emit_msgs_changed ( call. msg . chat_id , call_id) ;
486- self . emit_event ( EventType :: CallEnded {
487- msg_id : call. msg . id ,
488- chat_id : call. msg . chat_id ,
489- } ) ;
490502 }
491503 _ => { }
492504 }
0 commit comments