diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 0dd56b4da..ef64ed58d 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -3026,6 +3026,32 @@ int dc_msg_get_duration (const dc_msg_t* msg); int dc_msg_get_showpadlock (const dc_msg_t* msg); +/** + * Get ephemeral timer duration for message. + * + * To check if the timer is started and calculate remaining time, + * use dc_msg_get_ephemeral_timestamp(). + * + * @memberof dc_msg_t + * @param msg The message object. + * @return Duration in seconds, or 0 if no timer is set. + */ +uint32_t dc_msg_get_ephemeral_timer (const dc_msg_t* msg); + +/** + * Get timestamp of ephemeral message removal. + * + * If returned value is non-zero, you can calculate the * fraction of + * time remaining by divinding the difference between the current timestamp + * and this timestamp by dc_msg_get_ephemeral_timer(). + * + * @memberof dc_msg_t + * @param msg The message object. + * @return Time of message removal, 0 if the timer is not started. + */ +int64_t dc_msg_get_ephemeral_timestamp (const dc_msg_t* msg); + + /** * Get a summary for a message. * diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 1856333f6..b36b78976 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -2675,6 +2675,26 @@ pub unsafe extern "C" fn dc_msg_get_showpadlock(msg: *mut dc_msg_t) -> libc::c_i ffi_msg.message.get_showpadlock() as libc::c_int } +#[no_mangle] +pub unsafe extern "C" fn dc_msg_get_ephemeral_timer(msg: *mut dc_msg_t) -> u32 { + if msg.is_null() { + eprintln!("ignoring careless call to dc_msg_get_ephemeral_timer()"); + return 0; + } + let ffi_msg = &*msg; + ffi_msg.message.get_ephemeral_timer() +} + +#[no_mangle] +pub unsafe extern "C" fn dc_msg_get_ephemeral_timestamp(msg: *mut dc_msg_t) -> i64 { + if msg.is_null() { + eprintln!("ignoring careless call to dc_msg_get_ephemeral_timer()"); + return 0; + } + let ffi_msg = &*msg; + ffi_msg.message.get_ephemeral_timestamp() +} + #[no_mangle] pub unsafe extern "C" fn dc_msg_get_summary( msg: *mut dc_msg_t, diff --git a/python/src/deltachat/message.py b/python/src/deltachat/message.py index 5c3bd7f59..7a7bbd2d9 100644 --- a/python/src/deltachat/message.py +++ b/python/src/deltachat/message.py @@ -154,6 +154,26 @@ class Message(object): if ts: return datetime.utcfromtimestamp(ts) + @props.with_doc + def ephemeral_timer(self): + """Ephemeral timer in seconds + + :returns: timer in seconds or None if there is no timer + """ + timer = lib.dc_msg_get_ephemeral_timer(self._dc_msg) + if timer: + return timer + + @props.with_doc + def ephemeral_timestamp(self): + """UTC time when the message will be deleted. + + :returns: naive datetime.datetime() object or None if the timer is not started. + """ + ts = lib.dc_msg_get_ephemeral_timestamp(self._dc_msg) + if ts: + return datetime.utcfromtimestamp(ts) + def get_mime_headers(self): """ return mime-header object for an incoming message. diff --git a/python/tests/test_account.py b/python/tests/test_account.py index c65164eb7..526c98c4a 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -1568,19 +1568,25 @@ class TestOnlineAccount: lp.sec("ac2: send message to ac1") sent_message = chat2.send_text("message") + assert sent_message.ephemeral_timer == 60 assert "Ephemeral timer: 60\n" in sent_message.get_message_info() # Timer is started immediately for sent messages + assert sent_message.ephemeral_timestamp is not None assert "Expires: " in sent_message.get_message_info() lp.sec("ac1: waiting for message from ac2") text_message = ac1._evtracker.wait_next_incoming_message() assert text_message.text == "message" + assert text_message.ephemeral_timer == 60 assert "Ephemeral timer: 60\n" in text_message.get_message_info() # Timer should not start until message is displayed + assert text_message.ephemeral_timestamp is None assert "Expires: " not in text_message.get_message_info() text_message.mark_seen() + text_message = ac1.get_message_by_id(text_message.id) + assert text_message.ephemeral_timestamp is not None assert "Expires: " in text_message.get_message_info() lp.sec("ac2: set ephemeral timer to 0") @@ -1589,6 +1595,7 @@ class TestOnlineAccount: lp.sec("ac1: receive system message about ephemeral timer modification") ac1._evtracker.get_matching("DC_EVENT_CHAT_EPHEMERAL_TIMER_MODIFIED") system_message2 = ac1._evtracker.wait_next_incoming_message() + assert system_message2.ephemeral_timer is None assert "Ephemeral timer: " not in system_message2.get_message_info() assert chat1.get_ephemeral_timer() == 0 diff --git a/src/message.rs b/src/message.rs index 71b20c2aa..cadc025b9 100644 --- a/src/message.rs +++ b/src/message.rs @@ -223,7 +223,7 @@ pub struct Message { pub(crate) timestamp_sort: i64, pub(crate) timestamp_sent: i64, pub(crate) timestamp_rcvd: i64, - pub(crate) ephemeral_timer: i64, + pub(crate) ephemeral_timer: u32, pub(crate) ephemeral_timestamp: i64, pub(crate) text: Option, pub(crate) rfc724_mid: String, @@ -493,6 +493,14 @@ impl Message { self.param.get_int(Param::GuaranteeE2ee).unwrap_or_default() != 0 } + pub fn get_ephemeral_timer(&self) -> u32 { + self.ephemeral_timer + } + + pub fn get_ephemeral_timestamp(&self) -> i64 { + self.ephemeral_timestamp + } + pub async fn get_summary(&mut self, context: &Context, chat: Option<&Chat>) -> Lot { let mut ret = Lot::new();