Skip to content

Commit

Permalink
unify get original/saved API to return IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
r10s committed Oct 17, 2024
1 parent 47e48d1 commit 1440885
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 60 deletions.
34 changes: 17 additions & 17 deletions deltachat-ffi/deltachat.h
Original file line number Diff line number Diff line change
Expand Up @@ -4882,33 +4882,33 @@ dc_msg_t* dc_msg_get_parent (const dc_msg_t* msg);


/**
* Get original message for a saved message.
* Get original chat ID for a saved message from the "Saved Messages" chat.
*
* For messages from the "Saved Messages" chat,
* this function returns the original message ID, if possible.
* Additionally, you can use dc_msg_get_original_msg_id() to find out the original message,
* which, however, may be deleted.
*
* If this function returns NULL, try dc_msg_get_original_chat_id().
* To save a message, use dc_forward_msgs().
* To check if a message is saved, use dc_msgs_get_saved_msg_id().
*
* @param msg The message object as returned for the "Saved Messages" chat.
* @return The message object of the original message.
* NULL if the given message object is not a "Saved Message"
* or if the original message does no longer exist.
* @param msg The message object. Usually, this refers to a a message inside "Saved Messages".
* @return The chat ID of the original message.
* 0 if the given message object is not a "Saved Message"
* or if the original chat does no longer exist.
*/
dc_msg_t* dc_msg_get_original_msg (const dc_msg_t* msg);
uint32_t dc_msg_get_original_chat_id (const dc_msg_t* msg);


/**
* Get original chat ID for a saved message.
* Get original message ID for a saved message from the "Saved Messages" chat.
*
* This may succeed even if the original message was deleted
* and dc_msg_get_original_msg() return NULL.
* Usually, UI will check dc_msg_get_original_chat_id() as well.
*
* @param msg The message object as returned for the "Saved Messages" chat.
* @return The chat ID of the original message.
* @param msg The message object. Usually, this refers to a a message inside "Saved Messages".
* @return The message ID of the original message.
* 0 if the given message object is not a "Saved Message"
* or if the original chat does no longer exist.
* or if the original message does no longer exist.
*/
uint32_t dc_msg_get_original_chat_id (const dc_msg_t* msg);
uint32_t dc_msg_get_original_msg_id (const dc_msg_t* msg);


/**
Expand All @@ -4917,7 +4917,7 @@ uint32_t dc_msg_get_original_chat_id (const dc_msg_t* msg);
* The returned ID can be used to un-save a message.
* The state "is saved" can be used to show some icon to indicate that a message was saved.
*
* @param msg The message object.
* @param msg The message object. Usually, this refers to a a message outside "Saved Messages".
* @return The message ID inside "Saved Messages", if any.
* 0 if the given message object is not saved.
*/
Expand Down
29 changes: 13 additions & 16 deletions deltachat-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3942,41 +3942,38 @@ pub unsafe extern "C" fn dc_msg_get_parent(msg: *const dc_msg_t) -> *mut dc_msg_
}

