diff --git a/src/frontend/index.js b/src/frontend/index.js index 4be2ab3..4b1a010 100644 --- a/src/frontend/index.js +++ b/src/frontend/index.js @@ -454,11 +454,8 @@ socket.onmessage = function(msg) { case "inc_file_transfer": onIncFilesTransfer(args[1], parseInt(args[2])); break; - case "load_sent_msg": - onMsgLoad(args[1], args[2] === "true", msg.data.slice(args[0].length+args[1].length+args[2].length+3)); - break; - case "load_sent_file": - onFileLoad(args[1], args[2] === "true", args[3], msg.data.slice(args[0].length+args[1].length+args[2].length+args[3].length+4)); + case "load_msgs": + onMsgsLoad(args[1], msg.data.slice(args[0].length+args[1].length+2)); break; case "name_told": onNameTold(args[1], msg.data.slice(args[0].length+args[1].length+2)); @@ -512,15 +509,15 @@ function onNameTold(sessionId, name) { } displaySessions(); } -function setNotSeen(str_sessionIds) { - let sessionIds = str_sessionIds.split(' '); +function setNotSeen(strSessionIds) { + let sessionIds = strSessionIds.split(' '); for (let i=0; i { let mut rows = stmt.query([]).unwrap(); - let row = rows.next().unwrap(); - if row.is_some() { - let total: usize = row.unwrap().get(0).unwrap(); - if offset >= total { - print_error!("Offset larger than total numbers of rows"); - None - } else { - if offset+count >= total { - count = total-offset; - } - match db.prepare(&format!("SELECT outgoing, data FROM \"{}\" LIMIT {} OFFSET {}", contact_uuid, count, total-offset-count)) { - Ok(mut stmt) => { - let mut rows = stmt.query([]).unwrap(); - let mut msgs = Vec::new(); - while let Some(row) = rows.next().unwrap() { - let encrypted_outgoing: Vec = row.get(0).unwrap(); - match crypto::decrypt_data(encrypted_outgoing.as_slice(), &self.master_key){ - Ok(outgoing) => { - match byte_to_bool(outgoing[0]) { - Ok(outgoing) => { - let encrypted_data: Vec = row.get(1).unwrap(); - match crypto::decrypt_data(encrypted_data.as_slice(), &self.master_key) { - Ok(data) => { - msgs.push( - ( - outgoing, - data + match rows.next() { + Ok(row) => if row.is_some() { + let total: usize = row.unwrap().get(0).unwrap(); + if offset >= total { + None + } else { + if offset+count >= total { + count = total-offset; + } + match db.prepare(&format!("SELECT outgoing, data FROM \"{}\" LIMIT {} OFFSET {}", contact_uuid, count, total-offset-count)) { + Ok(mut stmt) => { + let mut rows = stmt.query([]).unwrap(); + let mut msgs = Vec::new(); + while let Some(row) = rows.next().unwrap() { + let encrypted_outgoing: Vec = row.get(0).unwrap(); + match crypto::decrypt_data(encrypted_outgoing.as_slice(), &self.master_key){ + Ok(outgoing) => { + match byte_to_bool(outgoing[0]) { + Ok(outgoing) => { + let encrypted_data: Vec = row.get(1).unwrap(); + match crypto::decrypt_data(encrypted_data.as_slice(), &self.master_key) { + Ok(data) => { + msgs.push( + ( + outgoing, + data + ) ) - ) - }, - Err(e) => print_error!(e) + }, + Err(e) => print_error!(e) + } } + Err(_) => {} } - Err(_) => {} + } - + Err(e) => print_error!(e) } - Err(e) => print_error!(e) } + Some(msgs) + } + Err(e) => { + print_error!(e); + None } - Some(msgs) - } - Err(e) => { - print_error!(e); - None } } + } else { + None } - } else { - None + Err(_) => None } } Err(e) => { diff --git a/src/main.rs b/src/main.rs index eccec77..a8d74ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -114,7 +114,9 @@ async fn websocket_worker(mut ui_connection: UiConnection, global_vars: Arc 0 { + ui_connection.load_msgs(&msgs.0, &msgs.1); + } }); let mut ips = Vec::new(); match if_addrs::get_if_addrs() { diff --git a/src/session_manager/mod.rs b/src/session_manager/mod.rs index ee1a676..731e8cf 100644 --- a/src/session_manager/mod.rs +++ b/src/session_manager/mod.rs @@ -102,10 +102,11 @@ impl SessionManager { pub fn store_msg(&self, session_id: &usize, outgoing: bool, buffer: Vec) { let mut msg_saved = false; if self.is_contact(session_id) { + let mut offsets = self.last_loaded_msg_offsets.write().unwrap(); //locking mutex before modifying the DB to prevent race conditions match self.identity.read().unwrap().as_ref().unwrap().store_msg(&self.loaded_contacts.read().unwrap().get(session_id).unwrap().uuid, outgoing, &buffer) { Ok(_) => { + *offsets.get_mut(session_id).unwrap() += 1; msg_saved = true; - *self.last_loaded_msg_offsets.write().unwrap().get_mut(session_id).unwrap() += 1; }, Err(e) => print_error!(e), } @@ -634,9 +635,13 @@ impl SessionManager { pub fn load_msgs(&self, session_id: &usize, count: usize) -> Option)>> { let mut offsets = self.last_loaded_msg_offsets.write().unwrap(); - let msgs = self.identity.read().unwrap().as_ref().unwrap().load_msgs(&self.loaded_contacts.read().unwrap().get(session_id).unwrap().uuid, *offsets.get(session_id).unwrap(), count); - if msgs.is_some() { - *offsets.get_mut(session_id).unwrap() += msgs.as_ref().unwrap().len(); + let msgs = self.identity.read().unwrap().as_ref().unwrap().load_msgs( + &self.loaded_contacts.read().unwrap().get(session_id).unwrap().uuid, + *offsets.get(session_id).unwrap(), + count + ); + if let Some(msgs) = msgs.as_ref() { + *offsets.get_mut(session_id).unwrap() += msgs.len(); } msgs } diff --git a/src/ui_interface.rs b/src/ui_interface.rs index eba2ea2..984990e 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -8,18 +8,6 @@ mod ui_messages { use uuid::Uuid; use crate::{print_error, session_manager::{LargeFileDownload, LargeFilesDownload, protocol}, utils::to_uuid_bytes}; - const ON_NEW_MESSAGE: &str = "new_message"; - const LOAD_SENT_MESSAGE: &str = "load_sent_msg"; - - fn new_message(command: &str, session_id: &usize, outgoing: bool, raw_message: &[u8]) -> Option { - match from_utf8(raw_message) { - Ok(msg) => Some(Message::from(format!("{} {} {} {}", command, session_id, outgoing, msg))), - Err(e) => { - print_error!(e); - None - } - } - } fn simple_event(command: &str, session_id: &usize) -> Message { Message::from(format!("{} {}", command, session_id)) } @@ -84,26 +72,36 @@ mod ui_messages { simple_event("aborted", session_id) } pub fn on_new_message(session_id: &usize, outgoing: bool, buffer: &[u8]) -> Option { - new_message(ON_NEW_MESSAGE, session_id, outgoing, &buffer[1..]) + match from_utf8(&buffer[1..]) { + Ok(msg) => Some(Message::from(format!("{} {} {} {}", "new_message", session_id, outgoing, msg))), + Err(e) => { + print_error!(e); + None + } + } } pub fn inc_files_transfer(session_id: &usize, chunk_size: u64) -> Message { Message::from(format!("inc_file_transfer {} {}", session_id, chunk_size)) } - pub fn load_msg(session_id: &usize, outgoing: bool, buffer: &[u8]) -> Option { - match buffer[0] { - protocol::Headers::MESSAGE => new_message(LOAD_SENT_MESSAGE, session_id, outgoing, &buffer[1..]), - protocol::Headers::FILE => { - let uuid = Uuid::from_bytes(to_uuid_bytes(&buffer[1..17])?); - match from_utf8(&buffer[17..]) { - Ok(file_name) => Some(Message::from(format!("load_sent_file {} {} {} {}", session_id, outgoing, uuid.to_string(), file_name))), - Err(e) => { - print_error!(e); - None + pub fn load_msgs(session_id: &usize, msgs: &Vec<(bool, Vec)>) -> Message { + let mut s = format!("load_msgs {}", session_id); + msgs.into_iter().rev().for_each(|entry| { + match entry.1[0] { + protocol::Headers::MESSAGE => match from_utf8(&entry.1[1..]) { + Ok(msg) => s.push_str(&format!(" m {} {}", entry.0, base64::encode(msg))), + Err(e) => print_error!(e) + } + protocol::Headers::FILE => { + let uuid = Uuid::from_bytes(to_uuid_bytes(&entry.1[1..17]).unwrap()); + match from_utf8(&entry.1[17..]) { + Ok(file_name) => s.push_str(&format!(" f {} {} {}", entry.0, uuid.to_string(), base64::encode(file_name))), + Err(e) => print_error!(e) } } + _ => {} } - _ => None - } + }); + Message::from(s) } pub fn set_not_seen(session_ids: Vec) -> Message { data_list("not_seen", session_ids) @@ -189,12 +187,7 @@ impl UiConnection { self.write_message(ui_messages::set_as_contact(session_id, name, verified, fingerprint)); } pub fn load_msgs(&mut self, session_id: &usize, msgs: &Vec<(bool, Vec)>) { - msgs.into_iter().rev().for_each(|msg| { - match ui_messages::load_msg(session_id, msg.0, &msg.1) { - Some(msg) => self.write_message(msg), - None => {} - } - }) + self.write_message(ui_messages::load_msgs(session_id, msgs)); } pub fn set_not_seen(&mut self, session_ids: Vec) { self.write_message(ui_messages::set_not_seen(session_ids));