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;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::MessageGet) {
|
||||
self.send_message(&message_handlers::handle_message_get(&cv))
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::GetChats) {
|
||||
self.send_message(&message_handlers::handle_get_chats(&cv))
|
||||
.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,
|
||||
storage_owner: i64,
|
||||
partner_id: i64,
|
||||
) -> DataValue {
|
||||
) -> Vec<(DataType, DataValue)> {
|
||||
let mut fields = vec![
|
||||
(
|
||||
DataType::MessageId,
|
||||
|
|
@ -162,7 +162,15 @@ fn stored_message_value(
|
|||
.collect();
|
||||
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 {
|
||||
|
|
@ -520,6 +528,28 @@ pub fn handle_messages_get(cv: &CommunicationValue) -> CommunicationValue {
|
|||
.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 {
|
||||
let user_id = cv.get_sender();
|
||||
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> {
|
||||
if ids.is_empty() {
|
||||
return Vec::new();
|
||||
|
|
|
|||
|
|
@ -30,5 +30,5 @@ serde = "1.0.228"
|
|||
tempfile = "3.27.0"
|
||||
anyhow = "1.0.102"
|
||||
semver = "1.0.28"
|
||||
ed25519-dalek = "2.2.0"
|
||||
ed25519-dalek = "3.0.0"
|
||||
serde_json = "1.0"
|
||||
|
|
|
|||
|
|
@ -884,6 +884,7 @@ impl OmikronConnection {
|
|||
dispatch!(MessageReactionLive, handle_message_reaction_live);
|
||||
dispatch!(MessageDeleteLive, handle_message_delete_live);
|
||||
dispatch!(MessageOtherIota, handle_message_other_iota);
|
||||
dispatch!(MessageGet, handle_message_get);
|
||||
dispatch!(MessagesGet, handle_messages_get);
|
||||
dispatch!(GetChats, handle_get_chats);
|
||||
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 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();
|
||||
|
||||
if is_local {
|
||||
|
|
@ -1701,6 +1720,12 @@ impl OmikronConnection {
|
|||
.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) {
|
||||
let _ = self
|
||||
.send_message(&message_handlers::handle_get_chats(cv))
|
||||
|
|
|
|||
Loading…
Reference in a new issue