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

View File

@ -251,11 +251,10 @@ impl Identity {
match db.prepare(&format!("SELECT count(*) FROM \"{}\"", contact_uuid)) { match db.prepare(&format!("SELECT count(*) FROM \"{}\"", contact_uuid)) {
Ok(mut stmt) => { Ok(mut stmt) => {
let mut rows = stmt.query([]).unwrap(); let mut rows = stmt.query([]).unwrap();
let row = rows.next().unwrap(); match rows.next() {
if row.is_some() { Ok(row) => if row.is_some() {
let total: usize = row.unwrap().get(0).unwrap(); let total: usize = row.unwrap().get(0).unwrap();
if offset >= total { if offset >= total {
print_error!("Offset larger than total numbers of rows");
None None
} else { } else {
if offset+count >= total { if offset+count >= total {
@ -302,6 +301,8 @@ impl Identity {
} else { } else {
None None
} }
Err(_) => None
}
} }
Err(e) => { Err(e) => {
print_error!(e); print_error!(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| { session_manager.get_saved_msgs().into_iter().for_each(|msgs| {
if msgs.1.len() > 0 {
ui_connection.load_msgs(&msgs.0, &msgs.1); ui_connection.load_msgs(&msgs.0, &msgs.1);
}
}); });
let mut ips = Vec::new(); let mut ips = Vec::new();
match if_addrs::get_if_addrs() { 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>) { pub fn store_msg(&self, session_id: &usize, outgoing: bool, buffer: Vec<u8>) {
let mut msg_saved = false; let mut msg_saved = false;
if self.is_contact(session_id) { 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) { match self.identity.read().unwrap().as_ref().unwrap().store_msg(&self.loaded_contacts.read().unwrap().get(session_id).unwrap().uuid, outgoing, &buffer) {
Ok(_) => { Ok(_) => {
*offsets.get_mut(session_id).unwrap() += 1;
msg_saved = true; msg_saved = true;
*self.last_loaded_msg_offsets.write().unwrap().get_mut(session_id).unwrap() += 1;
}, },
Err(e) => print_error!(e), 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>)>> { 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 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); let msgs = self.identity.read().unwrap().as_ref().unwrap().load_msgs(
if msgs.is_some() { &self.loaded_contacts.read().unwrap().get(session_id).unwrap().uuid,
*offsets.get_mut(session_id).unwrap() += msgs.as_ref().unwrap().len(); *offsets.get(session_id).unwrap(),
count
);
if let Some(msgs) = msgs.as_ref() {
*offsets.get_mut(session_id).unwrap() += msgs.len();
} }
msgs msgs
} }

View File

@ -8,18 +8,6 @@ mod ui_messages {
use uuid::Uuid; use uuid::Uuid;
use crate::{print_error, session_manager::{LargeFileDownload, LargeFilesDownload, protocol}, utils::to_uuid_bytes}; 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 { fn simple_event(command: &str, session_id: &usize) -> Message {
Message::from(format!("{} {}", command, session_id)) Message::from(format!("{} {}", command, session_id))
} }
@ -84,26 +72,36 @@ mod ui_messages {
simple_event("aborted", session_id) simple_event("aborted", session_id)
} }
pub fn on_new_message(session_id: &usize, outgoing: bool, buffer: &[u8]) -> Option<Message> { 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))),
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) => { Err(e) => {
print_error!(e); print_error!(e);
None None
} }
} }
} }
_ => 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_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)
}
}
_ => {}
}
});
Message::from(s)
} }
pub fn set_not_seen(session_ids: Vec<usize>) -> Message { pub fn set_not_seen(session_ids: Vec<usize>) -> Message {
data_list("not_seen", session_ids) 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)); 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>)>) { pub fn load_msgs(&mut self, session_id: &usize, msgs: &Vec<(bool, Vec<u8>)>) {
msgs.into_iter().rev().for_each(|msg| { self.write_message(ui_messages::load_msgs(session_id, msgs));
match ui_messages::load_msg(session_id, msg.0, &msg.1) {
Some(msg) => self.write_message(msg),
None => {}
}
})
} }
pub fn set_not_seen(&mut self, session_ids: Vec<usize>) { pub fn set_not_seen(&mut self, session_ids: Vec<usize>) {
self.write_message(ui_messages::set_not_seen(session_ids)); self.write_message(ui_messages::set_not_seen(session_ids));