diff --git a/Cargo.lock b/Cargo.lock index f0470c5..cc1b8e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -517,6 +517,7 @@ dependencies = [ "percent-encoding", "rand", "serde", + "serde_json", "sha1", "yaml-rust", ] diff --git a/Cargo.toml b/Cargo.toml index 9d83c5b..a3bc8dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ mysql = "18.2.0" actix-web = "2.0.0" actix-rt = "1.1.1" serde = "1.0.110" +serde_json = "1.0.53" futures = "0.3.5" encoding_rs = "0.8.23" percent-encoding = "2.1.0" diff --git a/src/controllers/conversations_controller.rs b/src/controllers/conversations_controller.rs index 7f4ec80..3fb26f3 100644 --- a/src/controllers/conversations_controller.rs +++ b/src/controllers/conversations_controller.rs @@ -177,10 +177,37 @@ pub fn refresh_list(r: &mut HttpRequestHandler) -> RequestResult { conversations_helper::mark_user_seen(conv_id as u64, r.user_id()?)?; } - - // TODO : Check for refresh of already initialized conversations } + // Check for refresh of already initialized conversations + if r.has_post_parameter("toRefresh") { + let v: HashMap> = + serde_json::from_str(r.post_string("toRefresh")?.as_str())?; + + for (k, v) in v { + // Get conversation ID + if !k.starts_with("conversation-") { + return r.bad_request("Entries of 'toRefresh' must start with 'conversation-'!".to_string()); + } + let conv_id = k.replace("conversation-", "").parse::()?; + + // Extract last message id + if !v.contains_key("last_message_id") { + return r.bad_request(format!("Missing 'last_message_id' in conversation {}!", conv_id)); + } + let last_message_id = v["last_message_id"].as_u64().unwrap_or(0); + + // Check user rights + if !conversations_helper::does_user_belongs_to(r.user_id()?, conv_id)? { + return r.forbidden(format!("You do not belong to conversation {}!", conv_id)); + } + + let list_conv = conversations_helper::get_new_messages(conv_id, last_message_id)?; + list.insert(conv_id, list_conv); + + conversations_helper::mark_user_seen(conv_id as u64, r.user_id()?)?; + } + } r.set_response(ConversationRefreshResultAPI::new(list)) } \ No newline at end of file diff --git a/src/helpers/conversations_helper.rs b/src/helpers/conversations_helper.rs index 9c70078..bb89e2c 100644 --- a/src/helpers/conversations_helper.rs +++ b/src/helpers/conversations_helper.rs @@ -213,6 +213,16 @@ pub fn get_last_messages(conv_id: u64, number_of_messages: u64) -> ResultBoxErro }) } +/// Get the new messages of a conversation +pub fn get_new_messages(conv_id: u64, last_message_id: u64) -> ResultBoxError> { + database::QueryInfo::new(CONV_MESSAGES_TABLE) + .cond_u64("conv_id", conv_id) + .set_custom_where("id > ?") + .add_custom_where_argument_u64(last_message_id) + .set_order("id") + .exec(db_to_conversation_message) +} + /// Indicate that a user has seen the last messages of a conversation pub fn mark_user_seen(conv_id: u64, user_id: UserID) -> ResultBoxError<()> { database::UpdateInfo::new(CONV_USERS_TABLE) diff --git a/src/helpers/database.rs b/src/helpers/database.rs index d370e59..921e76a 100644 --- a/src/helpers/database.rs +++ b/src/helpers/database.rs @@ -71,6 +71,9 @@ pub struct QueryInfo { /// Custom WHERE condition pub custom_where: Option, + /// Custom WHERE values + pub custom_where_ars: Vec, + /// Limit of the query (0 = no limit) pub limit: u64, @@ -92,6 +95,7 @@ impl QueryInfo { joins: Vec::new(), conditions: collections::HashMap::new(), custom_where: None, + custom_where_ars: vec![], limit: 0, order: None, fields: Vec::new(), @@ -144,6 +148,12 @@ impl QueryInfo { self } + /// Add a custom u64 WHERE value + pub fn add_custom_where_argument_u64(mut self, val: u64) -> QueryInfo { + self.custom_where_ars.push(mysql::Value::UInt(val)); + self + } + /// Append a field to the list of selected fields pub fn add_field(mut self, key: &str) -> QueryInfo { self.fields.push(key.to_string()); @@ -349,7 +359,7 @@ pub fn query ProcessRowResult>(info: QueryInfo, proce for (k, v) in info.conditions { where_args.push(format!("{} = ?", k)); - params.push(v) + params.push(mysql::Value::from(v)); } let where_args = format!(" WHERE {} ", where_args.join(" AND ")); @@ -359,6 +369,9 @@ pub fn query ProcessRowResult>(info: QueryInfo, proce // Custom WHERE clause if let Some(custom_where) = info.custom_where { query = query.add(format!(" AND ({})", custom_where).as_str()); + + let mut custom_args = info.custom_where_ars; + params.append(&mut custom_args); } // ORDER clause