Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ce93a30ae | |||
|
326ebf3b37 |
6 changed files with 292 additions and 199 deletions
366
Cargo.lock
generated
366
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -407,6 +407,12 @@ impl ClientConnection {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cv.is_type(CommunicationType::MessageGet) {
|
||||||
|
self.send_message(&message_handlers::handle_message_get(&cv))
|
||||||
|
.await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if cv.is_type(CommunicationType::GetChats) {
|
if cv.is_type(CommunicationType::GetChats) {
|
||||||
self.send_message(&message_handlers::handle_get_chats(&cv))
|
self.send_message(&message_handlers::handle_get_chats(&cv))
|
||||||
.await;
|
.await;
|
||||||
|
|
|
||||||
|
|
@ -102,11 +102,11 @@ pub fn handle_message_delete(cv: &CommunicationValue) -> CommunicationValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stored_message_value(
|
fn stored_message_fields(
|
||||||
message: &chat_files::StoredMessage,
|
message: &chat_files::StoredMessage,
|
||||||
storage_owner: i64,
|
storage_owner: i64,
|
||||||
partner_id: i64,
|
partner_id: i64,
|
||||||
) -> DataValue {
|
) -> Vec<(DataType, DataValue)> {
|
||||||
let mut fields = vec![
|
let mut fields = vec![
|
||||||
(
|
(
|
||||||
DataType::MessageId,
|
DataType::MessageId,
|
||||||
|
|
@ -162,7 +162,15 @@ fn stored_message_value(
|
||||||
.collect();
|
.collect();
|
||||||
fields.push((DataType::Reactions, DataValue::Array(reactions)));
|
fields.push((DataType::Reactions, DataValue::Array(reactions)));
|
||||||
}
|
}
|
||||||
typed_container(fields)
|
fields
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stored_message_value(
|
||||||
|
message: &chat_files::StoredMessage,
|
||||||
|
storage_owner: i64,
|
||||||
|
partner_id: i64,
|
||||||
|
) -> DataValue {
|
||||||
|
typed_container(stored_message_fields(message, storage_owner, partner_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_get_chat_secret(cv: &CommunicationValue) -> CommunicationValue {
|
pub fn handle_get_chat_secret(cv: &CommunicationValue) -> CommunicationValue {
|
||||||
|
|
@ -520,6 +528,28 @@ pub fn handle_messages_get(cv: &CommunicationValue) -> CommunicationValue {
|
||||||
.add_typed_default(DataType::Messages, DataValue::Array(msg_array))
|
.add_typed_default(DataType::Messages, DataValue::Array(msg_array))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_message_get(cv: &CommunicationValue) -> CommunicationValue {
|
||||||
|
let Some(send_time) = data_i64(cv, DataType::SendTime) else {
|
||||||
|
return error_response(cv, CommunicationType::ErrorInvalidData);
|
||||||
|
};
|
||||||
|
let partner_id = data_i64(cv, DataType::ChatPartnerId);
|
||||||
|
let owner = cv.get_sender() as i64;
|
||||||
|
|
||||||
|
let message = match chat_files::get_message(owner, send_time, partner_id) {
|
||||||
|
Ok(Some(message)) => message,
|
||||||
|
Ok(None) => return error_response(cv, CommunicationType::ErrorNotFound),
|
||||||
|
Err(_) => return error_response(cv, CommunicationType::ErrorInvalidData),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut response = CommunicationValue::new(CommunicationType::MessageGet)
|
||||||
|
.with_id(cv.get_id())
|
||||||
|
.with_receiver(cv.get_sender());
|
||||||
|
for (data_type, value) in stored_message_fields(&message, owner, message.external_user) {
|
||||||
|
response = response.add_typed_default(data_type, value);
|
||||||
|
}
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_get_chats(cv: &CommunicationValue) -> CommunicationValue {
|
pub fn handle_get_chats(cv: &CommunicationValue) -> CommunicationValue {
|
||||||
let user_id = cv.get_sender();
|
let user_id = cv.get_sender();
|
||||||
let users = chats_util::get_users(user_id as i64);
|
let users = chats_util::get_users(user_id as i64);
|
||||||
|
|
|
||||||
|
|
@ -644,6 +644,62 @@ pub fn get_messages(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_message(
|
||||||
|
storage_owner: i64,
|
||||||
|
message_time: i64,
|
||||||
|
external_user: Option<i64>,
|
||||||
|
) -> Result<Option<StoredMessage>, StorageError> {
|
||||||
|
db::with_db(|conn| {
|
||||||
|
let mut stmt = conn.prepare(
|
||||||
|
r#"
|
||||||
|
SELECT id, message_time, content, sent_by_self, message_state, height,
|
||||||
|
reply_to, edited_count, external_user
|
||||||
|
FROM messages
|
||||||
|
WHERE storage_owner = ?1
|
||||||
|
AND message_time = ?2
|
||||||
|
AND deleted_by_external = 0
|
||||||
|
AND (?3 IS NULL OR external_user = ?3)
|
||||||
|
ORDER BY id DESC
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let rows = stmt.query_map(params![storage_owner, message_time, external_user], |row| {
|
||||||
|
Ok(StoredMessage {
|
||||||
|
id: row.get(0)?,
|
||||||
|
message_time: row.get(1)?,
|
||||||
|
content: row.get(2)?,
|
||||||
|
sent_by_self: row.get::<_, i64>(3)? != 0,
|
||||||
|
message_state: row.get(4)?,
|
||||||
|
height: row.get(5).unwrap_or(0),
|
||||||
|
reply_to: row.get(6).ok().flatten(),
|
||||||
|
edited: row.get::<_, i64>(7).unwrap_or(0) > 0,
|
||||||
|
external_user: row.get(8)?,
|
||||||
|
reactions: Vec::new(),
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let messages: Vec<StoredMessage> = rows.collect::<Result<_, _>>()?;
|
||||||
|
if messages.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
if external_user.is_none()
|
||||||
|
&& messages
|
||||||
|
.iter()
|
||||||
|
.map(|message| message.external_user)
|
||||||
|
.collect::<std::collections::HashSet<_>>()
|
||||||
|
.len()
|
||||||
|
> 1
|
||||||
|
{
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut message = messages.into_iter().next().expect("checked non-empty");
|
||||||
|
let reaction_map = load_reactions(conn, &[message.id]);
|
||||||
|
message.reactions = reaction_map.get(&message.id).cloned().unwrap_or_default();
|
||||||
|
Ok(Some(message))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_messages_by_ids(storage_owner: i64, ids: &[i64]) -> Vec<StoredMessage> {
|
pub fn get_messages_by_ids(storage_owner: i64, ids: &[i64]) -> Vec<StoredMessage> {
|
||||||
if ids.is_empty() {
|
if ids.is_empty() {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
|
|
|
||||||
|
|
@ -30,5 +30,5 @@ serde = "1.0.228"
|
||||||
tempfile = "3.27.0"
|
tempfile = "3.27.0"
|
||||||
anyhow = "1.0.102"
|
anyhow = "1.0.102"
|
||||||
semver = "1.0.28"
|
semver = "1.0.28"
|
||||||
ed25519-dalek = "2.2.0"
|
ed25519-dalek = "3.0.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
|
||||||
|
|
@ -884,6 +884,7 @@ impl OmikronConnection {
|
||||||
dispatch!(MessageReactionLive, handle_message_reaction_live);
|
dispatch!(MessageReactionLive, handle_message_reaction_live);
|
||||||
dispatch!(MessageDeleteLive, handle_message_delete_live);
|
dispatch!(MessageDeleteLive, handle_message_delete_live);
|
||||||
dispatch!(MessageOtherIota, handle_message_other_iota);
|
dispatch!(MessageOtherIota, handle_message_other_iota);
|
||||||
|
dispatch!(MessageGet, handle_message_get);
|
||||||
dispatch!(MessagesGet, handle_messages_get);
|
dispatch!(MessagesGet, handle_messages_get);
|
||||||
dispatch!(GetChats, handle_get_chats);
|
dispatch!(GetChats, handle_get_chats);
|
||||||
dispatch!(AddConversation, handle_add_conversation);
|
dispatch!(AddConversation, handle_add_conversation);
|
||||||
|
|
@ -1447,6 +1448,24 @@ impl OmikronConnection {
|
||||||
let height = cv.get_data(DataType::Height).as_number().unwrap_or(0) as i64;
|
let height = cv.get_data(DataType::Height).as_number().unwrap_or(0) as i64;
|
||||||
let reply_to = cv.get_data(DataType::ReplyId).as_number().map(|n| n as i64);
|
let reply_to = cv.get_data(DataType::ReplyId).as_number().map(|n| n as i64);
|
||||||
|
|
||||||
|
if let Some(reply_to) = reply_to {
|
||||||
|
match chat_files::get_message(sender_id as i64, reply_to, Some(receiver_id)) {
|
||||||
|
Ok(Some(_)) => {}
|
||||||
|
Ok(None) => {
|
||||||
|
let _ = self
|
||||||
|
.send_message(&error_response(cv, CommunicationType::ErrorNotFound))
|
||||||
|
.await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
let _ = self
|
||||||
|
.send_message(&error_response(cv, CommunicationType::ErrorInvalidData))
|
||||||
|
.await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let is_local = iota_storage::users::user_manager::get_user(receiver_id).is_some();
|
let is_local = iota_storage::users::user_manager::get_user(receiver_id).is_some();
|
||||||
|
|
||||||
if is_local {
|
if is_local {
|
||||||
|
|
@ -1701,6 +1720,12 @@ impl OmikronConnection {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_message_get(self: Arc<Self>, cv: &CommunicationValue) {
|
||||||
|
let _ = self
|
||||||
|
.send_message(&message_handlers::handle_message_get(cv))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_get_chats(self: Arc<Self>, cv: &CommunicationValue) {
|
async fn handle_get_chats(self: Arc<Self>, cv: &CommunicationValue) {
|
||||||
let _ = self
|
let _ = self
|
||||||
.send_message(&message_handlers::handle_get_chats(cv))
|
.send_message(&message_handlers::handle_get_chats(cv))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue