2020-07-13 11:49:14 +02:00
|
|
|
//! # Calls controller
|
|
|
|
//!
|
|
|
|
//! @author Pierre Hubert
|
|
|
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
2021-02-10 17:32:14 +01:00
|
|
|
use crate::api_data::call_member_info::CallMemberInfo;
|
2021-02-10 17:16:52 +01:00
|
|
|
use crate::api_data::joined_call_message::JoinedCallMessage;
|
2021-02-10 18:04:03 +01:00
|
|
|
use crate::api_data::left_call_message::LeftCallMessage;
|
2021-02-08 18:24:28 +01:00
|
|
|
use crate::api_data::user_calls_config::UserCallsConfig;
|
2020-07-13 11:49:14 +02:00
|
|
|
use crate::controllers::routes::RequestResult;
|
2021-02-10 17:16:52 +01:00
|
|
|
use crate::controllers::user_ws_controller;
|
2021-02-05 09:11:30 +01:00
|
|
|
use crate::data::base_request_handler::BaseRequestHandler;
|
2021-02-08 18:24:28 +01:00
|
|
|
use crate::data::config::conf;
|
2021-02-10 18:04:03 +01:00
|
|
|
use crate::data::conversation::ConvID;
|
2021-02-10 17:16:52 +01:00
|
|
|
use crate::data::error::{ExecError, Res};
|
2020-07-13 11:49:14 +02:00
|
|
|
use crate::data::http_request_handler::HttpRequestHandler;
|
2021-02-10 18:04:03 +01:00
|
|
|
use crate::data::user_ws_connection::{ActiveCall, UserWsConnection};
|
2021-02-10 17:16:52 +01:00
|
|
|
use crate::data::user_ws_message::UserWsMessage;
|
2021-02-08 18:24:28 +01:00
|
|
|
use crate::data::user_ws_request_handler::UserWsRequestHandler;
|
2021-02-10 17:16:52 +01:00
|
|
|
use crate::helpers::{calls_helper, conversations_helper, events_helper};
|
|
|
|
use crate::helpers::events_helper::Event;
|
2020-07-13 11:49:14 +02:00
|
|
|
|
|
|
|
/// Get legacy call configuration
|
|
|
|
pub fn get_legacy_config(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let mut map = HashMap::new();
|
|
|
|
map.insert("enabled", false);
|
|
|
|
r.set_response(map)
|
2021-02-08 18:24:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get calls configuration
|
|
|
|
pub fn get_config(r: &mut UserWsRequestHandler) -> RequestResult {
|
2021-02-10 18:07:55 +01:00
|
|
|
// Check whether the user is the member of a call or not
|
|
|
|
if let None = r.get_conn().active_call {
|
|
|
|
r.forbidden("You do not belong to any call yet!".to_string())?;
|
|
|
|
}
|
2021-02-08 18:24:28 +01:00
|
|
|
|
|
|
|
if let Some(conf) = conf().rtc_relay.as_ref()
|
|
|
|
{
|
|
|
|
return r.set_response(UserCallsConfig::new(conf));
|
|
|
|
}
|
|
|
|
|
|
|
|
r.internal_error(ExecError::boxed_new("Missing calls configuration!"))
|
2021-02-10 17:16:52 +01:00
|
|
|
}
|
|
|
|
|
2021-02-10 18:14:17 +01:00
|
|
|
/// Check out whether a conversation is having a call or not
|
|
|
|
pub fn is_conversation_having_call(conv_id: &ConvID) -> bool {
|
|
|
|
let mut found = false;
|
|
|
|
|
|
|
|
let res = user_ws_controller::foreach_connection(|f| {
|
|
|
|
if found || f.is_having_call_with_conversation(conv_id) {
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
|
|
|
|
if let Err(e) = res {
|
|
|
|
eprintln!("Failed to check if a conversation is having call! Conversation: {} / Error: {:#?}", conv_id, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
found
|
|
|
|
}
|
|
|
|
|
2021-02-10 17:16:52 +01:00
|
|
|
/// Join a call
|
|
|
|
pub fn join_call(r: &mut UserWsRequestHandler) -> RequestResult {
|
|
|
|
let conv_id = r.post_conv_id("convID")?;
|
|
|
|
|
|
|
|
// Check if the conversation can have a call
|
|
|
|
let conv = conversations_helper::get_single(conv_id, r.user_id_ref()?)?;
|
|
|
|
if !calls_helper::can_have_call(&conv) {
|
|
|
|
r.forbidden("This conversation can not be used to make calls!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO : Remove any previous call linked to current connection + any other active connection
|
|
|
|
// of current user to current conversation call
|
|
|
|
|
|
|
|
r.update_conn(|r| r.active_call = Some(ActiveCall {
|
|
|
|
conv_id,
|
|
|
|
ready: false,
|
|
|
|
}))?;
|
|
|
|
|
|
|
|
// Propagate event
|
2021-02-10 18:04:03 +01:00
|
|
|
events_helper::propagate_event(&Event::UserJoinedCall(&conv_id, r.user_id_ref()?))?;
|
2021-02-10 17:16:52 +01:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-02-10 18:04:03 +01:00
|
|
|
/// Leave a call
|
|
|
|
pub fn leave_call(r: &mut UserWsRequestHandler) -> RequestResult {
|
|
|
|
// Warning ! For some technical reasons, we do not check if the user
|
|
|
|
// really belongs to the conversation, so be careful when manipulating
|
|
|
|
// conversation ID here
|
|
|
|
let conv_id = r.post_u64("convID")?;
|
|
|
|
|
|
|
|
// Check if the user was not in the conversation
|
|
|
|
if !r.get_conn().is_having_call_with_conversation(&conv_id) {
|
|
|
|
return r.success("Left call!");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make the user leave the call
|
|
|
|
make_user_leave_call(&conv_id, r.get_conn())?;
|
|
|
|
|
|
|
|
r.success("Left call!")
|
|
|
|
}
|
|
|
|
|
2021-02-10 17:32:14 +01:00
|
|
|
/// Get the list of members of a call
|
|
|
|
pub fn get_members_list(r: &mut UserWsRequestHandler) -> RequestResult {
|
|
|
|
let conv_id = r.post_call_id("callID")?;
|
|
|
|
let mut list = vec![];
|
|
|
|
|
|
|
|
user_ws_controller::foreach_connection(|conn| {
|
|
|
|
if conn.is_having_call_with_conversation(&conv_id) {
|
|
|
|
list.push(CallMemberInfo::new(&conn.user_id, &conn.active_call.as_ref().unwrap()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
})?;
|
|
|
|
|
|
|
|
r.set_response(list)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-10 18:04:03 +01:00
|
|
|
/// Make the user leave the call
|
|
|
|
pub fn make_user_leave_call(conv_id: &ConvID, connection: &UserWsConnection) -> Res {
|
|
|
|
connection.clone().replace(|c| c.active_call = None);
|
|
|
|
|
|
|
|
// Notify user (if possible)
|
|
|
|
if connection.session.connected() {
|
|
|
|
user_ws_controller::send_to_client(connection, &UserWsMessage::no_id_message("call_closed", conv_id)?)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO : call main stream (sender)
|
|
|
|
|
|
|
|
// TODO : close receiver streams (other users streams)
|
|
|
|
|
|
|
|
// Create a notification
|
|
|
|
events_helper::propagate_event(&Event::UserLeftCall(conv_id, &connection.user_id))?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-02-10 17:16:52 +01:00
|
|
|
/// Events handler
|
|
|
|
pub fn handle_event(e: &events_helper::Event) -> Res {
|
|
|
|
match e {
|
|
|
|
Event::UserJoinedCall(conv_id, user_id) => {
|
|
|
|
user_ws_controller::send_message_to_specific_connections(
|
|
|
|
|c| c.is_having_call_with_conversation(conv_id) && &c.user_id != user_id,
|
|
|
|
|_| UserWsMessage::no_id_message("user_joined_call", JoinedCallMessage::new(conv_id, user_id)),
|
|
|
|
None::<fn(&_) -> _>,
|
|
|
|
)?;
|
|
|
|
}
|
|
|
|
|
2021-02-10 18:04:03 +01:00
|
|
|
Event::UserLeftCall(conv_id, user_id) => {
|
|
|
|
user_ws_controller::send_message_to_specific_connections(
|
|
|
|
|c| c.is_having_call_with_conversation(conv_id),
|
|
|
|
|_| UserWsMessage::no_id_message("user_left_call", LeftCallMessage::new(conv_id, user_id)),
|
|
|
|
None::<fn(&_) -> _>,
|
|
|
|
)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Event::UserWsClosed(c) => {
|
|
|
|
if let Some(call) = c.active_call.clone() {
|
|
|
|
make_user_leave_call(&call.conv_id, c)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-10 17:16:52 +01:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
2020-07-13 11:49:14 +02:00
|
|
|
}
|