2020-06-04 13:36:57 +02:00
|
|
|
//! # Conversations helper
|
|
|
|
//!
|
|
|
|
//! @author Pierre Hubert
|
|
|
|
|
2021-03-02 18:57:34 +01:00
|
|
|
use crate::constants::database_tables_names::{CONV_LIST_TABLE, CONV_MEMBERS_TABLE, CONV_MESSAGES_TABLE};
|
2021-03-04 18:51:52 +01:00
|
|
|
use crate::data::conversation::{Conversation, ConversationMember, ConversationMemberSetting, ConvID, NewConversationSettings};
|
2021-03-02 18:57:34 +01:00
|
|
|
use crate::data::conversation_message::{ConversationMessage, ConversationMessageFile, ConversationServerMessageType};
|
2021-02-14 19:15:04 +01:00
|
|
|
use crate::data::error::{ExecError, Res, ResultBoxError};
|
2020-06-15 14:52:23 +02:00
|
|
|
use crate::data::new_conversation::NewConversation;
|
2020-06-22 12:19:13 +02:00
|
|
|
use crate::data::new_conversation_message::NewConversationMessage;
|
2021-02-14 19:15:04 +01:00
|
|
|
use crate::data::user::{User, UserID};
|
2021-02-06 09:41:56 +01:00
|
|
|
use crate::helpers::{database, events_helper};
|
2021-03-04 18:51:52 +01:00
|
|
|
use crate::helpers::database::{InsertQuery, UpdateInfo};
|
2021-02-06 09:41:56 +01:00
|
|
|
use crate::helpers::events_helper::Event;
|
2020-06-15 14:52:23 +02:00
|
|
|
use crate::utils::date_utils::time;
|
2021-03-02 18:57:34 +01:00
|
|
|
use crate::utils::user_data_utils::delete_user_data_file_if_exists;
|
2020-06-04 13:36:57 +02:00
|
|
|
|
|
|
|
/// Create a new conversation. This method returns the ID of the created conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn create(conv: &NewConversation) -> Res<ConvID> {
|
2020-06-04 13:36:57 +02:00
|
|
|
// Create the conversation in the main table
|
|
|
|
let conv_id = InsertQuery::new(CONV_LIST_TABLE)
|
2020-06-25 10:08:34 +02:00
|
|
|
.add_user_id("user_id", &conv.owner_id)
|
2020-06-04 13:36:57 +02:00
|
|
|
.add_str("name", conv.name.clone().unwrap_or(String::new()).as_str())
|
2021-03-04 18:51:52 +01:00
|
|
|
.add_u64("last_activity", time())
|
2020-06-04 13:36:57 +02:00
|
|
|
.add_u64("creation_time", time())
|
2021-03-04 18:51:52 +01:00
|
|
|
.add_opt_str("color", Option::from(&conv.color))
|
|
|
|
.add_opt_str("background", Option::from(&conv.background))
|
2020-06-04 13:36:57 +02:00
|
|
|
.add_legacy_bool("can_everyone_add_members", conv.can_everyone_add_members)
|
2021-03-04 18:51:52 +01:00
|
|
|
.add_opt_group_id("group_id", conv.group_id.clone())
|
|
|
|
.insert()?
|
|
|
|
.map(|i| ConvID::new(i))
|
|
|
|
.ok_or(ExecError::new("missing result conv id!"))?;
|
2020-06-04 13:36:57 +02:00
|
|
|
|
|
|
|
// Add the members to the conversation
|
|
|
|
for member in &conv.members {
|
2021-03-04 18:51:52 +01:00
|
|
|
|
2020-06-04 13:36:57 +02:00
|
|
|
// Check following status of the member
|
|
|
|
let mut follow = true;
|
2021-03-04 18:51:52 +01:00
|
|
|
let mut admin = false;
|
2020-06-04 13:36:57 +02:00
|
|
|
if member.eq(&conv.owner_id) {
|
|
|
|
follow = conv.owner_following;
|
2021-03-04 18:51:52 +01:00
|
|
|
admin = true;
|
2020-06-04 13:36:57 +02:00
|
|
|
}
|
|
|
|
|
2021-03-04 18:51:52 +01:00
|
|
|
add_member(conv_id, member, follow, admin)?;
|
2020-06-04 13:36:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(conv_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Add a member to a conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn add_member(conv_id: ConvID, user_id: &UserID, following: bool, admin: bool) -> Res {
|
2021-03-02 17:32:24 +01:00
|
|
|
InsertQuery::new(CONV_MEMBERS_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.add_conv_id("conv_id", conv_id)
|
2020-06-04 13:36:57 +02:00
|
|
|
.add_user_id("user_id", user_id)
|
2021-03-04 18:51:52 +01:00
|
|
|
.add_u64("added_on", time())
|
2020-06-04 13:36:57 +02:00
|
|
|
.add_legacy_bool("following", following)
|
2021-03-04 18:51:52 +01:00
|
|
|
.add_legacy_bool("is_admin", admin)
|
|
|
|
.add_u64("last_message_seen", 0)
|
2020-06-04 13:36:57 +02:00
|
|
|
.insert()?;
|
|
|
|
|
2021-03-04 18:51:52 +01:00
|
|
|
// TODO : create a message
|
|
|
|
|
2020-06-04 13:36:57 +02:00
|
|
|
Ok(())
|
2020-06-04 19:01:35 +02:00
|
|
|
}
|
|
|
|
|
2021-03-04 18:51:52 +01:00
|
|
|
/// Update admin status of a member for a conversation
|
|
|
|
pub fn set_admin(conv_id: &ConvID, user_id: &UserID, admin: bool) -> Res {
|
|
|
|
UpdateInfo::new(CONV_MEMBERS_TABLE)
|
|
|
|
.cond_user_id("user_id", user_id)
|
|
|
|
.cond_conv_id("conv_id", conv_id.clone())
|
|
|
|
.set_legacy_bool("is_admin", admin)
|
|
|
|
.exec()
|
|
|
|
}
|
|
|
|
|
2020-06-15 10:46:10 +02:00
|
|
|
/// Remove a member from a conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn remove_member(conv_id: ConvID, user_id: &UserID) -> ResultBoxError<()> {
|
2021-03-02 17:32:24 +01:00
|
|
|
database::DeleteQuery::new(CONV_MEMBERS_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-15 10:46:10 +02:00
|
|
|
.cond_user_id("user_id", user_id)
|
2021-03-04 18:51:52 +01:00
|
|
|
.exec()?;
|
|
|
|
|
|
|
|
// TODO : create a message
|
|
|
|
|
|
|
|
Ok(())
|
2020-06-15 10:46:10 +02:00
|
|
|
}
|
|
|
|
|
2020-06-04 19:01:35 +02:00
|
|
|
/// Get the list of conversations of a specific user
|
2020-06-25 10:08:34 +02:00
|
|
|
pub fn get_list_user(user_id: &UserID) -> ResultBoxError<Vec<Conversation>> {
|
2020-06-04 19:01:35 +02:00
|
|
|
database::QueryInfo::new(CONV_LIST_TABLE)
|
|
|
|
.alias("l")
|
|
|
|
|
|
|
|
// Join with conversation members table
|
2021-03-02 17:32:24 +01:00
|
|
|
.join(CONV_MEMBERS_TABLE, "u", "l.id = u.conv_id")
|
2020-06-04 19:01:35 +02:00
|
|
|
|
|
|
|
// Specify selected fields
|
2021-03-04 18:51:52 +01:00
|
|
|
.add_field("l.*")
|
2020-06-04 19:01:35 +02:00
|
|
|
|
|
|
|
// Filter query
|
|
|
|
.cond_user_id("u.user_id", user_id)
|
|
|
|
|
|
|
|
// Sort results
|
2021-03-04 18:51:52 +01:00
|
|
|
.set_order("l.last_activity DESC")
|
2020-06-04 19:01:35 +02:00
|
|
|
|
|
|
|
// Execute query
|
|
|
|
.exec(db_to_conversation_info)
|
|
|
|
}
|
|
|
|
|
2020-06-12 09:20:32 +02:00
|
|
|
/// Get information about a single conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn get_single(conv_id: ConvID) -> ResultBoxError<Conversation> {
|
2020-06-12 09:20:32 +02:00
|
|
|
// Tables
|
|
|
|
database::QueryInfo::new(CONV_LIST_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("id", conv_id)
|
2020-06-12 09:20:32 +02:00
|
|
|
.query_row(db_to_conversation_info)
|
|
|
|
}
|
|
|
|
|
2020-06-04 19:01:35 +02:00
|
|
|
/// Get the list of members of a conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn get_list_members(conv_id: ConvID) -> Res<Vec<ConversationMember>> {
|
2021-03-02 17:32:24 +01:00
|
|
|
database::QueryInfo::new(CONV_MEMBERS_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
|
|
|
.exec(db_to_conversation_member)
|
2020-06-12 09:04:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if a user belongs to a conversation or not
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn get_user_membership(user_id: &UserID, conv_id: ConvID) -> Res<ConversationMember> {
|
|
|
|
database::QueryInfo::new(CONV_MEMBERS_TABLE)
|
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-12 09:04:43 +02:00
|
|
|
.cond_user_id("user_id", user_id)
|
2021-03-04 18:51:52 +01:00
|
|
|
.query_row(db_to_conversation_member)
|
2020-06-04 19:01:35 +02:00
|
|
|
}
|
|
|
|
|
2020-06-15 09:29:38 +02:00
|
|
|
|
|
|
|
/// Check out whether all the members of a conversation can add members to it or not
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn can_everyone_add_members(conv_id: ConvID) -> ResultBoxError<bool> {
|
2020-06-15 09:29:38 +02:00
|
|
|
database::QueryInfo::new(CONV_LIST_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("id", conv_id)
|
2020-06-15 09:29:38 +02:00
|
|
|
.add_field("can_everyone_add_members")
|
2020-06-15 10:47:34 +02:00
|
|
|
.query_row(|f| f.get_legacy_bool("can_everyone_add_members"))
|
2020-06-15 09:29:38 +02:00
|
|
|
}
|
2020-06-12 11:26:12 +02:00
|
|
|
|
2020-06-15 08:23:23 +02:00
|
|
|
/// Set whether a user is following a conversation or not
|
2021-03-05 11:58:31 +01:00
|
|
|
pub fn set_following(user_id: &UserID, conv_id: ConvID, following: bool) -> ResultBoxError<()> {
|
2021-03-02 17:32:24 +01:00
|
|
|
database::UpdateInfo::new(CONV_MEMBERS_TABLE)
|
2021-03-05 11:58:31 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-15 08:23:23 +02:00
|
|
|
.cond_user_id("user_id", user_id)
|
|
|
|
.set_legacy_bool("following", following)
|
|
|
|
.exec()
|
|
|
|
}
|
|
|
|
|
2020-06-15 10:46:10 +02:00
|
|
|
/// Set a new list of members for a given conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn set_members(conv_id: ConvID, new_list: &Vec<ConversationMemberSetting>, can_delete: bool) -> ResultBoxError<()> {
|
2020-06-15 10:46:10 +02:00
|
|
|
let curr_list = get_list_members(conv_id)?;
|
|
|
|
|
|
|
|
// Add new members
|
|
|
|
for member in new_list {
|
2021-03-04 18:51:52 +01:00
|
|
|
if let Some(user) = curr_list.iter().filter(|m| m.user_id == member.user_id).next() {
|
|
|
|
// Check if we have to update admin state
|
|
|
|
if user.is_admin != member.set_admin {
|
|
|
|
set_admin(&conv_id, &member.user_id, member.set_admin)?;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
add_member(conv_id, &member.user_id, true, member.set_admin)?;
|
2020-06-15 10:46:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-15 10:47:34 +02:00
|
|
|
// Remove a member
|
2020-06-15 10:46:10 +02:00
|
|
|
if can_delete {
|
|
|
|
for member in curr_list {
|
2021-03-04 18:51:52 +01:00
|
|
|
if new_list.iter().any(|m| m.user_id.eq(&member.user_id)) {
|
2020-06-15 10:46:10 +02:00
|
|
|
continue;
|
|
|
|
}
|
2021-03-04 18:51:52 +01:00
|
|
|
remove_member(conv_id, &member.user_id)?;
|
2020-06-15 10:46:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-06-15 14:30:01 +02:00
|
|
|
/// Set a new name to the conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn set_settings(settings: NewConversationSettings) -> Res {
|
2020-06-15 14:30:01 +02:00
|
|
|
database::UpdateInfo::new(CONV_LIST_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("id", settings.conv_id)
|
|
|
|
.set_opt_str("name", settings.name)
|
|
|
|
.set_opt_str("color", settings.color)
|
|
|
|
.set_legacy_bool("can_everyone_add_members", settings.can_everyone_add_members)
|
2020-06-15 14:52:23 +02:00
|
|
|
.exec()
|
|
|
|
}
|
|
|
|
|
2020-06-18 09:26:25 +02:00
|
|
|
/// Search for private conversation between two users
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn find_private(user_1: &UserID, user_2: &UserID) -> ResultBoxError<Vec<ConvID>> {
|
2021-03-02 17:32:24 +01:00
|
|
|
database::QueryInfo::new(CONV_MEMBERS_TABLE)
|
2020-06-18 09:26:25 +02:00
|
|
|
.alias("t1")
|
|
|
|
|
|
|
|
// Join
|
2021-03-02 17:32:24 +01:00
|
|
|
.join(CONV_MEMBERS_TABLE, "t2", "t1.conv_id = t2.conv_id")
|
2020-06-18 09:26:25 +02:00
|
|
|
|
|
|
|
// Conditions
|
|
|
|
.cond_user_id("t1.user_id", user_1)
|
|
|
|
.cond_user_id("t2.user_id", user_2)
|
2021-03-02 17:32:24 +01:00
|
|
|
.set_custom_where(format!("(SELECT COUNT(*) FROM {} WHERE conv_id = t1.conv_id) = 2", CONV_MEMBERS_TABLE).as_ref())
|
2020-06-18 09:26:25 +02:00
|
|
|
.add_field("t1.conv_id AS conv_id")
|
2021-03-04 18:51:52 +01:00
|
|
|
.exec(|f| f.get_conv_id("conv_id"))
|
2020-06-18 09:26:25 +02:00
|
|
|
}
|
|
|
|
|
2020-06-18 14:15:17 +02:00
|
|
|
/// Get the last messages posted in a conversation
|
2021-03-05 11:58:31 +01:00
|
|
|
pub fn get_last_messages(conv_id: ConvID, number_of_messages: u64) -> ResultBoxError<Vec<ConversationMessage>> {
|
2020-06-18 14:15:17 +02:00
|
|
|
database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
2021-03-05 11:58:31 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-18 14:15:17 +02:00
|
|
|
.set_limit(number_of_messages)
|
|
|
|
.set_order("id DESC")
|
|
|
|
.exec(db_to_conversation_message)
|
|
|
|
.map(|mut l| {
|
2020-06-18 14:33:43 +02:00
|
|
|
l.sort_by(|a, b| a.id.partial_cmp(&b.id).unwrap());
|
2020-06-18 14:15:17 +02:00
|
|
|
l
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-06-18 18:16:46 +02:00
|
|
|
/// Get the new messages of a conversation
|
2021-03-05 11:58:31 +01:00
|
|
|
pub fn get_new_messages(conv_id: ConvID, last_message_id: u64) -> ResultBoxError<Vec<ConversationMessage>> {
|
2020-06-18 18:16:46 +02:00
|
|
|
database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
2021-03-05 11:58:31 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-18 18:16:46 +02:00
|
|
|
.set_custom_where("id > ?")
|
|
|
|
.add_custom_where_argument_u64(last_message_id)
|
|
|
|
.set_order("id")
|
|
|
|
.exec(db_to_conversation_message)
|
|
|
|
}
|
|
|
|
|
2020-06-22 14:16:52 +02:00
|
|
|
/// Get older messages of a conversation
|
|
|
|
///
|
|
|
|
/// `conv_id` contains the ID of the target conversation
|
|
|
|
/// `start_id` contains the ID from wich the research start
|
|
|
|
/// `limit` Maximum number of messages to get
|
2021-03-05 11:58:31 +01:00
|
|
|
pub fn get_older_messages(conv_id: ConvID, start_id: u64, limit: u64) -> ResultBoxError<Vec<ConversationMessage>> {
|
2020-06-22 14:16:52 +02:00
|
|
|
database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
2021-03-05 11:58:31 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-22 14:16:52 +02:00
|
|
|
.set_custom_where("ID <= ?")
|
|
|
|
.add_custom_where_argument_u64(start_id)
|
|
|
|
.set_order("id DESC")
|
|
|
|
.set_limit(limit)
|
|
|
|
.exec(db_to_conversation_message)
|
|
|
|
.map(|mut l| {
|
|
|
|
l.sort_by(|a, b| a.id.partial_cmp(&b.id).unwrap());
|
|
|
|
l
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-06-23 07:44:42 +02:00
|
|
|
/// Get all the messages of a single user for a conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn get_user_messages_for_conversations(conv_id: ConvID, user_id: &UserID) -> ResultBoxError<Vec<ConversationMessage>> {
|
2020-06-23 07:44:42 +02:00
|
|
|
database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-23 07:44:42 +02:00
|
|
|
.cond_user_id("user_id", user_id)
|
|
|
|
.exec(db_to_conversation_message)
|
|
|
|
}
|
|
|
|
|
2020-07-14 07:54:40 +02:00
|
|
|
/// Export all the messages of a given user on all conversations
|
|
|
|
pub fn export_all_user_messages(user_id: &UserID) -> ResultBoxError<Vec<ConversationMessage>> {
|
|
|
|
database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
|
|
|
.cond_user_id("user_id", user_id)
|
|
|
|
.exec(db_to_conversation_message)
|
|
|
|
}
|
|
|
|
|
2021-02-14 19:15:04 +01:00
|
|
|
/// Clean old user conversation messages
|
|
|
|
pub fn clean_old_messages(user: &User) -> Res {
|
2021-02-15 17:38:25 +01:00
|
|
|
let lifetime = user.delete_conversation_messages_after.unwrap_or(0);
|
|
|
|
if lifetime < 1 {
|
2021-02-14 19:15:04 +01:00
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
|
|
|
let messages = database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
|
|
|
.cond_user_id("user_id", &user.id)
|
|
|
|
.set_custom_where("time_insert < ?")
|
2021-02-15 17:38:25 +01:00
|
|
|
.add_custom_where_argument_u64(time() - lifetime)
|
2021-02-14 19:15:04 +01:00
|
|
|
.exec(db_to_conversation_message)?;
|
|
|
|
|
|
|
|
for message in messages {
|
|
|
|
delete_message(&message)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-01-21 18:36:53 +01:00
|
|
|
/// Delete all the messages of a given user
|
|
|
|
pub fn delete_all_user_messages(user_id: &UserID) -> ResultBoxError {
|
|
|
|
for msg in &export_all_user_messages(user_id)? {
|
|
|
|
delete_message(msg)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-01-21 18:41:27 +01:00
|
|
|
/// Remove the user from all the conversations he belongs to
|
|
|
|
pub fn delete_all_user_conversations(user_id: &UserID) -> ResultBoxError {
|
|
|
|
for conversation in &get_list_user(user_id)? {
|
2021-03-04 18:51:52 +01:00
|
|
|
remove_user_from_conversation(user_id, conversation, user_id)?;
|
2021-01-21 18:41:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-06-23 08:03:30 +02:00
|
|
|
/// Get the entire list of messages of a given conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn get_all_messages(conv_id: ConvID) -> ResultBoxError<Vec<ConversationMessage>> {
|
2020-06-23 08:03:30 +02:00
|
|
|
database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-23 08:03:30 +02:00
|
|
|
.exec(db_to_conversation_message)
|
|
|
|
}
|
|
|
|
|
2020-06-23 14:09:52 +02:00
|
|
|
/// Get a single message specified by its ID
|
|
|
|
pub fn get_single_message(msg_id: u64) -> ResultBoxError<ConversationMessage> {
|
|
|
|
database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
|
|
|
.cond_u64("id", msg_id)
|
|
|
|
.query_row(db_to_conversation_message)
|
|
|
|
}
|
|
|
|
|
2020-06-22 12:19:13 +02:00
|
|
|
/// Send a new conversation message
|
|
|
|
pub fn send_message(msg: &NewConversationMessage) -> ResultBoxError<()> {
|
|
|
|
let t = time();
|
|
|
|
|
|
|
|
// Insert the message in the database
|
2021-03-04 18:51:52 +01:00
|
|
|
let mut msg_request = database::InsertQuery::new(CONV_MESSAGES_TABLE)
|
|
|
|
.add_conv_id("conv_id", msg.conv_id)
|
|
|
|
.add_u64("user_id", msg.user_id.as_ref().map(|u| u.id()).unwrap_or(0))
|
|
|
|
.add_u64("time_sent", t);
|
|
|
|
|
|
|
|
if let Some(server_msg) = &msg.server_message {
|
|
|
|
msg_request = msg_request.add_str("message", &server_msg.to_db());
|
|
|
|
} else if let Some(message) = &msg.message {
|
|
|
|
msg_request = msg_request.add_str("message", message);
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(file) = &msg.file {
|
|
|
|
msg_request = msg_request.add_str("file_path", &file.path)
|
|
|
|
.add_u64("file_size", file.size)
|
|
|
|
.add_str("file_name", &file.name)
|
|
|
|
.add_str("file_type", &file.r#type)
|
|
|
|
.add_opt_str("file_thumbnail", Option::from(&file.thumbnail));
|
|
|
|
}
|
|
|
|
|
|
|
|
let msg_id = msg_request.insert_expect_result()?;
|
2020-06-22 12:19:13 +02:00
|
|
|
|
|
|
|
// Update the last activity of the conversation
|
|
|
|
database::UpdateInfo::new(CONV_LIST_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("id", msg.conv_id)
|
|
|
|
.set_u64("last_activity", t)
|
2020-06-22 12:19:13 +02:00
|
|
|
.exec()?;
|
|
|
|
|
2021-02-06 16:26:53 +01:00
|
|
|
// Get the list of users to notify after the update
|
2021-03-02 17:32:24 +01:00
|
|
|
let list_to_notify = database::QueryInfo::new(CONV_MEMBERS_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("conv_id", msg.conv_id)
|
2021-02-06 16:26:53 +01:00
|
|
|
.cond_legacy_bool("following", true)
|
|
|
|
.set_custom_where("user_id != ?")
|
2021-03-04 18:51:52 +01:00
|
|
|
.add_custom_where_argument_user_id(msg.user_id.as_ref().unwrap_or(&UserID::invalid()))
|
2021-02-06 16:26:53 +01:00
|
|
|
.exec(|r| r.get_user_id("user_id"))?;
|
|
|
|
|
2021-03-04 18:51:52 +01:00
|
|
|
// Mark the user has seen his message
|
|
|
|
if let Some(user_id) = &msg.user_id {
|
|
|
|
mark_user_seen(msg.conv_id, user_id, msg_id)?;
|
|
|
|
}
|
2020-06-22 12:19:13 +02:00
|
|
|
|
2021-02-06 16:26:53 +01:00
|
|
|
// Send an event (updated_number_unread_conversations)
|
|
|
|
events_helper::propagate_event(&Event::UpdatedNumberUnreadConversations(&list_to_notify))?;
|
2021-02-06 09:41:56 +01:00
|
|
|
|
|
|
|
// Send an event (sent_conversation_message)
|
|
|
|
events_helper::propagate_event(&Event::NewConversationMessage(&get_single_message(msg_id)?))?;
|
2021-02-05 15:14:47 +01:00
|
|
|
|
2020-06-22 12:19:13 +02:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-06-23 14:02:16 +02:00
|
|
|
/// Update message content
|
|
|
|
pub fn update_message_content(msg_id: u64, new_content: &str) -> ResultBoxError<()> {
|
|
|
|
database::UpdateInfo::new(CONV_MESSAGES_TABLE)
|
|
|
|
.cond_u64("id", msg_id)
|
|
|
|
.set_str("message", new_content)
|
2021-02-05 15:14:47 +01:00
|
|
|
.exec()?;
|
|
|
|
|
2021-02-06 09:41:56 +01:00
|
|
|
// Send an event (conv_message_updated)
|
|
|
|
events_helper::propagate_event(&Event::UpdatedConversationMessage(&get_single_message(msg_id)?))?;
|
2021-02-05 15:14:47 +01:00
|
|
|
|
|
|
|
Ok(())
|
2020-06-23 14:02:16 +02:00
|
|
|
}
|
|
|
|
|
2020-06-23 07:44:42 +02:00
|
|
|
/// Remove a message from a conversation
|
|
|
|
pub fn delete_message(msg: &ConversationMessage) -> ResultBoxError<()> {
|
|
|
|
|
2021-03-02 18:57:34 +01:00
|
|
|
// Delete associated files
|
|
|
|
if let Some(file) = &msg.file {
|
|
|
|
delete_user_data_file_if_exists(&file.path)?;
|
|
|
|
|
|
|
|
if let Some(thumb) = &file.thumbnail {
|
|
|
|
delete_user_data_file_if_exists(thumb)?;
|
2020-06-23 07:44:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
database::DeleteQuery::new(CONV_MESSAGES_TABLE)
|
|
|
|
.cond_u64("ID", msg.id)
|
|
|
|
.exec()?;
|
|
|
|
|
2021-02-06 09:41:56 +01:00
|
|
|
// Send en event (conv_message_deleted)
|
|
|
|
events_helper::propagate_event(&Event::DeleteConversationMessage(msg))?;
|
2021-02-05 15:14:47 +01:00
|
|
|
|
2020-06-23 07:44:42 +02:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-06-23 14:09:52 +02:00
|
|
|
/// Delete a message with a specific ID
|
|
|
|
pub fn delete_message_by_id(id: u64) -> ResultBoxError<()> {
|
|
|
|
delete_message(&get_single_message(id)?)
|
|
|
|
}
|
|
|
|
|
2020-06-22 14:32:14 +02:00
|
|
|
/// Count the number of unread conversation for a specified user
|
2020-06-25 10:08:34 +02:00
|
|
|
pub fn count_unread_for_user(user_id: &UserID) -> ResultBoxError<usize> {
|
2021-03-05 11:58:31 +01:00
|
|
|
get_list_unread(user_id).map(|l| l.len())
|
2020-06-22 14:32:14 +02:00
|
|
|
}
|
|
|
|
|
2020-06-22 18:55:24 +02:00
|
|
|
/// Get the list of unread conversations of a user
|
2021-03-05 11:58:31 +01:00
|
|
|
pub fn get_list_unread(user_id: &UserID) -> ResultBoxError<Vec<ConvID>> {
|
|
|
|
// First, get the ID of unread conversation
|
2021-03-02 17:32:24 +01:00
|
|
|
database::QueryInfo::new(CONV_MEMBERS_TABLE)
|
2021-03-05 11:58:31 +01:00
|
|
|
.alias("mem")
|
|
|
|
.join(CONV_MESSAGES_TABLE, "mess", "mem.conv_id = mess.conv_id")
|
|
|
|
|
|
|
|
.cond_user_id("mem.user_id", user_id)
|
|
|
|
.cond_legacy_bool("mem.following", true)
|
|
|
|
|
|
|
|
.set_custom_where("mem.last_message_seen < mess.id")
|
|
|
|
|
|
|
|
.add_field("distinct mem.conv_id")
|
|
|
|
|
|
|
|
.exec(|r| r.get_conv_id("conv_id"))
|
2020-06-22 18:55:24 +02:00
|
|
|
}
|
|
|
|
|
2020-06-18 14:33:43 +02:00
|
|
|
/// Indicate that a user has seen the last messages of a conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn mark_user_seen(conv_id: ConvID, user_id: &UserID, last_msg: u64) -> ResultBoxError<()> {
|
2021-03-02 17:32:24 +01:00
|
|
|
database::UpdateInfo::new(CONV_MEMBERS_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("conv_id", conv_id)
|
2020-06-18 14:33:43 +02:00
|
|
|
.cond_user_id("user_id", user_id)
|
2021-03-04 18:51:52 +01:00
|
|
|
.set_u64("last_message_seen", last_msg)
|
2021-02-05 15:14:47 +01:00
|
|
|
.exec()?;
|
|
|
|
|
2021-02-06 16:26:53 +01:00
|
|
|
// Push an event (updated_number_unread_conversations)
|
|
|
|
events_helper::propagate_event(&Event::UpdatedNumberUnreadConversations(&vec![user_id.clone()]))?;
|
2021-02-05 15:14:47 +01:00
|
|
|
|
|
|
|
Ok(())
|
2020-06-18 14:33:43 +02:00
|
|
|
}
|
|
|
|
|
2020-06-23 07:44:42 +02:00
|
|
|
/// Remove a user from a conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn remove_user_from_conversation(user_id: &UserID, conv: &Conversation, remover: &UserID) -> ResultBoxError<()> {
|
|
|
|
if conv.is_last_admin(user_id) {
|
|
|
|
delete_conversation(conv)
|
2020-06-23 07:44:42 +02:00
|
|
|
} else {
|
2021-03-04 18:51:52 +01:00
|
|
|
delete_member(user_id, conv.id, remover)
|
2020-06-23 07:44:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-23 08:03:30 +02:00
|
|
|
/// Remove permanently a conversation
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn delete_conversation(conv: &Conversation) -> ResultBoxError<()> {
|
2020-06-23 08:03:30 +02:00
|
|
|
// Delete all the messages of the conversations
|
2021-03-04 18:51:52 +01:00
|
|
|
for message in get_all_messages(conv.id)? {
|
2020-06-23 08:03:30 +02:00
|
|
|
delete_message(&message)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete all the members of the conversation
|
2021-03-02 17:32:24 +01:00
|
|
|
database::DeleteQuery::new(CONV_MEMBERS_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("conv_id", conv.id)
|
2020-06-23 08:03:30 +02:00
|
|
|
.exec()?;
|
|
|
|
|
2021-03-04 18:51:52 +01:00
|
|
|
// Delete associated background image, if any
|
|
|
|
if let Some(image) = &conv.background {
|
|
|
|
delete_user_data_file_if_exists(image)?;
|
|
|
|
}
|
|
|
|
|
2020-06-23 08:03:30 +02:00
|
|
|
// Delete the conversation entry itself
|
|
|
|
database::DeleteQuery::new(CONV_LIST_TABLE)
|
2021-03-04 18:51:52 +01:00
|
|
|
.cond_conv_id("id", conv.id)
|
2020-06-23 08:03:30 +02:00
|
|
|
.exec()?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-06-23 07:44:42 +02:00
|
|
|
/// Delete a conversation membership
|
2021-03-04 18:51:52 +01:00
|
|
|
pub fn delete_member(user_id: &UserID, conv_id: ConvID, _remover: &UserID) -> ResultBoxError<()> {
|
2020-06-23 07:44:42 +02:00
|
|
|
for msg in get_user_messages_for_conversations(conv_id, user_id)? {
|
|
|
|
delete_message(&msg)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete membership
|
|
|
|
remove_member(conv_id, user_id)?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-06-23 14:02:16 +02:00
|
|
|
/// Check out whether a user is the owner of a message or not
|
2020-06-25 10:08:34 +02:00
|
|
|
pub fn is_message_owner(user_id: &UserID, message_id: u64) -> ResultBoxError<bool> {
|
2020-06-23 14:02:16 +02:00
|
|
|
database::QueryInfo::new(CONV_MESSAGES_TABLE)
|
|
|
|
.cond_u64("id", message_id)
|
|
|
|
.cond_user_id("user_id", user_id)
|
|
|
|
.exec_count()
|
|
|
|
.map(|r| r > 0)
|
|
|
|
}
|
|
|
|
|
2020-06-04 19:01:35 +02:00
|
|
|
/// Turn a database entry into a ConversationInfo object
|
|
|
|
fn db_to_conversation_info(row: &database::RowResult) -> ResultBoxError<Conversation> {
|
2021-03-04 18:51:52 +01:00
|
|
|
let conv_id = row.get_conv_id("id")?;
|
2020-06-04 19:01:35 +02:00
|
|
|
Ok(Conversation {
|
|
|
|
id: conv_id,
|
2021-03-04 18:51:52 +01:00
|
|
|
color: row.get_optional_str("color")?,
|
|
|
|
background: row.get_optional_str("background")?,
|
2020-06-04 19:01:35 +02:00
|
|
|
name: row.get_optional_str("name")?,
|
|
|
|
members: get_list_members(conv_id)?,
|
|
|
|
can_everyone_add_members: row.get_legacy_bool("can_everyone_add_members")?,
|
2021-03-04 18:51:52 +01:00
|
|
|
last_activity: row.get_u64("last_activity")?,
|
|
|
|
creation_time: row.get_u64("creation_time")?,
|
|
|
|
group_id: row.get_optional_group_id("group_id")?,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Turn a database entry into a ConversationMember object
|
|
|
|
fn db_to_conversation_member(row: &database::RowResult) -> Res<ConversationMember> {
|
|
|
|
Ok(ConversationMember {
|
|
|
|
member_id: row.get_u64("id")?,
|
|
|
|
conv_id: row.get_conv_id("conv_id")?,
|
|
|
|
user_id: row.get_user_id("user_id")?,
|
|
|
|
added_on: row.get_u64("added_on")?,
|
2020-06-04 19:01:35 +02:00
|
|
|
following: row.get_legacy_bool("following")?,
|
2021-03-04 18:51:52 +01:00
|
|
|
is_admin: row.get_legacy_bool("is_admin")?,
|
|
|
|
last_message_seen: row.get_u64("last_message_seen")?,
|
2020-06-04 19:01:35 +02:00
|
|
|
})
|
2020-06-18 14:15:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Turn a database entry into a ConversationMessgae object
|
|
|
|
fn db_to_conversation_message(row: &database::RowResult) -> ResultBoxError<ConversationMessage> {
|
2021-03-02 18:57:34 +01:00
|
|
|
let user_id = match row.is_null("user_id")? {
|
|
|
|
true => None,
|
|
|
|
false => Some(row.get_user_id("user_id")?)
|
|
|
|
};
|
|
|
|
|
2021-03-04 18:51:52 +01:00
|
|
|
let file = match row.is_null_or_empty("file_path")? {
|
2021-03-02 18:57:34 +01:00
|
|
|
true => None,
|
|
|
|
false => Some(ConversationMessageFile {
|
2021-03-04 18:51:52 +01:00
|
|
|
path: row.get_str("file_path")?,
|
2021-03-02 18:57:34 +01:00
|
|
|
size: row.get_u64("file_size")?,
|
|
|
|
name: row.get_str("file_name")?,
|
|
|
|
thumbnail: row.get_optional_str("file_thumbnail")?,
|
|
|
|
r#type: row.get_str("file_type")?,
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
let server_message = match &user_id {
|
|
|
|
Some(_) => None,
|
|
|
|
None => Some(ConversationServerMessageType::from_db(&row.get_str("message")?)?)
|
|
|
|
};
|
|
|
|
|
|
|
|
let message = match server_message {
|
|
|
|
None => row.get_optional_str("message")?,
|
|
|
|
Some(_) => None,
|
|
|
|
};
|
|
|
|
|
2020-06-18 14:15:17 +02:00
|
|
|
Ok(ConversationMessage {
|
|
|
|
id: row.get_u64("id")?,
|
2021-03-02 18:57:34 +01:00
|
|
|
time_sent: row.get_u64("time_sent")?,
|
2021-03-04 18:51:52 +01:00
|
|
|
conv_id: row.get_conv_id("conv_id")?,
|
2021-03-02 18:57:34 +01:00
|
|
|
user_id,
|
|
|
|
message,
|
|
|
|
server_message,
|
|
|
|
file,
|
2020-06-18 14:15:17 +02:00
|
|
|
})
|
2020-06-04 13:36:57 +02:00
|
|
|
}
|