Skip to content

Commit bed1623

Browse files
authored
feat: use dedicated 'call' viewtype (#7174)
a dedicated viewtype allows the UI to show a more advanced UI, but even when using the defaults, it has the advantage that incoming/outgoing and the date are directly visible. successor of #6650
1 parent d470497 commit bed1623

File tree

10 files changed

+109
-104
lines changed

10 files changed

+109
-104
lines changed

deltachat-ffi/deltachat.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4620,8 +4620,6 @@ int dc_msg_is_info (const dc_msg_t* msg);
46204620
* and also offer a way to fix the encryption, eg. by a button offering a QR scan
46214621
* - DC_INFO_WEBXDC_INFO_MESSAGE (32) - Info-message created by webxdc app sending `update.info`
46224622
* - DC_INFO_CHAT_E2EE (50) - Info-message for "Chat is end-to-end-encrypted"
4623-
* - DC_INFO_OUTGOING_CALL (60) - Info-message refers to an outgoing call
4624-
* - DC_INFO_INCOMING_CALL (65) - Info-message refers to an incoming call
46254623
*
46264624
* For the messages that refer to a CONTACT,
46274625
* dc_msg_get_info_contact_id() returns the contact ID.
@@ -4678,8 +4676,6 @@ uint32_t dc_msg_get_info_contact_id (const dc_msg_t* msg);
46784676
#define DC_INFO_INVALID_UNENCRYPTED_MAIL 13
46794677
#define DC_INFO_WEBXDC_INFO_MESSAGE 32
46804678
#define DC_INFO_CHAT_E2EE 50
4681-
#define DC_INFO_OUTGOING_CALL 60
4682-
#define DC_INFO_INCOMING_CALL 65
46834679

46844680

46854681
/**
@@ -5716,6 +5712,12 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
57165712
#define DC_MSG_VIDEOCHAT_INVITATION 70
57175713

57185714

5715+
/**
5716+
* Message indicating an incoming or outgoing call.
5717+
*/
5718+
#define DC_MSG_CALL 71
5719+
5720+
57195721
/**
57205722
* The message is a webxdc instance.
57215723
*

deltachat-jsonrpc/src/api/types/message.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ pub enum MessageViewtype {
324324
/// Message is an invitation to a videochat.
325325
VideochatInvitation,
326326

327+
/// Message is a call.
328+
Call,
329+
327330
/// Message is an webxdc instance.
328331
Webxdc,
329332

@@ -346,6 +349,7 @@ impl From<Viewtype> for MessageViewtype {
346349
Viewtype::Video => MessageViewtype::Video,
347350
Viewtype::File => MessageViewtype::File,
348351
Viewtype::VideochatInvitation => MessageViewtype::VideochatInvitation,
352+
Viewtype::Call => MessageViewtype::Call,
349353
Viewtype::Webxdc => MessageViewtype::Webxdc,
350354
Viewtype::Vcard => MessageViewtype::Vcard,
351355
}
@@ -365,6 +369,7 @@ impl From<MessageViewtype> for Viewtype {
365369
MessageViewtype::Video => Viewtype::Video,
366370
MessageViewtype::File => Viewtype::File,
367371
MessageViewtype::VideochatInvitation => Viewtype::VideochatInvitation,
372+
MessageViewtype::Call => Viewtype::Call,
368373
MessageViewtype::Webxdc => Viewtype::Webxdc,
369374
MessageViewtype::Vcard => Viewtype::Vcard,
370375
}
@@ -438,8 +443,6 @@ pub enum SystemMessageType {
438443
/// This message contains a users iroh node address.
439444
IrohNodeAddr,
440445

441-
OutgoingCall,
442-
IncomingCall,
443446
CallAccepted,
444447
CallEnded,
445448
}
@@ -468,8 +471,6 @@ impl From<deltachat::mimeparser::SystemMessage> for SystemMessageType {
468471
SystemMessage::IrohNodeAddr => SystemMessageType::IrohNodeAddr,
469472
SystemMessage::SecurejoinWait => SystemMessageType::SecurejoinWait,
470473
SystemMessage::SecurejoinWaitTimeout => SystemMessageType::SecurejoinWaitTimeout,
471-
SystemMessage::OutgoingCall => SystemMessageType::OutgoingCall,
472-
SystemMessage::IncomingCall => SystemMessageType::IncomingCall,
473474
SystemMessage::CallAccepted => SystemMessageType::CallAccepted,
474475
SystemMessage::CallEnded => SystemMessageType::CallEnded,
475476
}

src/calls.rs

Lines changed: 52 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! This means, the "Call ID" is a "Message ID" currently - similar to webxdc.
55
use crate::chat::{Chat, ChatId, send_msg};
66
use crate::constants::Chattype;
7+
use crate::contact::ContactId;
78
use crate::context::Context;
89
use crate::events::EventType;
910
use crate::headerdef::HeaderDef;
@@ -82,11 +83,10 @@ impl Context {
8283
ensure!(chat.typ == Chattype::Single && !chat.is_self_talk());
8384

8485
let mut call = Message {
85-
viewtype: Viewtype::Text,
86+
viewtype: Viewtype::Call,
8687
text: "Calling...".into(),
8788
..Default::default()
8889
};
89-
call.param.set_cmd(SystemMessage::OutgoingCall);
9090
call.param.set(Param::WebrtcRoom, &place_call_info);
9191
call.id = send_msg(self, chat_id, &mut call).await?;
9292

@@ -184,60 +184,61 @@ impl Context {
184184
mime_message: &MimeMessage,
185185
call_id: MsgId,
186186
) -> Result<()> {
187-
match mime_message.is_system_message {
188-
SystemMessage::IncomingCall => {
189-
let call = self.load_call_by_id(call_id).await?;
190-
if call.is_incoming {
191-
if call.is_stale_call() {
192-
call.update_text(self, "Missed call").await?;
193-
self.emit_incoming_msg(call.msg.chat_id, call_id);
187+
if mime_message.is_call() {
188+
let call = self.load_call_by_id(call_id).await?;
189+
if call.is_incoming {
190+
if call.is_stale_call() {
191+
call.update_text(self, "Missed call").await?;
192+
self.emit_incoming_msg(call.msg.chat_id, call_id);
193+
} else {
194+
self.emit_msgs_changed(call.msg.chat_id, call_id);
195+
self.emit_event(EventType::IncomingCall {
196+
msg_id: call.msg.id,
197+
place_call_info: call.place_call_info.to_string(),
198+
});
199+
let wait = call.remaining_ring_seconds();
200+
task::spawn(Context::emit_end_call_if_unaccepted(
201+
self.clone(),
202+
wait.try_into()?,
203+
call.msg.id,
204+
));
205+
}
206+
} else {
207+
self.emit_msgs_changed(call.msg.chat_id, call_id);
208+
}
209+
} else {
210+
match mime_message.is_system_message {
211+
SystemMessage::CallAccepted => {
212+
let call = self.load_call_by_id(call_id).await?;
213+
self.emit_msgs_changed(call.msg.chat_id, call_id);
214+
if call.is_incoming {
215+
self.emit_event(EventType::IncomingCallAccepted {
216+
msg_id: call.msg.id,
217+
accept_call_info: call.accept_call_info,
218+
});
194219
} else {
195-
self.emit_msgs_changed(call.msg.chat_id, call_id);
196-
self.emit_event(EventType::IncomingCall {
220+
let accept_call_info = mime_message
221+
.get_header(HeaderDef::ChatWebrtcAccepted)
222+
.unwrap_or_default();
223+
call.msg
224+
.clone()
225+
.mark_call_as_accepted(self, accept_call_info.to_string())
226+
.await?;
227+
self.emit_event(EventType::OutgoingCallAccepted {
197228
msg_id: call.msg.id,
198-
place_call_info: call.place_call_info.to_string(),
229+
accept_call_info: accept_call_info.to_string(),
199230
});
200-
let wait = call.remaining_ring_seconds();
201-
task::spawn(Context::emit_end_call_if_unaccepted(
202-
self.clone(),
203-
wait.try_into()?,
204-
call.msg.id,
205-
));
206231
}
207-
} else {
208-
self.emit_msgs_changed(call.msg.chat_id, call_id);
209232
}
210-
}
211-
SystemMessage::CallAccepted => {
212-
let call = self.load_call_by_id(call_id).await?;
213-
self.emit_msgs_changed(call.msg.chat_id, call_id);
214-
if call.is_incoming {
215-
self.emit_event(EventType::IncomingCallAccepted {
216-
msg_id: call.msg.id,
217-
accept_call_info: call.accept_call_info,
218-
});
219-
} else {
220-
let accept_call_info = mime_message
221-
.get_header(HeaderDef::ChatWebrtcAccepted)
222-
.unwrap_or_default();
223-
call.msg
224-
.clone()
225-
.mark_call_as_accepted(self, accept_call_info.to_string())
226-
.await?;
227-
self.emit_event(EventType::OutgoingCallAccepted {
233+
SystemMessage::CallEnded => {
234+
let call = self.load_call_by_id(call_id).await?;
235+
self.emit_msgs_changed(call.msg.chat_id, call_id);
236+
self.emit_event(EventType::CallEnded {
228237
msg_id: call.msg.id,
229-
accept_call_info: accept_call_info.to_string(),
230238
});
231239
}
240+
_ => {}
232241
}
233-
SystemMessage::CallEnded => {
234-
let call = self.load_call_by_id(call_id).await?;
235-
self.emit_msgs_changed(call.msg.chat_id, call_id);
236-
self.emit_event(EventType::CallEnded {
237-
msg_id: call.msg.id,
238-
});
239-
}
240-
_ => {}
241242
}
242243
Ok(())
243244
}
@@ -255,13 +256,10 @@ impl Context {
255256
}
256257

257258
fn load_call_by_message(&self, call: Message) -> Result<CallInfo> {
258-
ensure!(
259-
call.get_info_type() == SystemMessage::IncomingCall
260-
|| call.get_info_type() == SystemMessage::OutgoingCall
261-
);
259+
ensure!(call.viewtype == Viewtype::Call);
262260

263261
Ok(CallInfo {
264-
is_incoming: call.get_info_type() == SystemMessage::IncomingCall,
262+
is_incoming: call.get_from_id() != ContactId::SELF,
265263
is_accepted: call.is_call_accepted()?,
266264
place_call_info: call
267265
.param
@@ -284,21 +282,15 @@ impl Message {
284282
context: &Context,
285283
accept_call_info: String,
286284
) -> Result<()> {
287-
ensure!(
288-
self.get_info_type() == SystemMessage::IncomingCall
289-
|| self.get_info_type() == SystemMessage::OutgoingCall
290-
);
285+
ensure!(self.viewtype == Viewtype::Call);
291286
self.param.set_int(Param::Arg, 1);
292287
self.param.set(Param::WebrtcAccepted, accept_call_info);
293288
self.update_param(context).await?;
294289
Ok(())
295290
}
296291

297292
fn is_call_accepted(&self) -> Result<bool> {
298-
ensure!(
299-
self.get_info_type() == SystemMessage::IncomingCall
300-
|| self.get_info_type() == SystemMessage::OutgoingCall
301-
);
293+
ensure!(self.viewtype == Viewtype::Call);
302294
Ok(self.param.get_int(Param::Arg) == Some(1))
303295
}
304296
}

src/calls/calls_tests.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ async fn setup_call() -> Result<CallSetup> {
3333
let alice_call = Message::load_from_db(&alice, sent1.sender_msg_id).await?;
3434
let alice2_call = alice2.recv_msg(&sent1).await;
3535
for (t, m) in [(&alice, &alice_call), (&alice2, &alice2_call)] {
36-
assert!(m.is_info());
37-
assert_eq!(m.get_info_type(), SystemMessage::OutgoingCall);
36+
assert!(!m.is_info());
37+
assert_eq!(m.viewtype, Viewtype::Call);
3838
let info = t.load_call_by_id(m.id).await?;
39+
assert!(!info.is_incoming);
3940
assert!(!info.is_accepted);
4041
assert_eq!(info.place_call_info, "place_info");
4142
}
@@ -45,12 +46,13 @@ async fn setup_call() -> Result<CallSetup> {
4546
let bob_call = bob.recv_msg(&sent1).await;
4647
let bob2_call = bob2.recv_msg(&sent1).await;
4748
for (t, m) in [(&bob, &bob_call), (&bob2, &bob2_call)] {
48-
assert!(m.is_info());
49-
assert_eq!(m.get_info_type(), SystemMessage::IncomingCall);
49+
assert!(!m.is_info());
50+
assert_eq!(m.viewtype, Viewtype::Call);
5051
t.evtracker
5152
.get_matching(|evt| matches!(evt, EventType::IncomingCall { .. }))
5253
.await;
5354
let info = t.load_call_by_id(m.id).await?;
55+
assert!(info.is_incoming);
5456
assert!(!info.is_accepted);
5557
assert_eq!(info.place_call_info, "place_info");
5658
}

src/chat.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2691,7 +2691,10 @@ impl ChatIdBlocked {
26912691
}
26922692

26932693
async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> {
2694-
if msg.viewtype == Viewtype::Text || msg.viewtype == Viewtype::VideochatInvitation {
2694+
if msg.viewtype == Viewtype::Text
2695+
|| msg.viewtype == Viewtype::VideochatInvitation
2696+
|| msg.viewtype == Viewtype::Call
2697+
{
26952698
// the caller should check if the message text is empty
26962699
} else if msg.viewtype.has_file() {
26972700
let viewtype_orig = msg.viewtype;
@@ -3167,6 +3170,7 @@ pub async fn send_edit_request(context: &Context, msg_id: MsgId, new_text: Strin
31673170
original_msg.viewtype != Viewtype::VideochatInvitation,
31683171
"Cannot edit videochat invitations"
31693172
);
3173+
ensure!(original_msg.viewtype != Viewtype::Call, "Cannot edit calls");
31703174
ensure!(
31713175
!original_msg.text.is_empty(), // avoid complexity in UI element changes. focus is typos and rewordings
31723176
"Cannot add text"

src/message.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -973,8 +973,6 @@ impl Message {
973973
| SystemMessage::WebxdcStatusUpdate
974974
| SystemMessage::WebxdcInfoMessage
975975
| SystemMessage::IrohNodeAddr
976-
| SystemMessage::OutgoingCall
977-
| SystemMessage::IncomingCall
978976
| SystemMessage::CallAccepted
979977
| SystemMessage::CallEnded
980978
| SystemMessage::Unknown => Ok(None),
@@ -2280,6 +2278,9 @@ pub enum Viewtype {
22802278
/// Message is an invitation to a videochat.
22812279
VideochatInvitation = 70,
22822280

2281+
/// Message is an incoming or outgoing call.
2282+
Call = 71,
2283+
22832284
/// Message is an webxdc instance.
22842285
Webxdc = 80,
22852286

@@ -2303,6 +2304,7 @@ impl Viewtype {
23032304
Viewtype::Video => true,
23042305
Viewtype::File => true,
23052306
Viewtype::VideochatInvitation => false,
2307+
Viewtype::Call => false,
23062308
Viewtype::Webxdc => true,
23072309
Viewtype::Vcard => true,
23082310
}

src/mimefactory.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::collections::{BTreeSet, HashSet};
44
use std::io::Cursor;
55

6-
use anyhow::{Context as _, Result, anyhow, bail, ensure};
6+
use anyhow::{Context as _, Result, bail, ensure};
77
use base64::Engine as _;
88
use data_encoding::BASE32_NOPAD;
99
use deltachat_contact_tools::sanitize_bidi_characters;
@@ -1533,15 +1533,6 @@ impl MimeFactory {
15331533
.into(),
15341534
));
15351535
}
1536-
SystemMessage::OutgoingCall => {
1537-
headers.push((
1538-
"Chat-Content",
1539-
mail_builder::headers::raw::Raw::new("call").into(),
1540-
));
1541-
}
1542-
SystemMessage::IncomingCall => {
1543-
return Err(anyhow!("Unexpected incoming call rendering."));
1544-
}
15451536
SystemMessage::CallAccepted => {
15461537
headers.push((
15471538
"Chat-Content",
@@ -1578,6 +1569,11 @@ impl MimeFactory {
15781569
"Chat-Content",
15791570
mail_builder::headers::raw::Raw::new("videochat-invitation").into(),
15801571
));
1572+
} else if msg.viewtype == Viewtype::Call {
1573+
headers.push((
1574+
"Chat-Content",
1575+
mail_builder::headers::raw::Raw::new("call").into(),
1576+
));
15811577
}
15821578

15831579
if msg.param.exists(Param::WebrtcRoom) {

0 commit comments

Comments
 (0)