diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index ccb326430..aed6b6e8e 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -7544,12 +7544,6 @@ void dc_event_unref(dc_event_t* event); /// "❤️ Seems you're enjoying Delta Chat!"… (donation request device message) #define DC_STR_DONATION_REQUEST 193 -/// "Outgoing call" -#define DC_STR_OUTGOING_CALL 194 - -/// "Incoming call" -#define DC_STR_INCOMING_CALL 195 - /// "Declined call" #define DC_STR_DECLINED_CALL 196 @@ -7601,6 +7595,18 @@ void dc_event_unref(dc_event_t* event); /// Used as the first info messages in newly created classic email threads. #define DC_STR_CHAT_UNENCRYPTED_EXPLANATON 230 +/// "Outgoing audio call" +#define DC_STR_OUTGOING_AUDIO_CALL 232 + +/// "Outgoing video call" +#define DC_STR_OUTGOING_VIDEO_CALL 233 + +/// "Incoming audio call" +#define DC_STR_INCOMING_AUDIO_CALL 234 + +/// "Incoming video call" +#define DC_STR_INCOMING_VIDEO_CALL 235 + /** * @} */ diff --git a/src/calls.rs b/src/calls.rs index 321c7b8a7..3e0263f0a 100644 --- a/src/calls.rs +++ b/src/calls.rs @@ -103,10 +103,14 @@ impl CallInfo { }; if self.is_incoming() { - self.update_text(context, &format!("Incoming call\n{duration}")) + let incoming_call_str = + stock_str::incoming_call(context, self.has_video_initially()).await; + self.update_text(context, &format!("{incoming_call_str}\n{duration}")) .await?; } else { - self.update_text(context, &format!("Outgoing call\n{duration}")) + let outgoing_call_str = + stock_str::outgoing_call(context, self.has_video_initially()).await; + self.update_text(context, &format!("{outgoing_call_str}\n{duration}")) .await?; } Ok(()) @@ -201,7 +205,7 @@ impl Context { ); ensure!(!chat.is_self_talk(), "Cannot call self"); - let outgoing_call_str = stock_str::outgoing_call(self).await; + let outgoing_call_str = stock_str::outgoing_call(self, has_video_initially).await; let mut call = Message { viewtype: Viewtype::Call, text: outgoing_call_str, @@ -358,7 +362,8 @@ impl Context { call.update_text(self, &missed_call_str).await?; self.emit_incoming_msg(call.msg.chat_id, call_id); // notify missed call } else { - let incoming_call_str = stock_str::incoming_call(self).await; + let incoming_call_str = + stock_str::incoming_call(self, call.has_video_initially()).await; call.update_text(self, &incoming_call_str).await?; self.emit_msgs_changed(call.msg.chat_id, call_id); // ringing calls are not additionally notified let can_call_me = match who_can_call_me(self).await? { @@ -399,7 +404,8 @@ impl Context { )); } } else { - let outgoing_call_str = stock_str::outgoing_call(self).await; + let outgoing_call_str = + stock_str::outgoing_call(self, call.has_video_initially()).await; call.update_text(self, &outgoing_call_str).await?; self.emit_msgs_changed(call.msg.chat_id, call_id); } diff --git a/src/calls/calls_tests.rs b/src/calls/calls_tests.rs index de582261e..4328bcc4a 100644 --- a/src/calls/calls_tests.rs +++ b/src/calls/calls_tests.rs @@ -62,7 +62,7 @@ async fn setup_call() -> Result { assert!(!info.is_accepted()); assert_eq!(info.place_call_info, PLACE_INFO); assert_eq!(info.has_video_initially(), true); - assert_text(t, m.id, "Outgoing call").await?; + assert_text(t, m.id, "Outgoing video call").await?; assert_eq!(call_state(t, m.id).await?, CallState::Alerting); } @@ -84,7 +84,7 @@ async fn setup_call() -> Result { assert!(!info.is_accepted()); assert_eq!(info.place_call_info, PLACE_INFO); assert_eq!(info.has_video_initially(), true); - assert_text(t, m.id, "Incoming call").await?; + assert_text(t, m.id, "Incoming video call").await?; assert_eq!(call_state(t, m.id).await?, CallState::Alerting); } @@ -115,7 +115,7 @@ async fn accept_call() -> Result { // Bob accepts the incoming call bob.accept_incoming_call(bob_call.id, ACCEPT_INFO.to_string()) .await?; - assert_text(&bob, bob_call.id, "Incoming call").await?; + assert_text(&bob, bob_call.id, "Incoming video call").await?; bob.evtracker .get_matching(|evt| matches!(evt, EventType::IncomingCallAccepted { .. })) .await; @@ -129,7 +129,7 @@ async fn accept_call() -> Result { assert_eq!(call_state(&bob, bob_call.id).await?, CallState::Active); bob2.recv_msg_trash(&sent2).await; - assert_text(&bob, bob_call.id, "Incoming call").await?; + assert_text(&bob, bob_call.id, "Incoming video call").await?; bob2.evtracker .get_matching(|evt| matches!(evt, EventType::IncomingCallAccepted { .. })) .await; @@ -142,7 +142,7 @@ async fn accept_call() -> Result { // Alice receives the acceptance message alice.recv_msg_trash(&sent2).await; - assert_text(&alice, alice_call.id, "Outgoing call").await?; + assert_text(&alice, alice_call.id, "Outgoing video call").await?; let ev = alice .evtracker .get_matching(|evt| matches!(evt, EventType::OutgoingCallAccepted { .. })) @@ -164,7 +164,7 @@ async fn accept_call() -> Result { assert_eq!(call_state(&alice, alice_call.id).await?, CallState::Active); alice2.recv_msg_trash(&sent2).await; - assert_text(&alice2, alice2_call.id, "Outgoing call").await?; + assert_text(&alice2, alice2_call.id, "Outgoing video call").await?; alice2 .evtracker .get_matching(|evt| matches!(evt, EventType::OutgoingCallAccepted { .. })) @@ -203,7 +203,7 @@ async fn test_accept_call_callee_ends() -> Result<()> { // Bob has accepted the call and also ends it bob.end_call(bob_call.id).await?; - assert_text(&bob, bob_call.id, "Incoming call\n<1 minute").await?; + assert_text(&bob, bob_call.id, "Incoming video call\n<1 minute").await?; bob.evtracker .get_matching(|evt| matches!(evt, EventType::CallEnded { .. })) .await; @@ -214,7 +214,7 @@ async fn test_accept_call_callee_ends() -> Result<()> { )); bob2.recv_msg_trash(&sent3).await; - assert_text(&bob2, bob2_call.id, "Incoming call\n<1 minute").await?; + assert_text(&bob2, bob2_call.id, "Incoming video call\n<1 minute").await?; bob2.evtracker .get_matching(|evt| matches!(evt, EventType::CallEnded { .. })) .await; @@ -225,7 +225,7 @@ async fn test_accept_call_callee_ends() -> Result<()> { // Alice receives the ending message alice.recv_msg_trash(&sent3).await; - assert_text(&alice, alice_call.id, "Outgoing call\n<1 minute").await?; + assert_text(&alice, alice_call.id, "Outgoing video call\n<1 minute").await?; alice .evtracker .get_matching(|evt| matches!(evt, EventType::CallEnded { .. })) @@ -236,7 +236,7 @@ async fn test_accept_call_callee_ends() -> Result<()> { )); alice2.recv_msg_trash(&sent3).await; - assert_text(&alice2, alice2_call.id, "Outgoing call\n<1 minute").await?; + assert_text(&alice2, alice2_call.id, "Outgoing video call\n<1 minute").await?; alice2 .evtracker .get_matching(|evt| matches!(evt, EventType::CallEnded { .. })) @@ -266,7 +266,7 @@ async fn test_accept_call_caller_ends() -> Result<()> { // Bob has accepted the call but Alice ends it alice.end_call(alice_call.id).await?; - assert_text(&alice, alice_call.id, "Outgoing call\n<1 minute").await?; + assert_text(&alice, alice_call.id, "Outgoing video call\n<1 minute").await?; alice .evtracker .get_matching(|evt| matches!(evt, EventType::CallEnded { .. })) @@ -278,7 +278,7 @@ async fn test_accept_call_caller_ends() -> Result<()> { )); alice2.recv_msg_trash(&sent3).await; - assert_text(&alice2, alice2_call.id, "Outgoing call\n<1 minute").await?; + assert_text(&alice2, alice2_call.id, "Outgoing video call\n<1 minute").await?; alice2 .evtracker .get_matching(|evt| matches!(evt, EventType::CallEnded { .. })) @@ -290,7 +290,7 @@ async fn test_accept_call_caller_ends() -> Result<()> { // Bob receives the ending message bob.recv_msg_trash(&sent3).await; - assert_text(&bob, bob_call.id, "Incoming call\n<1 minute").await?; + assert_text(&bob, bob_call.id, "Incoming video call\n<1 minute").await?; bob.evtracker .get_matching(|evt| matches!(evt, EventType::CallEnded { .. })) .await; @@ -300,7 +300,7 @@ async fn test_accept_call_caller_ends() -> Result<()> { )); bob2.recv_msg_trash(&sent3).await; - assert_text(&bob2, bob2_call.id, "Incoming call\n<1 minute").await?; + assert_text(&bob2, bob2_call.id, "Incoming video call\n<1 minute").await?; bob2.evtracker .get_matching(|evt| matches!(evt, EventType::CallEnded { .. })) .await; @@ -420,7 +420,7 @@ async fn test_caller_cancels_call() -> Result<()> { // Test that message summary says it is a missed call. let bob_call_msg = Message::load_from_db(&bob, bob_call.id).await?; let summary = bob_call_msg.get_summary(&bob, None).await?; - assert_eq!(summary.text, "📞 Missed call"); + assert_eq!(summary.text, "🎥 Missed call"); bob2.recv_msg_trash(&sent3).await; assert_text(&bob2, bob2_call.id, "Missed call").await?; diff --git a/src/stock_str.rs b/src/stock_str.rs index 93011a440..c38b76691 100644 --- a/src/stock_str.rs +++ b/src/stock_str.rs @@ -369,12 +369,6 @@ Help keeping us to keep Delta Chat independent and make it more awesome in the f https://delta.chat/donate"))] DonationRequest = 193, - #[strum(props(fallback = "Outgoing call"))] - OutgoingCall = 194, - - #[strum(props(fallback = "Incoming call"))] - IncomingCall = 195, - #[strum(props(fallback = "Declined call"))] DeclinedCall = 196, @@ -417,6 +411,18 @@ https://delta.chat/donate"))] fallback = "You are using the legacy option \"Settings → Advanced → Move automatically to DeltaChat Folder\".\n\nThis option will be removed in a few weeks and you should disable it already today.\n\nIf having chat messages mixed into your inbox is a problem, see https://delta.chat/legacy-move" ))] MvboxMoveDeprecation = 231, + + #[strum(props(fallback = "Outgoing audio call"))] + OutgoingAudioCall = 232, + + #[strum(props(fallback = "Outgoing video call"))] + OutgoingVideoCall = 233, + + #[strum(props(fallback = "Incoming audio call"))] + IncomingAudioCall = 234, + + #[strum(props(fallback = "Incoming video call"))] + IncomingVideoCall = 235, } impl StockMessage { @@ -762,14 +768,30 @@ pub(crate) async fn donation_request(context: &Context) -> String { translated(context, StockMessage::DonationRequest).await } -/// Stock string: `Outgoing call`. -pub(crate) async fn outgoing_call(context: &Context) -> String { - translated(context, StockMessage::OutgoingCall).await +/// Stock string: `Outgoing video call` or `Outgoing audio call`. +pub(crate) async fn outgoing_call(context: &Context, has_video: bool) -> String { + translated( + context, + if has_video { + StockMessage::OutgoingVideoCall + } else { + StockMessage::OutgoingAudioCall + }, + ) + .await } -/// Stock string: `Incoming call`. -pub(crate) async fn incoming_call(context: &Context) -> String { - translated(context, StockMessage::IncomingCall).await +/// Stock string: `Incoming video call` or `Incoming audio call`. +pub(crate) async fn incoming_call(context: &Context, has_video: bool) -> String { + translated( + context, + if has_video { + StockMessage::IncomingVideoCall + } else { + StockMessage::IncomingAudioCall + }, + ) + .await } /// Stock string: `Declined call`. diff --git a/src/summary.rs b/src/summary.rs index 4a9b4191b..35aff3004 100644 --- a/src/summary.rs +++ b/src/summary.rs @@ -247,16 +247,18 @@ impl Message { append_text = true; } Viewtype::Call => { + let call_info = context.load_call_by_id(self.id).await.unwrap_or(None); + let has_video = call_info.is_some_and(|c| c.has_video_initially()); let call_state = call_state(context, self.id) .await .unwrap_or(CallState::Alerting); - emoji = Some("📞"); + emoji = Some(if has_video { "🎥" } else { "📞" }); type_name = Some(match call_state { CallState::Alerting | CallState::Active | CallState::Completed { .. } => { if self.from_id == ContactId::SELF { - stock_str::outgoing_call(context).await + stock_str::outgoing_call(context, has_video).await } else { - stock_str::incoming_call(context).await + stock_str::incoming_call(context, has_video).await } } CallState::Missed => stock_str::missed_call(context).await,