mirror of
				https://gitlab.com/comunic/comunicapiv3
				synced 2025-10-31 07:34:45 +00:00 
			
		
		
		
	Can join call
This commit is contained in:
		
							
								
								
									
										25
									
								
								src/api_data/joined_call_message.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/api_data/joined_call_message.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| //! # Joined call message | ||||
| //! | ||||
| //! @author Pierre Hubert | ||||
|  | ||||
| use serde::Serialize; | ||||
|  | ||||
| use crate::data::conversation::ConvID; | ||||
| use crate::data::user::UserID; | ||||
|  | ||||
| /// This structure is used to give information about a user who joined a call | ||||
| #[derive(Serialize)] | ||||
| #[allow(non_snake_case)] | ||||
| pub struct JoinedCallMessage { | ||||
|     callID: u64, | ||||
|     userID: u64, | ||||
| } | ||||
|  | ||||
| impl JoinedCallMessage { | ||||
|     pub fn new(call_id: &ConvID, user_id: &UserID) -> Self { | ||||
|         Self { | ||||
|             callID: call_id.clone(), | ||||
|             userID: user_id.id(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -57,4 +57,5 @@ pub mod security_settings_api; | ||||
| pub mod account_image_settings_api; | ||||
| pub mod res_create_custom_emoji; | ||||
| pub mod res_get_ws_token; | ||||
| pub mod user_calls_config; | ||||
| pub mod user_calls_config; | ||||
| pub mod joined_call_message; | ||||
| @@ -4,13 +4,19 @@ | ||||
|  | ||||
| use std::collections::HashMap; | ||||
|  | ||||
| use crate::api_data::joined_call_message::JoinedCallMessage; | ||||
| use crate::api_data::user_calls_config::UserCallsConfig; | ||||
| use crate::controllers::routes::RequestResult; | ||||
| use crate::controllers::user_ws_controller; | ||||
| use crate::data::base_request_handler::BaseRequestHandler; | ||||
| use crate::data::config::conf; | ||||
| use crate::data::error::ExecError; | ||||
| use crate::data::error::{ExecError, Res}; | ||||
| use crate::data::http_request_handler::HttpRequestHandler; | ||||
| use crate::data::user_ws_connection::ActiveCall; | ||||
| use crate::data::user_ws_message::UserWsMessage; | ||||
| use crate::data::user_ws_request_handler::UserWsRequestHandler; | ||||
| use crate::helpers::{calls_helper, conversations_helper, events_helper}; | ||||
| use crate::helpers::events_helper::Event; | ||||
|  | ||||
| /// Get legacy call configuration | ||||
| pub fn get_legacy_config(r: &mut HttpRequestHandler) -> RequestResult { | ||||
| @@ -29,4 +35,45 @@ pub fn get_config(r: &mut UserWsRequestHandler) -> RequestResult { | ||||
|     } | ||||
|  | ||||
|     r.internal_error(ExecError::boxed_new("Missing calls configuration!")) | ||||
| } | ||||
|  | ||||
| /// 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 | ||||
|     events_helper::propagate_event(&Event::UserJoinedCall(conv_id, r.user_id()?))?; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| /// 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(&_) -> _>, | ||||
|             )?; | ||||
|         } | ||||
|  | ||||
|         _ => {} | ||||
|     } | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
| @@ -13,13 +13,13 @@ use crate::api_data::res_create_conversation::ResCreateConversation; | ||||
| use crate::api_data::res_find_private_conversations::ResFindPrivateConversations; | ||||
| use crate::controllers::routes::RequestResult; | ||||
| use crate::controllers::user_ws_controller; | ||||
| use crate::controllers::user_ws_controller::WsConnection; | ||||
| use crate::data::base_request_handler::BaseRequestHandler; | ||||
| use crate::data::error::Res; | ||||
| use crate::data::http_request_handler::HttpRequestHandler; | ||||
| use crate::data::new_conversation::NewConversation; | ||||
| use crate::data::new_conversation_message::NewConversationMessage; | ||||
| use crate::data::user::UserID; | ||||
| use crate::data::user_ws_connection::UserWsConnection; | ||||
| use crate::data::user_ws_message::UserWsMessage; | ||||
| use crate::helpers::{conversations_helper, events_helper, user_helper}; | ||||
| use crate::helpers::events_helper::Event; | ||||
| @@ -362,7 +362,7 @@ pub fn handle_event(e: &events_helper::Event) -> Res { | ||||
|             user_ws_controller::send_message_to_specific_connections( | ||||
|                 |f| f.conversations.contains(&msg.conv_id), | ||||
|                 |_| UserWsMessage::no_id_message("new_conv_message", ConversationMessageAPI::new(msg)), | ||||
|                 Some(|conn: &WsConnection| conversations_helper::mark_user_seen(msg.conv_id, &conn.user_id)), | ||||
|                 Some(|conn: &UserWsConnection| conversations_helper::mark_user_seen(msg.conv_id, &conn.user_id)), | ||||
|             )?; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,6 @@ use serde_json::Value; | ||||
| use crate::api_data::res_get_ws_token::ResGetWsToken; | ||||
| use crate::constants::{USER_LAST_ACTIVITY_REFRESH, WS_ACCESS_TOKEN_LENGTH}; | ||||
| use crate::controllers::user_ws_controller::ws_connections_list::{add_connection, find_connection, get_ws_connections_list, remove_connection}; | ||||
| pub use crate::controllers::user_ws_controller::ws_connections_list::WsConnection; | ||||
| use crate::controllers::user_ws_routes::find_user_ws_route; | ||||
| use crate::data::api_client::APIClient; | ||||
| use crate::data::base_request_handler::BaseRequestHandler; | ||||
| @@ -22,6 +21,7 @@ use crate::data::config::conf; | ||||
| use crate::data::error::{ExecError, Res, ResultBoxError}; | ||||
| use crate::data::http_request_handler::HttpRequestHandler; | ||||
| use crate::data::user::UserID; | ||||
| use crate::data::user_ws_connection::UserWsConnection; | ||||
| use crate::data::user_ws_message::UserWsMessage; | ||||
| use crate::data::user_ws_request_handler::{UserWsRequestHandler, UserWsResponseType}; | ||||
| use crate::helpers::{account_helper, events_helper}; | ||||
| @@ -100,30 +100,15 @@ mod ws_tokens_list { | ||||
|  | ||||
| /// WebSocket connections list | ||||
| mod ws_connections_list { | ||||
|     use std::collections::HashSet; | ||||
|     use std::sync::Arc; | ||||
|     use std::sync::Mutex; | ||||
|  | ||||
|     use actix::Addr; | ||||
|  | ||||
|     use crate::controllers::user_ws_controller::WsSession; | ||||
|     use crate::data::conversation::ConvID; | ||||
|     use crate::data::post::PostID; | ||||
|     use crate::data::user::UserID; | ||||
|     use crate::data::user_ws_connection::UserWsConnection; | ||||
|  | ||||
|     /// This structure contains information about an active connection | ||||
|     #[derive(Clone, Debug)] | ||||
|     pub struct WsConnection { | ||||
|         pub user_id: UserID, | ||||
|         pub client_id: u32, | ||||
|         pub remote_ip: String, | ||||
|         pub session: actix::Addr<WsSession>, | ||||
|         pub incognito: bool, | ||||
|         pub conversations: HashSet<ConvID>, | ||||
|         pub posts: HashSet<PostID>, | ||||
|     } | ||||
|  | ||||
|     impl WsConnection { | ||||
|     impl UserWsConnection { | ||||
|         /// Change some of the properties of the connection | ||||
|         pub fn replace<H>(mut self, do_update: H) -> Self where H: FnOnce(&mut Self) { | ||||
|             let list = get_ws_connections_list(); | ||||
| @@ -147,23 +132,23 @@ mod ws_connections_list { | ||||
|     } | ||||
|  | ||||
|     lazy_static! { | ||||
|         static ref WS_CONNECTIONS: Arc<Mutex<Vec<WsConnection>>> = { | ||||
|         static ref WS_CONNECTIONS: Arc<Mutex<Vec<UserWsConnection >>> = { | ||||
|             Arc::new(Mutex::new(Vec::new())) | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /// Get the list of WebSocket connections | ||||
|     pub fn get_ws_connections_list() -> Arc<Mutex<Vec<WsConnection>>> { | ||||
|     pub fn get_ws_connections_list() -> Arc<Mutex<Vec<UserWsConnection>>> { | ||||
|         (*WS_CONNECTIONS).clone() | ||||
|     } | ||||
|  | ||||
|     /// Add a new token to the list | ||||
|     pub fn add_connection(t: WsConnection) { | ||||
|     pub fn add_connection(t: UserWsConnection) { | ||||
|         get_ws_connections_list().lock().unwrap().push(t) | ||||
|     } | ||||
|  | ||||
|     /// Find a connection in the list | ||||
|     pub fn find_connection(t: Addr<WsSession>) -> Option<WsConnection> { | ||||
|     pub fn find_connection(t: Addr<WsSession>) -> Option<UserWsConnection> { | ||||
|         get_ws_connections_list() | ||||
|             .lock() | ||||
|             .unwrap() | ||||
| @@ -173,7 +158,7 @@ mod ws_connections_list { | ||||
|     } | ||||
|  | ||||
|     /// Remove a connection from the list | ||||
|     pub fn remove_connection(t: Addr<WsSession>) -> Option<WsConnection> { | ||||
|     pub fn remove_connection(t: Addr<WsSession>) -> Option<UserWsConnection> { | ||||
|         let list = get_ws_connections_list(); | ||||
|         let mut list = list.lock().unwrap(); | ||||
|         for i in 0..list.len() { | ||||
| @@ -326,7 +311,7 @@ impl Actor for WsSession { | ||||
|         self.hb(ctx); | ||||
|         self.user_activity(ctx); | ||||
|  | ||||
|         add_connection(WsConnection { | ||||
|         add_connection(UserWsConnection { | ||||
|             user_id: self.user_id.clone(), | ||||
|             client_id: self.client_id, | ||||
|             remote_ip: self.remote_ip.clone(), | ||||
| @@ -334,6 +319,7 @@ impl Actor for WsSession { | ||||
|             incognito: self.incognito, | ||||
|             conversations: HashSet::new(), | ||||
|             posts: HashSet::new(), | ||||
|             active_call: None, | ||||
|         }) | ||||
|     } | ||||
|  | ||||
| @@ -506,9 +492,9 @@ pub fn send_message_to_user(msg: &UserWsMessage, user: &UserID) -> Res { | ||||
|  | ||||
| /// Send a message to specific users | ||||
| pub fn send_message_to_specific_connections<F, M, A>(filter: F, msg_generator: M, after_send: Option<A>) -> Res | ||||
|     where F: Fn(&WsConnection) -> bool, | ||||
|           M: Fn(&WsConnection) -> Res<UserWsMessage>, | ||||
|           A: Fn(&WsConnection) -> Res | ||||
|     where F: Fn(&UserWsConnection) -> bool, | ||||
|           M: Fn(&UserWsConnection) -> Res<UserWsMessage>, | ||||
|           A: Fn(&UserWsConnection) -> Res | ||||
| { | ||||
|     let connections = get_ws_connections_list() | ||||
|         .lock() | ||||
| @@ -516,7 +502,7 @@ pub fn send_message_to_specific_connections<F, M, A>(filter: F, msg_generator: M | ||||
|         .iter() | ||||
|         .filter(|f| filter(f)) | ||||
|         .map(|f| f.clone()) | ||||
|         .collect::<Vec<WsConnection>>(); | ||||
|         .collect::<Vec<UserWsConnection>>(); | ||||
|  | ||||
|     for con in connections { | ||||
|         send_message(con.session.clone(), &msg_generator(&con)?)?; | ||||
|   | ||||
| @@ -39,6 +39,7 @@ pub fn get_user_ws_routes() -> Vec<UserWsRoute> { | ||||
|  | ||||
|         // Calls controller | ||||
|         UserWsRoute::new("calls/config", calls_controller::get_config), | ||||
|         UserWsRoute::new("calls/join", calls_controller::join_call), | ||||
|     ] | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -36,4 +36,5 @@ pub mod general_settings; | ||||
| pub mod lang_settings; | ||||
| pub mod security_settings; | ||||
| pub mod new_custom_emoji; | ||||
| pub mod user_ws_message; | ||||
| pub mod user_ws_message; | ||||
| pub mod user_ws_connection; | ||||
							
								
								
									
										36
									
								
								src/data/user_ws_connection.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/data/user_ws_connection.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| use std::collections::HashSet; | ||||
|  | ||||
| use crate::controllers::user_ws_controller::WsSession; | ||||
| use crate::data::conversation::ConvID; | ||||
| use crate::data::post::PostID; | ||||
| use crate::data::user::UserID; | ||||
|  | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct ActiveCall { | ||||
|     pub conv_id: ConvID, | ||||
|     pub ready: bool, | ||||
| } | ||||
|  | ||||
| /// This structure contains information about an active connection | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct UserWsConnection { | ||||
|     pub user_id: UserID, | ||||
|     pub client_id: u32, | ||||
|     pub remote_ip: String, | ||||
|     pub session: actix::Addr<WsSession>, | ||||
|     pub incognito: bool, | ||||
|     pub conversations: HashSet<ConvID>, | ||||
|     pub posts: HashSet<PostID>, | ||||
|     pub active_call: Option<ActiveCall>, | ||||
| } | ||||
|  | ||||
| impl UserWsConnection { | ||||
|     /// Check out whether a connection is being used to make a call in a specific conversation or not | ||||
|     pub fn is_having_call_with_conversation(&self, conv_id: &ConvID) -> bool { | ||||
|         if let Some(call_info) = &self.active_call { | ||||
|             return &call_info.conv_id == conv_id; | ||||
|         } | ||||
|  | ||||
|         false | ||||
|     } | ||||
| } | ||||
| @@ -6,10 +6,10 @@ use serde::Serialize; | ||||
|  | ||||
| use crate::api_data::http_error::HttpError; | ||||
| use crate::controllers::routes::RequestResult; | ||||
| use crate::controllers::user_ws_controller::WsConnection; | ||||
| use crate::data::base_request_handler::{BaseRequestHandler, RequestValue}; | ||||
| use crate::data::error::ResultBoxError; | ||||
| use crate::data::user::UserID; | ||||
| use crate::data::user_ws_connection::UserWsConnection; | ||||
|  | ||||
| pub enum UserWsResponseType { | ||||
|     SUCCESS, | ||||
| @@ -22,13 +22,13 @@ pub struct UserWsResponse { | ||||
| } | ||||
|  | ||||
| pub struct UserWsRequestHandler { | ||||
|     connection: WsConnection, | ||||
|     connection: UserWsConnection, | ||||
|     args: HashMap<String, RequestValue>, | ||||
|     response: Option<UserWsResponse>, | ||||
| } | ||||
|  | ||||
| impl UserWsRequestHandler { | ||||
|     pub fn new(connection: &WsConnection, args: HashMap<String, String>) -> UserWsRequestHandler { | ||||
|     pub fn new(connection: &UserWsConnection, args: HashMap<String, String>) -> UserWsRequestHandler { | ||||
|         UserWsRequestHandler { | ||||
|             connection: connection.clone(), | ||||
|             args: args.into_iter().map(|f| (f.0, RequestValue::String(f.1))).collect(), | ||||
| @@ -51,7 +51,7 @@ impl UserWsRequestHandler { | ||||
|     } | ||||
|  | ||||
|     /// Update information about the WebSocket connection | ||||
|     pub fn update_conn<H>(&mut self, do_updates: H) -> ResultBoxError where H: FnOnce(&mut WsConnection) { | ||||
|     pub fn update_conn<H>(&mut self, do_updates: H) -> ResultBoxError where H: FnOnce(&mut UserWsConnection) { | ||||
|         self.connection = self.connection.clone().replace(do_updates); | ||||
|  | ||||
|         Ok(()) | ||||
|   | ||||
| @@ -4,9 +4,10 @@ | ||||
|  | ||||
|  | ||||
|  | ||||
| use crate::controllers::{comments_controller, conversations_controller, notifications_controller, user_ws_controller}; | ||||
| use crate::controllers::{calls_controller, comments_controller, conversations_controller, notifications_controller, user_ws_controller}; | ||||
| use crate::data::api_client::APIClient; | ||||
| use crate::data::comment::Comment; | ||||
| use crate::data::conversation::ConvID; | ||||
| use crate::data::conversation_message::ConversationMessage; | ||||
| use crate::data::error::Res; | ||||
| use crate::data::user::UserID; | ||||
| @@ -42,6 +43,9 @@ pub enum Event<'a> { | ||||
|     /// Connection to RTC relay was closed | ||||
|     ClosedRTCRelayWebSocket, | ||||
|  | ||||
|     /// User joined call | ||||
|     UserJoinedCall(ConvID, UserID), | ||||
|  | ||||
|     /// No event | ||||
|     None, | ||||
| } | ||||
| @@ -52,5 +56,6 @@ pub fn propagate_event(e: &Event) -> Res { | ||||
|     comments_controller::handle_event(e)?; | ||||
|     notifications_controller::handle_event(e)?; | ||||
|     user_ws_controller::handle_event(e)?; | ||||
|     calls_controller::handle_event(e)?; | ||||
|     Ok(()) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user