Fixes bug where updates can cause a sync loop
This commit is contained in:
@@ -131,7 +131,7 @@ impl<'a> Repository<'a> {
|
|||||||
.execute(self.connection)?;
|
.execute(self.connection)?;
|
||||||
|
|
||||||
// Update conversation date
|
// Update conversation date
|
||||||
self.update_conversation_metadata(conversation_guid, &db_message)?;
|
self.update_conversation_metadata(conversation_guid)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ impl<'a> Repository<'a> {
|
|||||||
.execute(self.connection)?;
|
.execute(self.connection)?;
|
||||||
|
|
||||||
// Update conversation date
|
// Update conversation date
|
||||||
self.update_conversation_metadata(conversation_guid, &db_messages.last().unwrap())?;
|
self.update_conversation_metadata(conversation_guid)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -243,14 +243,16 @@ impl<'a> Repository<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_conversation_metadata(&mut self, conversation_guid: &str, last_message: &MessageRecord) -> Result<()> {
|
fn update_conversation_metadata(&mut self, conversation_guid: &str) -> Result<()> {
|
||||||
let conversation = self.get_conversation_by_guid(conversation_guid)?;
|
let conversation = self.get_conversation_by_guid(conversation_guid)?;
|
||||||
if let Some(mut conversation) = conversation {
|
if let Some(mut conversation) = conversation {
|
||||||
|
if let Some(last_message) = self.get_last_message_for_conversation(conversation_guid)? {
|
||||||
log::debug!("Updating conversation metadata: {} message: {:?}", conversation_guid, last_message);
|
log::debug!("Updating conversation metadata: {} message: {:?}", conversation_guid, last_message);
|
||||||
conversation.date = last_message.date;
|
conversation.date = last_message.date;
|
||||||
conversation.last_message_preview = Some(last_message.text.clone());
|
conversation.last_message_preview = Some(last_message.text.clone());
|
||||||
self.insert_conversation(conversation)?;
|
self.insert_conversation(conversation)?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use time::OffsetDateTime;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::Identifiable;
|
use super::Identifiable;
|
||||||
|
use crate::model::message::Message;
|
||||||
|
|
||||||
pub type ConversationID = <Conversation as Identifiable>::ID;
|
pub type ConversationID = <Conversation as Identifiable>::ID;
|
||||||
|
|
||||||
@@ -24,6 +25,9 @@ pub struct Conversation {
|
|||||||
|
|
||||||
#[serde(rename = "displayName")]
|
#[serde(rename = "displayName")]
|
||||||
pub display_name: Option<String>,
|
pub display_name: Option<String>,
|
||||||
|
|
||||||
|
#[serde(rename = "lastMessage")]
|
||||||
|
pub last_message: Option<Message>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Conversation {
|
impl Conversation {
|
||||||
@@ -48,6 +52,7 @@ pub struct ConversationBuilder {
|
|||||||
last_message_preview: Option<String>,
|
last_message_preview: Option<String>,
|
||||||
participant_display_names: Option<Vec<String>>,
|
participant_display_names: Option<Vec<String>>,
|
||||||
display_name: Option<String>,
|
display_name: Option<String>,
|
||||||
|
last_message: Option<Message>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConversationBuilder {
|
impl ConversationBuilder {
|
||||||
@@ -85,6 +90,11 @@ impl ConversationBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn last_message(mut self, last_message: Message) -> Self {
|
||||||
|
self.last_message = Some(last_message);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Conversation {
|
pub fn build(self) -> Conversation {
|
||||||
Conversation {
|
Conversation {
|
||||||
guid: self.guid.unwrap_or(Uuid::new_v4().to_string()),
|
guid: self.guid.unwrap_or(Uuid::new_v4().to_string()),
|
||||||
@@ -93,6 +103,7 @@ impl ConversationBuilder {
|
|||||||
last_message_preview: self.last_message_preview,
|
last_message_preview: self.last_message_preview,
|
||||||
participant_display_names: self.participant_display_names.unwrap_or_default(),
|
participant_display_names: self.participant_display_names.unwrap_or_default(),
|
||||||
display_name: self.display_name,
|
display_name: self.display_name,
|
||||||
|
last_message: self.last_message,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use kordophone::api::event_socket::EventSocket;
|
|||||||
use kordophone::model::event::Event as UpdateEvent;
|
use kordophone::model::event::Event as UpdateEvent;
|
||||||
|
|
||||||
use kordophone_db::database::Database;
|
use kordophone_db::database::Database;
|
||||||
|
use kordophone_db::database::DatabaseAccess;
|
||||||
|
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -42,14 +43,33 @@ impl UpdateMonitor {
|
|||||||
match update {
|
match update {
|
||||||
UpdateEvent::ConversationChanged(conversation) => {
|
UpdateEvent::ConversationChanged(conversation) => {
|
||||||
log::info!(target: target::UPDATES, "Conversation changed: {:?}", conversation);
|
log::info!(target: target::UPDATES, "Conversation changed: {:?}", conversation);
|
||||||
if conversation.unread_count > 0 {
|
|
||||||
log::info!(target: target::UPDATES, "Syncing new messages for conversation id: {}", conversation.guid);
|
// Weird. We can get in a loop because calling getMessages triggers a conversation changed
|
||||||
|
// event for some reason. Check to see if the change event says the last message id is the same
|
||||||
|
// as the last message id in the database. If so, skip the sync.
|
||||||
|
let last_message = self.database.with_repository(|r| r.get_last_message_for_conversation(&conversation.guid)).await.unwrap_or_default();
|
||||||
|
let should_sync_conversation = match (&last_message, &conversation.last_message) {
|
||||||
|
(Some(message), Some(conversation_message)) => {
|
||||||
|
if message.id == conversation_message.guid {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => true
|
||||||
|
};
|
||||||
|
|
||||||
|
if !should_sync_conversation {
|
||||||
|
log::info!(target: target::UPDATES, "Skipping sync for conversation id: {}. We already have this message.", conversation.guid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!(target: target::UPDATES, "Syncing new messages for conversation id: {}, last message: {:?}", conversation.guid, last_message);
|
||||||
self.send_event(|r| Event::SyncConversation(conversation.guid, r)).await
|
self.send_event(|r| Event::SyncConversation(conversation.guid, r)).await
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
log::error!("Failed to send daemon event: {}", e);
|
log::error!("Failed to send daemon event: {}", e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
UpdateEvent::MessageReceived(conversation, message) => {
|
UpdateEvent::MessageReceived(conversation, message) => {
|
||||||
log::info!(target: target::UPDATES, "Message received: msgid:{:?}, convid:{:?}", message.guid, conversation.guid);
|
log::info!(target: target::UPDATES, "Message received: msgid:{:?}, convid:{:?}", message.guid, conversation.guid);
|
||||||
|
|||||||
Reference in New Issue
Block a user