Better messages loading

This commit is contained in:
Matéo Duparc 2021-05-14 15:14:40 +02:00
parent 1c584112b3
commit 8adcef8852
Signed by: hardcoresushi
GPG Key ID: 007F84120107191E
5 changed files with 110 additions and 93 deletions

View File

@ -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<sessionIds.length; ++i) {
sessionsData.get(sessionIds[i]).seen = false;
}
displaySessions();
}
function setLocalIps(str_ips) {
localIps = str_ips.split(' ');
function setLocalIps(strIPs) {
localIps = strIPs.split(' ');
}
function onIsContact(sessionId, verified, fingerprint, name) {
if (sessionsData.has(sessionId)) {
@ -679,16 +676,32 @@ function onIncFilesTransfer(sessionId, chunkSize) {
}
}
}
function onMsgLoad(sessionId, outgoing, msg) {
msgHistory.get(sessionId).unshift([outgoing, false, msg]);
if (currentSessionId == sessionId) {
displayHistory(false);
function onMsgsLoad(sessionId, strMsgs) {
let msgs = strMsgs.split(' ');
let n = 0;
while (n < msgs.length) {
let outgoing = msgs[n+1] === "true";
switch (msgs[n]) {
case 'm':
let msg = b64DecodeUnicode(msgs[n+2]);
msgHistory.get(sessionId).unshift([outgoing, false, msg]);
n += 3;
break;
case 'f':
let uuid = msgs[n+2];
let fileName = b64DecodeUnicode(msgs[n+3]);
msgHistory.get(sessionId).unshift([outgoing, true, [uuid, fileName]]);
n += 4;
}
}
}
function onFileLoad(sessionId, outgoing, uuid, fileName) {
msgHistory.get(sessionId).unshift([outgoing, true, [uuid, fileName]]);
if (currentSessionId == sessionId) {
displayHistory(false);
if (msg_log.scrollHeight - msg_log.scrollTop === msg_log.clientHeight) {
displayHistory();
} else {
let backupHeight = msg_log.scrollHeight;
displayHistory(false);
msg_log.scrollTop = msg_log.scrollHeight-backupHeight;
}
}
}
function onDisconnected(sessionId) {
@ -1078,4 +1091,7 @@ function displayHistory(scrollToBottom = true) {
if (scrollToBottom) {
msg_log.scrollTop = msg_log.scrollHeight;
}
if (msg_log.scrollHeight <= msg_log.clientHeight) {
socket.send("load_msgs "+currentSessionId);
}
}

View File

@ -251,56 +251,57 @@ impl Identity {
match db.prepare(&format!("SELECT count(*) FROM \"{}\"", contact_uuid)) {
Ok(mut stmt) => {
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<u8> = 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<u8> = 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<u8> = 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<u8> = 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) => {

View File

@ -114,7 +114,9 @@ async fn websocket_worker(mut ui_connection: UiConnection, global_vars: Arc<RwLo
}
}
session_manager.get_saved_msgs().into_iter().for_each(|msgs| {
ui_connection.load_msgs(&msgs.0, &msgs.1);
if msgs.1.len() > 0 {
ui_connection.load_msgs(&msgs.0, &msgs.1);
}
});
let mut ips = Vec::new();
match if_addrs::get_if_addrs() {

View File

@ -102,10 +102,11 @@ impl SessionManager {
pub fn store_msg(&self, session_id: &usize, outgoing: bool, buffer: Vec<u8>) {
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<Vec<(bool, Vec<u8>)>> {
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
}

View File

@ -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<Message> {
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<Message> {
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<Message> {
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<u8>)>) -> 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<usize>) -> 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<u8>)>) {
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<usize>) {
self.write_message(ui_messages::set_not_seen(session_ids));