roomhistory: load old messages to history in batch

This improves the performence of old message loading. This passes all
messages from a batch directly to the room history. Also this way the
Internal AppOp loop isn't used and it makes sure that the lazy loading
queue runs only once.
This commit is contained in:
Julian Sparber 2018-11-23 11:28:56 +01:00
parent fc539a2ce8
commit 3d7182c531
4 changed files with 26 additions and 42 deletions

View file

@ -1,6 +1,5 @@
use app::App; use app::App;
use appop::MsgPos;
use appop::AppState; use appop::AppState;
use std::thread; use std::thread;
@ -16,12 +15,11 @@ use types::StickerGroup;
#[derive(Debug)] #[derive(Debug)]
pub enum InternalCommand { pub enum InternalCommand {
AddRoomMessage(Message, MsgPos), AddRoomMessage(Message),
SetView(AppState), SetView(AppState),
NotifyClicked(Message), NotifyClicked(Message),
SelectRoom(Room), SelectRoom(Room),
LoadMore, LoadMore,
LoadMoreNormal,
RemoveInv(String), RemoveInv(String),
AppendTmpMessages, AppendTmpMessages,
ForceDequeueMessage, ForceDequeueMessage,
@ -41,8 +39,8 @@ pub fn appop_loop(rx: Receiver<InternalCommand>) {
loop { loop {
let recv = rx.recv(); let recv = rx.recv();
match recv { match recv {
Ok(InternalCommand::AddRoomMessage(msg, pos)) => { Ok(InternalCommand::AddRoomMessage(msg)) => {
APPOP!(add_room_message, (msg, pos)); APPOP!(add_room_message, (msg));
} }
Ok(InternalCommand::ToInvite(member)) => { Ok(InternalCommand::ToInvite(member)) => {
APPOP!(add_to_invite, (member)); APPOP!(add_to_invite, (member));
@ -63,9 +61,6 @@ pub fn appop_loop(rx: Receiver<InternalCommand>) {
Ok(InternalCommand::LoadMore) => { Ok(InternalCommand::LoadMore) => {
APPOP!(load_more_messages); APPOP!(load_more_messages);
} }
Ok(InternalCommand::LoadMoreNormal) => {
APPOP!(load_more_normal);
}
Ok(InternalCommand::RemoveInv(rid)) => { Ok(InternalCommand::RemoveInv(rid)) => {
APPOP!(remove_inv, (rid)); APPOP!(remove_inv, (rid));
} }

View file

@ -22,12 +22,6 @@ use types::Message;
use serde_json::Value as JsonValue; use serde_json::Value as JsonValue;
use gdk_pixbuf::Pixbuf; use gdk_pixbuf::Pixbuf;
#[derive(Debug, Clone)]
pub enum MsgPos {
Top,
Bottom,
}
pub struct TmpMsg { pub struct TmpMsg {
pub msg: Message, pub msg: Message,
pub widget: Option<gtk::Widget>, pub widget: Option<gtk::Widget>,
@ -54,21 +48,11 @@ impl AppOp {
} }
} }
pub fn add_room_message(&mut self, pub fn add_room_message(&mut self, msg: Message) {
msg: Message,
msgpos: MsgPos) {
if msg.room == self.active_room.clone().unwrap_or_default() && !msg.redacted { if msg.room == self.active_room.clone().unwrap_or_default() && !msg.redacted {
if let Some(ui_msg) = self.create_new_room_message(&msg) { if let Some(ui_msg) = self.create_new_room_message(&msg) {
if let Some(ref mut history) = self.history { if let Some(ref mut history) = self.history {
match msgpos { history.add_new_message(ui_msg);
MsgPos::Bottom => {
history.add_new_message(ui_msg);
},
MsgPos::Top => {
history.add_old_message(ui_msg);
}
}
} }
} }
} }
@ -433,7 +417,7 @@ impl AppOp {
self.notify(msg); self.notify(msg);
} }
let command = InternalCommand::AddRoomMessage(msg.clone(), MsgPos::Bottom); let command = InternalCommand::AddRoomMessage(msg.clone());
self.internal.send(command).unwrap(); self.internal.send(command).unwrap();
self.roomlist.moveup(msg.room.clone()); self.roomlist.moveup(msg.room.clone());
@ -451,6 +435,7 @@ impl AppOp {
Some(()) Some(())
} }
/* TODO: find a better name for this function */
pub fn show_room_messages_top(&mut self, msgs: Vec<Message>, roomid: String, prev_batch: Option<String>) { pub fn show_room_messages_top(&mut self, msgs: Vec<Message>, roomid: String, prev_batch: Option<String>) {
if let Some(r) = self.rooms.get_mut(&roomid) { if let Some(r) = self.rooms.get_mut(&roomid) {
r.prev_batch = prev_batch; r.prev_batch = prev_batch;
@ -461,21 +446,26 @@ impl AppOp {
return; return;
} }
for msg in msgs.iter().rev() { let active_room = self.active_room.clone().unwrap_or_default();
if let Some(r) = self.rooms.get_mut(&msg.room) { let mut list = vec![];
r.messages.insert(0, msg.clone()); for item in msgs.iter().rev() {
/* create a list of new messages to load to the history */
if item.room == active_room && !item.redacted {
if let Some(ui_msg) = self.create_new_room_message(item) {
list.push(ui_msg);
}
}
if let Some(r) = self.rooms.get_mut(&item.room) {
r.messages.insert(0, item.clone());
} }
} }
let size = msgs.len() - 1; if let Some(ref mut history) = self.history {
for i in 0..size+1 { history.add_old_messages_in_batch(list);
let msg = &msgs[size - i];
let command = InternalCommand::AddRoomMessage(msg.clone(), MsgPos::Top);
self.internal.send(command).unwrap();
} }
self.internal.send(InternalCommand::LoadMoreNormal).unwrap();
self.load_more_normal();
} }
/* parese a backend Message into a Message for the UI */ /* parese a backend Message into a Message for the UI */

View file

@ -44,7 +44,6 @@ mod stickers;
pub use self::state::AppState; pub use self::state::AppState;
use self::message::TmpMsg; use self::message::TmpMsg;
pub use self::message::MsgPos;
pub use self::room::RoomPanel; pub use self::room::RoomPanel;
use self::member::SearchType; use self::member::SearchType;

View file

@ -270,9 +270,9 @@ impl RoomHistory {
None None
} }
/* This adds messages to the top of the list */ pub fn add_old_messages_in_batch(&mut self, messages: Vec<MessageContent>) -> Option<()> {
pub fn add_old_message(&mut self, item: MessageContent) -> Option<()> { /* TODO: Try if extend would be faster then append */
self.queue.borrow_mut().push_back(item); self.queue.borrow_mut().append(&mut VecDeque::from(messages));
self.run_queue(); self.run_queue();
None None