Implements mark as read
This commit is contained in:
@@ -43,6 +43,12 @@
|
||||
value="Initiates a background sync of a single conversation with the server."/>
|
||||
</method>
|
||||
|
||||
<method name="MarkConversationAsRead">
|
||||
<arg type="s" name="conversation_id" direction="in"/>
|
||||
<annotation name="org.freedesktop.DBus.DocString"
|
||||
value="Marks a conversation as read."/>
|
||||
</method>
|
||||
|
||||
<signal name="ConversationsUpdated">
|
||||
<annotation name="org.freedesktop.DBus.DocString"
|
||||
value="Emitted when the list of conversations is updated."/>
|
||||
|
||||
@@ -26,6 +26,12 @@ pub enum Event {
|
||||
/// Asynchronous event for syncing a single conversation with the server.
|
||||
SyncConversation(String, Reply<()>),
|
||||
|
||||
/// Asynchronous event for marking a conversation as read.
|
||||
MarkConversationAsRead(String, Reply<()>),
|
||||
|
||||
/// Asynchronous event for updating the metadata for a conversation.
|
||||
UpdateConversationMetadata(Conversation, Reply<()>),
|
||||
|
||||
/// Sent when the update stream is reconnected after a timeout or configuration change.
|
||||
UpdateStreamReconnected,
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ pub mod target {
|
||||
pub static SETTINGS: &str = "settings";
|
||||
pub static UPDATES: &str = "updates";
|
||||
pub static ATTACHMENTS: &str = "attachments";
|
||||
pub static DAEMON: &str = "daemon";
|
||||
}
|
||||
|
||||
pub struct Daemon {
|
||||
@@ -221,6 +222,31 @@ impl Daemon {
|
||||
reply.send(()).unwrap();
|
||||
}
|
||||
|
||||
Event::MarkConversationAsRead(conversation_id, reply) => {
|
||||
let mut db_clone = self.database.clone();
|
||||
self.runtime.spawn(async move {
|
||||
let result = Self::mark_conversation_as_read_impl(&mut db_clone, conversation_id).await;
|
||||
if let Err(e) = result {
|
||||
log::error!(target: target::DAEMON, "Error handling mark conversation as read event: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
reply.send(()).unwrap();
|
||||
}
|
||||
|
||||
Event::UpdateConversationMetadata(conversation, reply) => {
|
||||
let mut db_clone = self.database.clone();
|
||||
let signal_sender = self.signal_sender.clone();
|
||||
self.runtime.spawn(async move {
|
||||
let result = Self::update_conversation_metadata_impl(&mut db_clone, conversation, &signal_sender).await;
|
||||
if let Err(e) = result {
|
||||
log::error!(target: target::DAEMON, "Error handling update conversation metadata event: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
reply.send(()).unwrap();
|
||||
}
|
||||
|
||||
Event::UpdateStreamReconnected => {
|
||||
log::info!(target: target::UPDATES, "Update stream reconnected");
|
||||
|
||||
@@ -590,6 +616,33 @@ impl Daemon {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn mark_conversation_as_read_impl(
|
||||
database: &mut Arc<Mutex<Database>>,
|
||||
conversation_id: String,
|
||||
) -> Result<()> {
|
||||
log::debug!(target: target::DAEMON, "Marking conversation as read: {}", conversation_id);
|
||||
|
||||
let mut client = Self::get_client_impl(database).await?;
|
||||
client.mark_conversation_as_read(&conversation_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_conversation_metadata_impl(
|
||||
database: &mut Arc<Mutex<Database>>,
|
||||
conversation: Conversation,
|
||||
signal_sender: &Sender<Signal>,
|
||||
) -> Result<()> {
|
||||
log::debug!(target: target::DAEMON, "Updating conversation metadata: {}", conversation.guid);
|
||||
let updated = database.with_repository(|r| r.merge_conversation_metadata(conversation)).await?;
|
||||
if updated {
|
||||
signal_sender
|
||||
.send(Signal::ConversationsUpdated)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_settings(&mut self) -> Result<Settings> {
|
||||
let settings = self.database.with_settings(Settings::from_db).await?;
|
||||
Ok(settings)
|
||||
|
||||
@@ -65,11 +65,19 @@ impl UpdateMonitor {
|
||||
UpdateEventData::ConversationChanged(conversation) => {
|
||||
log::info!(target: target::UPDATES, "Conversation changed: {:?}", conversation);
|
||||
|
||||
// Explicitly update the unread count, we assume this is fresh from the notification.
|
||||
let db_conversation: kordophone_db::models::Conversation = conversation.clone().into();
|
||||
self.send_event(|r| Event::UpdateConversationMetadata(db_conversation, r))
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
log::error!("Failed to send daemon event: {}", e);
|
||||
});
|
||||
|
||||
// Check if we've synced this conversation recently (within 5 seconds)
|
||||
// This is currently a hack/workaround to prevent an infinite loop of sync events, because for some reason
|
||||
// imagent will post a conversation changed notification when we call getMessages.
|
||||
if let Some(last_sync) = self.last_sync_times.get(&conversation.guid) {
|
||||
if last_sync.elapsed() < Duration::from_secs(5) {
|
||||
if last_sync.elapsed() < Duration::from_secs(1) {
|
||||
log::info!(target: target::UPDATES, "Skipping sync for conversation id: {}. Last sync was {} seconds ago.",
|
||||
conversation.guid, last_sync.elapsed().as_secs_f64());
|
||||
return;
|
||||
@@ -85,7 +93,7 @@ impl UpdateMonitor {
|
||||
match (&last_message, &conversation.last_message) {
|
||||
(Some(message), Some(conversation_message)) => {
|
||||
if message.id == conversation_message.guid {
|
||||
log::info!(target: target::UPDATES, "Skipping sync for conversation id: {}. We already have this message.", conversation.guid);
|
||||
log::info!(target: target::UPDATES, "Skipping sync for conversation id: {}. We already have this message.", &conversation.guid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,6 +233,10 @@ impl DbusRepository for DBusAgent {
|
||||
self.send_event_sync(|r| Event::SyncConversation(conversation_id, r))
|
||||
}
|
||||
|
||||
fn mark_conversation_as_read(&mut self, conversation_id: String) -> Result<(), MethodErr> {
|
||||
self.send_event_sync(|r| Event::MarkConversationAsRead(conversation_id, r))
|
||||
}
|
||||
|
||||
fn get_messages(&mut self, conversation_id: String, last_message_id: String) -> Result<Vec<arg::PropMap>, MethodErr> {
|
||||
let last_message_id_opt = if last_message_id.is_empty() {
|
||||
None
|
||||
|
||||
Reference in New Issue
Block a user