#[no_mangle]
pub unsafe extern "C" fn dc_msg_get_original_msg(msg: *const dc_msg_t) -> *mut dc_msg_t {
pub unsafe extern "C" fn dc_msg_get_original_chat_id(msg: *const dc_msg_t) -> u32 {
if msg.is_null() {
eprintln!("ignoring careless call to dc_msg_get_original_msg()");
return ptr::null_mut();
eprintln!("ignoring careless call to dc_msg_get_original_chat_id()");
return 0;
}
let ffi_msg: &MessageWrapper = &*msg;
let context = &*ffi_msg.context;
let res = block_on(async move {
block_on(async move {
ffi_msg
.message
.get_original_msg(context)
.get_original_chat_id(context)
.await
.context("failed to get original message")
.context("failed to get original chat")
.log_err(context)
.unwrap_or(None)
});

match res {
Some(message) => Box::into_raw(Box::new(MessageWrapper { context, message })),
None => ptr::null_mut(),
}
.unwrap_or_default()
.map(|id| id.to_u32())
.unwrap_or(0)
})
}

#[no_mangle]
pub unsafe extern "C" fn dc_msg_get_original_chat_id(msg: *const dc_msg_t) -> u32 {
pub unsafe extern "C" fn dc_msg_get_original_msg_id(msg: *const dc_msg_t) -> u32 {
if msg.is_null() {
eprintln!("ignoring careless call to dc_msg_get_original_chat_id()");
eprintln!("ignoring careless call to dc_msg_get_original_msg_id()");
return 0;
}
let ffi_msg: &MessageWrapper = &*msg;
let context = &*ffi_msg.context;
block_on(async move {
ffi_msg
.message
.get_original_chat_id(context)
.get_original_msg_id(context)
.await
.context("failed to get original message")
.log_err(context)
Expand Down
14 changes: 7 additions & 7 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6901,7 +6901,7 @@ mod tests {
let sent = alice.send_text(alice_chat.get_id(), "hi, bob").await;
let sent_msg = Message::load_from_db(&alice, sent.sender_msg_id).await?;
assert!(sent_msg.get_saved_msg_id(&alice).await?.is_none());
assert!(sent_msg.get_original_msg(&alice).await?.is_none());
assert!(sent_msg.get_original_msg_id(&alice).await?.is_none());
assert!(sent_msg.get_original_chat_id(&alice).await?.is_none());

let self_chat = alice.get_self_chat().await;
Expand All @@ -6911,7 +6911,7 @@ mod tests {
assert_ne!(saved_msg.get_id(), sent.sender_msg_id);
assert!(saved_msg.get_saved_msg_id(&alice).await?.is_none());
assert_eq!(
saved_msg.get_original_msg(&alice).await?.unwrap().id,
saved_msg.get_original_msg_id(&alice).await?.unwrap(),
sent.sender_msg_id
);
assert_eq!(
Expand All @@ -6930,7 +6930,7 @@ mod tests {
sent_msg.get_saved_msg_id(&alice).await?.unwrap(),
saved_msg.id
);
assert!(sent_msg.get_original_msg(&alice).await?.is_none());
assert!(sent_msg.get_original_msg_id(&alice).await?.is_none());
assert!(sent_msg.get_original_chat_id(&alice).await?.is_none());

let rcvd_msg = bob.recv_msg(&sent).await;
Expand All @@ -6939,7 +6939,7 @@ mod tests {
let saved_msg = bob.get_last_msg_in(self_chat.id).await;
assert_ne!(saved_msg.get_id(), rcvd_msg.id);
assert_eq!(
saved_msg.get_original_msg(&bob).await?.unwrap().id,
saved_msg.get_original_msg_id(&bob).await?.unwrap(),
rcvd_msg.id
);
assert_eq!(
Expand All @@ -6956,7 +6956,7 @@ mod tests {
// delete original message
rcvd_msg.id.delete_from_db(&bob).await?;
let saved_msg = Message::load_from_db(&bob, saved_msg.id).await?;
assert!(saved_msg.get_original_msg(&bob).await?.is_none());
assert!(saved_msg.get_original_msg_id(&bob).await?.is_none());
assert_eq!(
saved_msg.get_original_chat_id(&bob).await?.unwrap(),
rcvd_msg.chat_id
Expand Down Expand Up @@ -7006,14 +7006,14 @@ mod tests {
forward_msgs(&bob, &[orig.id], self_chat.id).await?;
let saved1 = bob.get_last_msg().await;
assert_eq!(
saved1.get_original_msg(&bob).await?.unwrap().id,
saved1.get_original_msg_id(&bob).await?.unwrap(),
sent.sender_msg_id
);

forward_msgs(&bob, &[saved1.id], self_chat.id).await?;
let saved2 = bob.get_last_msg().await;
assert_eq!(
saved2.get_original_msg(&bob).await?.unwrap().id,
saved2.get_original_msg_id(&bob).await?.unwrap(),
sent.sender_msg_id
);

Expand Down
2 changes: 1 addition & 1 deletion src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ test some special html-characters as < > and & but also " and &#x
let saved_msg = alice.get_last_msg_in(self_chat.get_id()).await;
assert_ne!(saved_msg.id, msg.id);
assert_eq!(
saved_msg.get_original_msg(&alice).await?.unwrap().id,
saved_msg.get_original_msg_id(&alice).await?.unwrap(),
msg.id
);
assert!(!saved_msg.is_forwarded()); // UI should not flag "saved messages" as "forwarded"
Expand Down
38 changes: 19 additions & 19 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1280,33 +1280,33 @@ impl Message {
Ok(None)
}

/// Returns original message object for message from "Saved Messages".
pub async fn get_original_msg(&self, context: &Context) -> Result<Option<Message>> {
/// Returns original chat ID for message from "Saved Messages".
/// This may work although get_original_msg_id() returns 0 as the message was deleted.
pub async fn get_original_chat_id(&self, context: &Context) -> Result<Option<ChatId>> {
if let Some(chat_id) = self.param.get_int(Param::OriginalChatId) {
let chat_id = ChatId::new(u32::try_from(chat_id)?);
if Chat::load_from_db(context, chat_id).await.is_ok() {
return Ok(Some(chat_id));
}
}
Ok(None)
}

/// Returns original message ID for message from "Saved Messages".
pub async fn get_original_msg_id(&self, context: &Context) -> Result<Option<MsgId>> {
if !self.original_msg_id.is_special() {
if let Some(msg) = Message::load_from_db_optional(context, self.original_msg_id).await?
{
return if msg.chat_id.is_trash() {
Ok(None)
} else {
Ok(Some(msg))
Ok(Some(msg.id))
};
}
}
Ok(None)
}

/// Returns original chat id for message from "Saved Messages".
/// This may work although get_original_msg() returns None as the message was deleted.
pub async fn get_original_chat_id(&self, context: &Context) -> Result<Option<ChatId>> {
if let Some(chat_id) = self.param.get_int(Param::OriginalChatId) {
let chat_id = ChatId::new(u32::try_from(chat_id)?);
if Chat::load_from_db(context, chat_id).await.is_ok() {
return Ok(Some(chat_id));
}
}
Ok(None)
}

/// Check if the message was saved and returns the corresponding message inside "Saved Messages".
/// UI can use this to show a symbol beside the message, indicating it was saved.
/// The message can be un-saved by deleting the returned message.
Expand Down Expand Up @@ -2563,15 +2563,15 @@ mod tests {
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_original_msg() -> Result<()> {
async fn test_get_original_msg_id() -> Result<()> {
let alice = TestContext::new_alice().await;
let bob = TestContext::new_bob().await;

// normal sending of messages does not have an original ID
let one2one_chat = alice.create_chat(&bob).await;
let sent = alice.send_text(one2one_chat.id, "foo").await;
let orig_msg = Message::load_from_db(&alice, sent.sender_msg_id).await?;
assert!(orig_msg.get_original_msg(&alice).await?.is_none());
assert!(orig_msg.get_original_msg_id(&alice).await?.is_none());
assert!(orig_msg.parent(&alice).await?.is_none());
assert!(orig_msg.quoted_message(&alice).await?.is_none());

Expand All @@ -2581,7 +2581,7 @@ mod tests {
let saved_msg = alice.get_last_msg_in(self_chat.get_id()).await;
assert_ne!(saved_msg.get_id(), orig_msg.get_id());
assert_eq!(
saved_msg.get_original_msg(&alice).await?.unwrap().get_id(),
saved_msg.get_original_msg_id(&alice).await?.unwrap(),
orig_msg.get_id()
);
assert!(saved_msg.parent(&alice).await?.is_none());
Expand All @@ -2592,7 +2592,7 @@ mod tests {
let forwarded_msg = alice.get_last_msg_in(one2one_chat.get_id()).await;
assert_ne!(forwarded_msg.get_id(), saved_msg.get_id());
assert_ne!(forwarded_msg.get_id(), orig_msg.get_id());
assert!(forwarded_msg.get_original_msg(&alice).await?.is_none());
assert!(forwarded_msg.get_original_msg_id(&alice).await?.is_none());

Ok(())
}
Expand Down

0 comments on commit 1440885

Please sign in to comment.