From beb6a21ecd9d7d4969b985c461dca2fa42e6718f Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 23 Dec 2024 20:56:50 +0000 Subject: [PATCH] feat: start ephemeral timers when the chat is noticed --- src/chat.rs | 27 ++++++++++++++++----------- src/ephemeral.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index c4f1f3d7a4..3e9eade4b5 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -28,7 +28,7 @@ use crate::contact::{self, Contact, ContactId, Origin}; use crate::context::Context; use crate::debug_logging::maybe_set_logging_xdc; use crate::download::DownloadState; -use crate::ephemeral::Timer as EphemeralTimer; +use crate::ephemeral::{start_chat_ephemeral_timers, Timer as EphemeralTimer}; use crate::events::EventType; use crate::html::new_html_mimepart; use crate::location; @@ -3269,20 +3269,24 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<()> context.emit_event(EventType::MsgsNoticed(chat_id_in_archive)); chatlist_events::emit_chatlist_item_changed(context, chat_id_in_archive); } - } else if context - .sql - .execute( - "UPDATE msgs + } else { + start_chat_ephemeral_timers(context, chat_id).await?; + + if context + .sql + .execute( + "UPDATE msgs SET state=? WHERE state=? AND hidden=0 AND chat_id=?;", - (MessageState::InNoticed, MessageState::InFresh, chat_id), - ) - .await? - == 0 - { - return Ok(()); + (MessageState::InNoticed, MessageState::InFresh, chat_id), + ) + .await? + == 0 + { + return Ok(()); + } } context.emit_event(EventType::MsgsNoticed(chat_id)); @@ -3354,6 +3358,7 @@ pub(crate) async fn mark_old_messages_as_noticed( } for c in changed_chats { + start_chat_ephemeral_timers(context, c).await?; context.emit_event(EventType::MsgsNoticed(c)); chatlist_events::emit_chatlist_item_changed(context, c); } diff --git a/src/ephemeral.rs b/src/ephemeral.rs index 4567c8343e..d6e6b8af5d 100644 --- a/src/ephemeral.rs +++ b/src/ephemeral.rs @@ -349,6 +349,28 @@ pub(crate) async fn start_ephemeral_timers_msgids( Ok(()) } +/// Starts ephemeral timer for all messages in the chat. +/// +/// This should be called when chat is marked as noticed. +pub(crate) async fn start_chat_ephemeral_timers(context: &Context, chat_id: ChatId) -> Result<()> { + let now = time(); + let should_interrupt = context + .sql + .execute( + "UPDATE msgs SET ephemeral_timestamp = ?1 + ephemeral_timer + WHERE chat_id = ?2 + AND ephemeral_timer > 0 + AND (ephemeral_timestamp == 0 OR ephemeral_timestamp > ?1 + ephemeral_timer)", + (now, chat_id), + ) + .await? + > 0; + if should_interrupt { + context.scheduler.interrupt_ephemeral_task().await; + } + Ok(()) +} + /// Selects messages which are expired according to /// `delete_device_after` setting or `ephemeral_timestamp` column. /// @@ -693,6 +715,7 @@ pub(crate) async fn start_ephemeral_timers(context: &Context) -> Result<()> { #[cfg(test)] mod tests { use super::*; + use crate::chat::marknoticed_chat; use crate::config::Config; use crate::download::DownloadState; use crate::location; @@ -1420,4 +1443,29 @@ mod tests { Ok(()) } + + /// Tests that ephemeral timer is started when the chat is noticed. + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_noticed_ephemeral_timer() -> Result<()> { + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + + let chat = alice.create_chat(bob).await; + let duration = 60; + chat.id + .set_ephemeral_timer(alice, Timer::Enabled { duration }) + .await?; + let bob_received_message = tcm.send_recv(alice, bob, "Hello!").await; + + marknoticed_chat(bob, bob_received_message.chat_id).await?; + SystemTime::shift(Duration::from_secs(100)); + + delete_expired_messages(bob, time()).await?; + + assert!(Message::load_from_db_optional(bob, bob_received_message.id) + .await? + .is_none()); + Ok(()) + } }