diff --git a/src/api_data/conversation_message_api.rs b/src/api_data/conversation_message_api.rs new file mode 100644 index 0000000..72a73c9 --- /dev/null +++ b/src/api_data/conversation_message_api.rs @@ -0,0 +1,42 @@ +//! # Conversation message API +//! +//! API representation of a conversation message +//! +//! @author Pierre HUBERT + +use serde::Serialize; + +use crate::data::conversation_message::ConversationMessage; +use crate::utils::user_data_utils::user_data_url; + +#[derive(Serialize)] +#[allow(non_snake_case)] +pub struct ConversationMessageAPI { + ID: u64, + convID: u64, + ID_user: u64, + time_insert: u64, + message: String, + image_path: Option, +} + +impl ConversationMessageAPI { + /// Turn a conversation message into an API entry + pub fn new(msg: &ConversationMessage) -> ConversationMessageAPI { + ConversationMessageAPI { + ID: msg.id, + convID: msg.conv_id, + ID_user: msg.user_id as u64, + time_insert: msg.time_sent, + message: msg.message.clone().unwrap_or(String::new()), + image_path: msg.image_path.as_ref().map(|f| user_data_url(f)), + } + } + + /// Turn a list of conversation messages into API entries + pub fn for_list(l: &Vec) -> Vec { + l.iter() + .map(|m| ConversationMessageAPI::new(m)) + .collect() + } +} \ No newline at end of file diff --git a/src/api_data/conversations_refresh_api.rs b/src/api_data/conversations_refresh_api.rs new file mode 100644 index 0000000..7709e26 --- /dev/null +++ b/src/api_data/conversations_refresh_api.rs @@ -0,0 +1,37 @@ +//! # Conversation refresh result +//! +//! Note : this structure is now deprecated and should no longer be used for further developments +//! +//! @author Pierre Hubert + +use std::collections::HashMap; + +use serde::Serialize; + +use crate::api_data::conversation_message_api::ConversationMessageAPI; +use crate::data::conversation_message::ConversationMessage; + +#[derive(Serialize)] +#[allow(non_snake_case)] +pub struct ConversationRefreshResultAPI { + #[serde(flatten)] + list: HashMap>, +} + +impl ConversationRefreshResultAPI { + /// Create a new list + pub fn new(list: HashMap>) -> ConversationRefreshResultAPI { + let list = list + .iter() + .map(|v| ( + format!("conversation-{}", v.0), + ConversationMessageAPI::for_list(v.1) + )) + .collect(); + + ConversationRefreshResultAPI { + list + } + } +} + diff --git a/src/api_data/mod.rs b/src/api_data/mod.rs index 0653c79..42bf7ba 100644 --- a/src/api_data/mod.rs +++ b/src/api_data/mod.rs @@ -17,4 +17,6 @@ pub mod res_find_virtual_directory; pub mod res_create_conversation; pub mod conversation_api; mod legacy_api_bool; -pub mod res_find_private_conversations; \ No newline at end of file +pub mod res_find_private_conversations; +pub mod conversation_message_api; +pub mod conversations_refresh_api; \ No newline at end of file diff --git a/src/controllers/conversations_controller.rs b/src/controllers/conversations_controller.rs index 4355220..6c35eb2 100644 --- a/src/controllers/conversations_controller.rs +++ b/src/controllers/conversations_controller.rs @@ -2,7 +2,10 @@ //! //! @author Pierre Hubert +use std::collections::HashMap; + use crate::api_data::conversation_api::ConversationAPI; +use crate::api_data::conversations_refresh_api::ConversationRefreshResultAPI; use crate::api_data::res_create_conversation::ResCreateConversation; use crate::api_data::res_find_private_conversations::ResFindPrivateConversations; use crate::controllers::routes::RequestResult; @@ -160,5 +163,24 @@ pub fn find_private(r: &mut HttpRequestHandler) -> RequestResult { /// /// This method was used only by ComunicWeb before the introduction of WebSockets pub fn refresh_list(r: &mut HttpRequestHandler) -> RequestResult { - r.success("Can implement") + let mut list = HashMap::new(); + + // Check for new conversations + if r.has_post_parameter("newConversations") { + for conv_id in r.post_numbers_list("newConversations", 0)? { + if !conversations_helper::does_user_belongs_to(r.user_id()?, conv_id as u64)? { + r.forbidden(format!("Your do not belongs to conversation {} !", conv_id))?; + } + + let msgs_conv = conversations_helper::get_last_messages(conv_id as u64, 10)?; + list.insert(conv_id as u64, msgs_conv); + + //TODO : mark user seen + } + + // TODO : Check for refresh of already initialized conversations + } + + + r.set_response(ConversationRefreshResultAPI::new(list)) } \ No newline at end of file diff --git a/src/data/conversation_message.rs b/src/data/conversation_message.rs new file mode 100644 index 0000000..a7a6e57 --- /dev/null +++ b/src/data/conversation_message.rs @@ -0,0 +1,15 @@ +//! # Conversation message +//! +//! Information about a single conversation message + +use crate::data::user::UserID; + +/// Information about a single conversation message +pub struct ConversationMessage { + pub id: u64, + pub time_sent: u64, + pub conv_id: u64, + pub user_id: UserID, + pub message: Option, + pub image_path: Option, +} \ No newline at end of file diff --git a/src/data/mod.rs b/src/data/mod.rs index 06fbdc6..3ef9e4f 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -8,4 +8,5 @@ pub mod user; pub mod user_token; pub mod custom_emoji; pub mod new_conversation; -pub mod conversation; \ No newline at end of file +pub mod conversation; +pub mod conversation_message; \ No newline at end of file diff --git a/src/helpers/conversations_helper.rs b/src/helpers/conversations_helper.rs index f535c65..10c5dfc 100644 --- a/src/helpers/conversations_helper.rs +++ b/src/helpers/conversations_helper.rs @@ -2,7 +2,7 @@ //! //! @author Pierre Hubert -use crate::constants::database_tables_names::{CONV_LIST_TABLE, CONV_USERS_TABLE}; +use crate::constants::database_tables_names::{CONV_LIST_TABLE, CONV_USERS_TABLE, CONV_MESSAGES_TABLE}; use crate::data::conversation::Conversation; use crate::data::error::{ExecError, ResultBoxError}; use crate::data::new_conversation::NewConversation; @@ -10,6 +10,7 @@ use crate::data::user::UserID; use crate::helpers::database::InsertQuery; use crate::helpers::database; use crate::utils::date_utils::time; +use crate::data::conversation_message::ConversationMessage; /// Create a new conversation. This method returns the ID of the created conversation pub fn create(conv: &NewConversation) -> ResultBoxError { @@ -199,6 +200,19 @@ pub fn find_private(user_1: UserID, user_2: UserID) -> ResultBoxError> .exec(|f|f.get_u64("conv_id")) } +/// Get the last messages posted in a conversation +pub fn get_last_messages(conv_id: u64, number_of_messages: u64) -> ResultBoxError> { + database::QueryInfo::new(CONV_MESSAGES_TABLE) + .cond_u64("conv_id", conv_id) + .set_limit(number_of_messages) + .set_order("id DESC") + .exec(db_to_conversation_message) + .map(|mut l| { + l.sort_by(|a,b| a.id.partial_cmp(&b.id).unwrap()); + l + }) +} + /// Turn a database entry into a ConversationInfo object fn db_to_conversation_info(row: &database::RowResult) -> ResultBoxError { let conv_id = row.get_u64("id")?; @@ -213,4 +227,17 @@ fn db_to_conversation_info(row: &database::RowResult) -> ResultBoxError ResultBoxError { + Ok(ConversationMessage { + id: row.get_u64("id")?, + time_sent: row.get_u64("time_insert")?, + conv_id: row.get_u64("conv_id")?, + user_id: row.get_user_id("user_id")?, + message: row.get_optional_str("message")?, + image_path: row.get_optional_str("image_path")? + }) } \ No newline at end of file diff --git a/src/helpers/database.rs b/src/helpers/database.rs index c67f896..a194279 100644 --- a/src/helpers/database.rs +++ b/src/helpers/database.rs @@ -150,6 +150,12 @@ impl QueryInfo { self } + /// Set the limit for the request + pub fn set_limit(mut self, value: u64) -> QueryInfo { + self.limit = value; + self + } + /// Set results ordering pub fn set_order(mut self, order: &str) -> QueryInfo { self.order = Some(order.to_string());