diff --git a/Cargo.lock b/Cargo.lock
index 8b51fa7..8f9c6fa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2108,7 +2108,7 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "presage"
version = "0.3.0"
-source = "git+https://github.com/Schmiddiii/presage?rev=0abbb46a92ec8f186ca43339cb109ad9132a02ed#0abbb46a92ec8f186ca43339cb109ad9132a02ed"
+source = "git+https://github.com/Schmiddiii/presage?rev=2ccbdb3fb14623625be9b51c76a8a0993203d535#2ccbdb3fb14623625be9b51c76a8a0993203d535"
dependencies = [
"async-trait",
"base64 0.12.3",
diff --git a/Cargo.toml b/Cargo.toml
index c5a30f5..b537961 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,7 +18,7 @@ futures = "0.3.24"
tokio = { version = "1.20.1", features = ["rt", "macros", "rt-multi-thread", "time"] }
async-recursion = "1.0.0"
-presage = { git = "https://github.com/Schmiddiii/presage", rev = "0abbb46a92ec8f186ca43339cb109ad9132a02ed" }
+presage = { git = "https://github.com/Schmiddiii/presage", rev = "2ccbdb3fb14623625be9b51c76a8a0993203d535" }
libsignal-service = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "f9b54478c5413252e810089fd9648b6351bcc3bf" }
async-trait = "0.1.57"
diff --git a/data/resources/ui/window.ui b/data/resources/ui/window.ui
index 3594a07..dc8c01f 100644
--- a/data/resources/ui/window.ui
+++ b/data/resources/ui/window.ui
@@ -125,6 +125,10 @@
Unlink
win.unlink
+ -
+ Clear messages
+ win.clear-messages
+
-
Keybindings
win.show-help-overlay
diff --git a/src/backend/channel.rs b/src/backend/channel.rs
index 85d61eb..d1739a9 100644
--- a/src/backend/channel.rs
+++ b/src/backend/channel.rs
@@ -9,7 +9,7 @@ use gio::subclass::prelude::ObjectSubclassIsExt;
use libsignal_service::{groups_v2::Group, prelude::Uuid, proto::DataMessage};
use presage::{
prelude::{GroupContextV2, GroupMasterKey, ServiceAddress},
- MessageIdentity,
+ MessageIdentity, Thread,
};
use super::{Contact, Manager, Message};
@@ -48,20 +48,9 @@ impl Channel {
if let Ok(group) = group {
return Self::from_group(group, group_context_v2, manager).await;
} else {
- if let Some(ref uuid) = contact.address().and_then(|a| a.uuid) {
- s.imp().unloaded_messages.swap(&RefCell::new(
- manager.messages_by_contact(uuid).unwrap_or_default(),
- ));
- }
s.imp().contact.swap(&RefCell::new(Some(contact)));
}
} else {
- if let Some(ref uuid) = contact.address().and_then(|a| a.uuid) {
- s.imp().unloaded_messages.swap(&RefCell::new(
- manager.messages_by_contact(uuid).unwrap_or_default(),
- ));
- }
-
s.imp().contact.swap(&RefCell::new(Some(contact)));
}
s
@@ -74,79 +63,65 @@ impl Channel {
) -> Self {
let s: Self = Object::new(&[("manager", manager)]).expect("Failed to create `Channel`");
s.imp().group.swap(&RefCell::new(Some(group)));
- s.imp().unloaded_messages.swap(&RefCell::new(
- manager
- .messages_by_group(group_context_v2)
- .unwrap_or_default(),
- ));
s.imp()
.group_context
.swap(&RefCell::new(Some(group_context_v2.clone())));
- s.imp().unloaded_messages.swap(&RefCell::new(
- manager
- .messages_by_group(group_context_v2)
- .unwrap_or_default(),
- ));
s
}
+ fn thread(&self) -> Option {
+ if let Some(key) = self
+ .group_context()
+ .and_then(|c| c.master_key)
+ .and_then(|k| <[u8; 32]>::try_from(k).ok())
+ {
+ Some(Thread::Group(key))
+ } else {
+ Some(Thread::Contact(self.uuid()?))
+ }
+ }
+
#[async_recursion::async_recursion(?Send)]
pub async fn load_last(&self, number: usize) -> Vec {
- let to_load = {
- let mut unloaded_msgs = self.imp().unloaded_messages.borrow_mut();
+ if let Some(thread) = self.thread() {
+ let mut results = vec![];
+ let manager = self.property::("manager");
+ let messages_unborrowed = &self.imp().messages;
+ let first_timestamp = {
+ let msgs = messages_unborrowed.borrow();
+ msgs.get(0).and_then(|m| m.timestamp()).map(|t| t - 1)
+ };
crate::trace!(
- "Loading last messages for channel: {} ({:?}). Got {} total unloaded messages.",
+ "Loading {} last messages for channel: {} (Thread: {:?}). Needed earlier then {:?}",
+ number,
self.property::("title"),
- self.uuid(),
- unloaded_msgs.len()
+ thread,
+ first_timestamp
);
- if unloaded_msgs.len() <= number {
- unloaded_msgs.drain(..).collect::>()
- } else {
- unloaded_msgs.drain(..number).collect::>()
+ // TODO: Skip already loaded messages?
+ let iter = manager.messages_by_thread(&thread, first_timestamp);
+ if iter.is_err() {
+ return vec![];
}
- };
-
- if to_load.is_empty() {
- return vec![];
- }
-
- let mut empty = 0;
- let mut results = vec![];
- let manager = self.property::("manager");
- for msg_id in to_load {
- if let Ok(Some(msg)) = manager.message_by_id(&msg_id).await {
+ for content in iter.unwrap() {
+ let msg = Message::from_content(content, &manager).await;
if !msg.is_empty() {
{
- let mut messages = self.imp().messages.borrow_mut();
+ let mut messages = messages_unborrowed.borrow_mut();
messages.insert(0, msg.clone());
}
results.insert(0, msg.clone());
self.notify("last-message");
- } else {
- log::trace!(
- "Channel {} got empty message, skipping.",
- self.property::("title")
- );
- empty += 1
+ let _ = self.do_new_message(&msg).await;
+ }
+ if results.len() == number {
+ break;
}
- // TODO: Error?
- let _ = self.do_new_message(&msg).await;
- } else {
- log::warn!(
- "Channel {} got message that could not be found, skipping.",
- self.property::("title")
- );
}
- }
-
- let mut previous = if empty != 0 {
- self.load_last(empty).await
+ results
} else {
vec![]
- };
- previous.append(&mut results);
- previous
+ }
}
pub(super) fn internal_hash(&self) -> u64 {
@@ -179,6 +154,7 @@ impl Channel {
body
);
if let Some(quote) = message.quote() {
+ log::trace!("Message claims to have a quote");
if let Ok(id) = MessageIdentity::try_from("e) {
if let Ok(Some(quoted_msg)) =
self.property::("manager").message_by_id(&id).await
@@ -355,7 +331,6 @@ mod imp {
pub(super) manager: RefCell