mirror of
https://github.com/chatmail/core.git
synced 2026-04-26 18:06:35 +03:00
api(jsonrpc): add state attribute to call info
Existing boolean attributes removed.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use deltachat::calls::{call_state, CallState};
|
||||
use deltachat::context::Context;
|
||||
use deltachat::message::MsgId;
|
||||
use serde::Serialize;
|
||||
@@ -8,46 +9,79 @@ use typescript_type_def::TypeDef;
|
||||
#[derive(Serialize, TypeDef, schemars::JsonSchema)]
|
||||
#[serde(rename = "CallInfo", rename_all = "camelCase")]
|
||||
pub struct JsonrpcCallInfo {
|
||||
/// True if the call is an incoming call.
|
||||
pub is_incoming: bool,
|
||||
|
||||
/// True if the call should not ring anymore.
|
||||
pub is_stale: bool,
|
||||
|
||||
/// True if the call is accepted.
|
||||
pub is_accepted: bool,
|
||||
|
||||
/// True if the call has been ended.
|
||||
pub is_ended: bool,
|
||||
|
||||
/// Call duration in seconds.
|
||||
pub duration: i64,
|
||||
|
||||
/// SDP offer.
|
||||
///
|
||||
/// Can be used to manually answer the call
|
||||
/// even if incoming call event was missed.
|
||||
pub sdp_offer: String,
|
||||
|
||||
/// Call state.
|
||||
///
|
||||
/// For example, if the call is accepted, active, cancelled, declined etc.
|
||||
pub state: JsonrpcCallState,
|
||||
}
|
||||
|
||||
impl JsonrpcCallInfo {
|
||||
pub async fn from_msg_id(context: &Context, msg_id: MsgId) -> Result<JsonrpcCallInfo> {
|
||||
let call_info = context.load_call_by_id(msg_id).await?;
|
||||
|
||||
let is_incoming = call_info.is_incoming();
|
||||
let is_stale = call_info.is_stale();
|
||||
let is_accepted = call_info.is_accepted();
|
||||
let is_ended = call_info.is_ended();
|
||||
let duration = call_info.duration_seconds();
|
||||
let sdp_offer = call_info.place_call_info.clone();
|
||||
let state = JsonrpcCallState::from_msg_id(context, msg_id).await?;
|
||||
|
||||
Ok(JsonrpcCallInfo {
|
||||
is_incoming,
|
||||
is_stale,
|
||||
is_accepted,
|
||||
is_ended,
|
||||
duration,
|
||||
sdp_offer,
|
||||
})
|
||||
Ok(JsonrpcCallInfo { sdp_offer, state })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, TypeDef, schemars::JsonSchema)]
|
||||
#[serde(rename = "CallState", tag = "kind")]
|
||||
pub enum JsonrpcCallState {
|
||||
/// Fresh incoming or outgoing call that is still ringing.
|
||||
///
|
||||
/// There is no separate state for outgoing call
|
||||
/// that has been dialled but not ringing on the other side yet
|
||||
/// as we don't know whether the other side received our call.
|
||||
Alerting,
|
||||
|
||||
/// Active call.
|
||||
Active,
|
||||
|
||||
/// Completed call that was once active
|
||||
/// and then was terminated for any reason.
|
||||
Completed {
|
||||
/// Call duration in seconds.
|
||||
duration: i64,
|
||||
},
|
||||
|
||||
/// Incoming call that was not picked up within a timeout
|
||||
/// or was explicitly ended by the caller before we picked up.
|
||||
Missed,
|
||||
|
||||
/// Incoming call that was explicitly ended on our side
|
||||
/// before picking up or outgoing call
|
||||
/// that was declined before the timeout.
|
||||
Declined,
|
||||
|
||||
/// Outgoing call that has been cancelled on our side
|
||||
/// before receiving a response.
|
||||
///
|
||||
/// Incoming calls cannot be cancelled,
|
||||
/// on the receiver side cancelled calls
|
||||
/// usually result in missed calls.
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
impl JsonrpcCallState {
|
||||
pub async fn from_msg_id(context: &Context, msg_id: MsgId) -> Result<JsonrpcCallState> {
|
||||
let call_state = call_state(context, msg_id).await?;
|
||||
|
||||
let jsonrpc_call_state = match call_state {
|
||||
CallState::Alerting => JsonrpcCallState::Alerting,
|
||||
CallState::Active => JsonrpcCallState::Active,
|
||||
CallState::Completed { duration } => JsonrpcCallState::Completed { duration },
|
||||
CallState::Missed => JsonrpcCallState::Missed,
|
||||
CallState::Declined => JsonrpcCallState::Declined,
|
||||
CallState::Cancelled => JsonrpcCallState::Cancelled,
|
||||
};
|
||||
|
||||
Ok(jsonrpc_call_state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,23 +10,27 @@ def test_calls(acfactory) -> None:
|
||||
alice_contact_bob = alice.create_contact(bob, "Bob")
|
||||
alice_chat_bob = alice_contact_bob.create_chat()
|
||||
outgoing_call_message = alice_chat_bob.place_outgoing_call(place_call_info)
|
||||
assert outgoing_call_message.get_call_info().state.kind == "Alerting"
|
||||
|
||||
incoming_call_event = bob.wait_for_event(EventType.INCOMING_CALL)
|
||||
assert incoming_call_event.place_call_info == place_call_info
|
||||
assert not incoming_call_event.has_video # Cannot be parsed as SDP, so false by default
|
||||
incoming_call_message = Message(bob, incoming_call_event.msg_id)
|
||||
assert not incoming_call_message.get_call_info().is_accepted
|
||||
assert incoming_call_message.get_call_info().state.kind == "Alerting"
|
||||
|
||||
incoming_call_message.accept_incoming_call(accept_call_info)
|
||||
assert incoming_call_message.get_call_info().is_accepted
|
||||
assert incoming_call_message.get_call_info().sdp_offer == place_call_info
|
||||
assert incoming_call_message.get_call_info().state.kind == "Active"
|
||||
outgoing_call_accepted_event = alice.wait_for_event(EventType.OUTGOING_CALL_ACCEPTED)
|
||||
assert outgoing_call_accepted_event.accept_call_info == accept_call_info
|
||||
assert outgoing_call_message.get_call_info().state.kind == "Active"
|
||||
|
||||
outgoing_call_message.end_call()
|
||||
assert outgoing_call_message.get_call_info().state.kind == "Completed"
|
||||
|
||||
end_call_event = bob.wait_for_event(EventType.CALL_ENDED)
|
||||
assert end_call_event.msg_id == outgoing_call_message.id
|
||||
assert incoming_call_message.get_call_info().state.kind == "Completed"
|
||||
|
||||
|
||||
def test_video_call(acfactory) -> None:
|
||||
|
||||
Reference in New Issue
Block a user