Better messages loading
This commit is contained in:
parent
1c584112b3
commit
8adcef8852
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user