From 9d033e2ea15ffcfe3f5bc3265cf0bde2c59d33c3 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Sat, 16 May 2020 23:06:32 +0300 Subject: [PATCH] Start autodelete timer when message is displayed --- python/tests/test_account.py | 13 +++++++++++- src/message.rs | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/python/tests/test_account.py b/python/tests/test_account.py index b0b8ab49a..9d634c39d 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -1497,7 +1497,13 @@ class TestOnlineAccount: assert "Autodelete timer: 60\n" in system_message1.get_message_info() lp.sec("ac2: send message to ac1") - chat2.send_text("message") + sent_message = chat2.send_text("message") + assert sent_message.is_encrypted() + assert "Autodelete timer: 60\n" in sent_message.get_message_info() + + # Timer is started immediately for sent messages + assert "Expires: " in sent_message.get_message_info() + lp.sec("ac1: waiting for message from ac2") incoming_message_event2 = ac1._evtracker.get_matching("DC_EVENT_INCOMING_MSG") text_message = ac1.get_message_by_id(incoming_message_event2.data2) @@ -1505,6 +1511,11 @@ class TestOnlineAccount: assert text_message.is_encrypted() assert "Autodelete timer: 60\n" in text_message.get_message_info() + # Timer should not start until message is displayed + assert "Expires: " not in text_message.get_message_info() + text_message.mark_seen() + assert "Expires: " in text_message.get_message_info() + lp.sec("ac2: set autodelete timer to 0") chat2.set_autodelete_timer(0) diff --git a/src/message.rs b/src/message.rs index 2b2e44bb9..b518012e8 100644 --- a/src/message.rs +++ b/src/message.rs @@ -133,6 +133,36 @@ impl MsgId { ) } + /// Returns autodelete timer value for the message. + pub(crate) fn autodelete_timer(self, context: &Context) -> sql::Result> { + let res = match context.sql.query_get_value_result( + "SELECT autodelete_timer FROM msgs WHERE id=?", + params![self], + )? { + None | Some(0) => None, + Some(timer) => Some(timer), + }; + Ok(res) + } + + /// Starts autodelete timer for the message if it is not started yet. + pub(crate) fn start_autodelete_timer(self, context: &Context) -> sql::Result<()> { + if let Some(autodelete_timer) = self.autodelete_timer(context)? { + let autodelete_timestamp = time() + autodelete_timer; + + sql::execute( + context, + &context.sql, + "UPDATE msgs SET autodelete_timestamp = ? \ + WHERE (autodelete_timestamp == 0 OR autodelete_timestamp > ?) \ + AND id = ?", + params![autodelete_timestamp, autodelete_timestamp, self], + ) + } else { + Ok(()) + } + } + /// Bad evil escape hatch. /// /// Avoid using this, eventually types should be cleaned up enough @@ -1077,6 +1107,14 @@ pub fn markseen_msgs(context: &Context, msg_ids: &[MsgId]) -> bool { let msgs = msgs.unwrap_or_default(); for (id, curr_state, curr_blocked) in msgs.into_iter() { + if let Err(err) = id.start_autodelete_timer(context) { + warn!( + context, + "Failed to start autodelete timer for message {}: {}", id, err + ); + continue; + } + if curr_blocked == Blocked::Not { if curr_state == MessageState::InFresh || curr_state == MessageState::InNoticed { update_msg_state(context, *id, MessageState::InSeen);