1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2024-11-26 23:39:22 +00:00

Can open new conversations

This commit is contained in:
Pierre HUBERT 2020-06-18 14:15:17 +02:00
parent 479caa3945
commit e7de23e995
8 changed files with 156 additions and 4 deletions

View File

@ -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<String>,
}
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<ConversationMessage>) -> Vec<ConversationMessageAPI> {
l.iter()
.map(|m| ConversationMessageAPI::new(m))
.collect()
}
}

View File

@ -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<String, Vec<ConversationMessageAPI>>,
}
impl ConversationRefreshResultAPI {
/// Create a new list
pub fn new(list: HashMap<u64, Vec<ConversationMessage>>) -> ConversationRefreshResultAPI {
let list = list
.iter()
.map(|v| (
format!("conversation-{}", v.0),
ConversationMessageAPI::for_list(v.1)
))
.collect();
ConversationRefreshResultAPI {
list
}
}
}

View File

@ -18,3 +18,5 @@ pub mod res_create_conversation;
pub mod conversation_api; pub mod conversation_api;
mod legacy_api_bool; mod legacy_api_bool;
pub mod res_find_private_conversations; pub mod res_find_private_conversations;
pub mod conversation_message_api;
pub mod conversations_refresh_api;

View File

@ -2,7 +2,10 @@
//! //!
//! @author Pierre Hubert //! @author Pierre Hubert
use std::collections::HashMap;
use crate::api_data::conversation_api::ConversationAPI; 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_create_conversation::ResCreateConversation;
use crate::api_data::res_find_private_conversations::ResFindPrivateConversations; use crate::api_data::res_find_private_conversations::ResFindPrivateConversations;
use crate::controllers::routes::RequestResult; 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 /// This method was used only by ComunicWeb before the introduction of WebSockets
pub fn refresh_list(r: &mut HttpRequestHandler) -> RequestResult { 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))
} }

View File

@ -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<String>,
pub image_path: Option<String>,
}

View File

@ -9,3 +9,4 @@ pub mod user_token;
pub mod custom_emoji; pub mod custom_emoji;
pub mod new_conversation; pub mod new_conversation;
pub mod conversation; pub mod conversation;
pub mod conversation_message;

View File

@ -2,7 +2,7 @@
//! //!
//! @author Pierre Hubert //! @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::conversation::Conversation;
use crate::data::error::{ExecError, ResultBoxError}; use crate::data::error::{ExecError, ResultBoxError};
use crate::data::new_conversation::NewConversation; use crate::data::new_conversation::NewConversation;
@ -10,6 +10,7 @@ use crate::data::user::UserID;
use crate::helpers::database::InsertQuery; use crate::helpers::database::InsertQuery;
use crate::helpers::database; use crate::helpers::database;
use crate::utils::date_utils::time; 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 /// Create a new conversation. This method returns the ID of the created conversation
pub fn create(conv: &NewConversation) -> ResultBoxError<u64> { pub fn create(conv: &NewConversation) -> ResultBoxError<u64> {
@ -199,6 +200,19 @@ pub fn find_private(user_1: UserID, user_2: UserID) -> ResultBoxError<Vec<u64>>
.exec(|f|f.get_u64("conv_id")) .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<Vec<ConversationMessage>> {
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 /// Turn a database entry into a ConversationInfo object
fn db_to_conversation_info(row: &database::RowResult) -> ResultBoxError<Conversation> { fn db_to_conversation_info(row: &database::RowResult) -> ResultBoxError<Conversation> {
let conv_id = row.get_u64("id")?; let conv_id = row.get_u64("id")?;
@ -214,3 +228,16 @@ fn db_to_conversation_info(row: &database::RowResult) -> ResultBoxError<Conversa
saw_last_message: row.get_legacy_bool("saw_last_message")?, saw_last_message: row.get_legacy_bool("saw_last_message")?,
}) })
} }
/// Turn a database entry into a ConversationMessgae object
fn db_to_conversation_message(row: &database::RowResult) -> ResultBoxError<ConversationMessage> {
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")?
})
}

View File

@ -150,6 +150,12 @@ impl QueryInfo {
self self
} }
/// Set the limit for the request
pub fn set_limit(mut self, value: u64) -> QueryInfo {
self.limit = value;
self
}
/// Set results ordering /// Set results ordering
pub fn set_order(mut self, order: &str) -> QueryInfo { pub fn set_order(mut self, order: &str) -> QueryInfo {
self.order = Some(order.to_string()); self.order = Some(order.to_string());