allow removing quotes on existing drafts (#2950)

allow `dc_msg_set_quote(msg, NULL)` and `msg.set_quote(None)`
to simplify draft handling keeping message-ids (as needed for webxdc updates).

closes #2948
This commit is contained in:
bjoern
2022-01-05 23:59:04 +01:00
committed by GitHub
parent c69ee180af
commit b3e3b1e245
5 changed files with 103 additions and 39 deletions

View File

@@ -4165,7 +4165,8 @@ void dc_msg_latefiling_mediasize (dc_msg_t* msg, int width, int hei
*
* @memberof dc_msg_t
* @param msg The message object to set the reply to.
* @param quote The quote to set for msg.
* @param quote The quote to set for the message object given as `msg`.
* NULL removes an previously set quote.
*/
void dc_msg_set_quote (dc_msg_t* msg, const dc_msg_t* quote);

View File

@@ -3372,17 +3372,21 @@ pub unsafe extern "C" fn dc_msg_set_quote(msg: *mut dc_msg_t, quote: *const dc_m
return;
}
let ffi_msg = &mut *msg;
let ffi_quote = &*quote;
if ffi_msg.context != ffi_quote.context {
eprintln!("ignoring attempt to quote message from a different context");
return;
}
let quote_msg = if quote.is_null() {
None
} else {
let ffi_quote = &*quote;
if ffi_msg.context != ffi_quote.context {
eprintln!("ignoring attempt to quote message from a different context");
return;
}
Some(&ffi_quote.message)
};
block_on(async move {
ffi_msg
.message
.set_quote(&*ffi_msg.context, &ffi_quote.message)
.set_quote(&*ffi_msg.context, quote_msg)
.await
.log_err(&*ffi_msg.context, "failed to set quote")
.ok();

View File

@@ -3441,6 +3441,58 @@ mod tests {
Ok(())
}
#[async_std::test]
async fn test_change_quotes_on_reused_message_object() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "chat").await?;
let quote1 =
Message::load_from_db(&t, send_text_msg(&t, chat_id, "quote1".to_string()).await?)
.await?;
let quote2 =
Message::load_from_db(&t, send_text_msg(&t, chat_id, "quote2".to_string()).await?)
.await?;
// save a draft
let mut draft = Message::new(Viewtype::Text);
draft.set_text(Some("draft text".to_string()));
chat_id.set_draft(&t, Some(&mut draft)).await?;
let test = Message::load_from_db(&t, draft.id).await?;
assert_eq!(test.text, Some("draft text".to_string()));
assert!(test.quoted_text().is_none());
assert!(test.quoted_message(&t).await?.is_none());
// add quote to same message object
draft.set_quote(&t, Some(&quote1)).await?;
chat_id.set_draft(&t, Some(&mut draft)).await?;
let test = Message::load_from_db(&t, draft.id).await?;
assert_eq!(test.text, Some("draft text".to_string()));
assert_eq!(test.quoted_text(), Some("quote1".to_string()));
assert_eq!(test.quoted_message(&t).await?.unwrap().id, quote1.id);
// change quote on same message object
draft.set_text(Some("another draft text".to_string()));
draft.set_quote(&t, Some(&quote2)).await?;
chat_id.set_draft(&t, Some(&mut draft)).await?;
let test = Message::load_from_db(&t, draft.id).await?;
assert_eq!(test.text, Some("another draft text".to_string()));
assert_eq!(test.quoted_text(), Some("quote2".to_string()));
assert_eq!(test.quoted_message(&t).await?.unwrap().id, quote2.id);
// remove quote on same message object
draft.set_quote(&t, None).await?;
chat_id.set_draft(&t, Some(&mut draft)).await?;
let test = Message::load_from_db(&t, draft.id).await?;
assert_eq!(test.text, Some("another draft text".to_string()));
assert!(test.quoted_text().is_none());
assert!(test.quoted_message(&t).await?.is_none());
Ok(())
}
#[async_std::test]
async fn test_add_contact_to_chat_ex_add_self() {
// Adding self to a contact should succeed, even though it's pointless.
@@ -4746,7 +4798,7 @@ mod tests {
// Bob quotes received message and sends a reply to Alice.
let mut reply = Message::new(Viewtype::Text);
reply.set_text(Some("Reply".to_owned()));
reply.set_quote(&bob, &received_msg).await?;
reply.set_quote(&bob, Some(&received_msg)).await?;
let sent_reply = bob.send_msg(bob_chat.id, &mut reply).await;
alice.recv_msg(&sent_reply).await;
let received_reply = alice.get_last_msg().await;

View File

@@ -756,36 +756,41 @@ impl Message {
///
/// The message itself is not required to exist in the database,
/// it may even be deleted from the database by the time the message is prepared.
pub async fn set_quote(&mut self, context: &Context, quote: &Message) -> Result<()> {
ensure!(
!quote.rfc724_mid.is_empty(),
"Message without Message-Id cannot be quoted"
);
self.in_reply_to = Some(quote.rfc724_mid.clone());
pub async fn set_quote(&mut self, context: &Context, quote: Option<&Message>) -> Result<()> {
if let Some(quote) = quote {
ensure!(
!quote.rfc724_mid.is_empty(),
"Message without Message-Id cannot be quoted"
);
self.in_reply_to = Some(quote.rfc724_mid.clone());
if quote
.param
.get_bool(Param::GuaranteeE2ee)
.unwrap_or_default()
{
self.param.set(Param::GuaranteeE2ee, "1");
if quote
.param
.get_bool(Param::GuaranteeE2ee)
.unwrap_or_default()
{
self.param.set(Param::GuaranteeE2ee, "1");
}
let text = quote.get_text().unwrap_or_default();
self.param.set(
Param::Quote,
if text.is_empty() {
// Use summary, similar to "Image" to avoid sending empty quote.
quote
.get_summary(context, None)
.await?
.truncated_text(500)
.to_string()
} else {
text
},
);
} else {
self.in_reply_to = None;
self.param.remove(Param::Quote);
}
let text = quote.get_text().unwrap_or_default();
self.param.set(
Param::Quote,
if text.is_empty() {
// Use summary, similar to "Image" to avoid sending empty quote.
quote
.get_summary(context, None)
.await?
.truncated_text(500)
.to_string()
} else {
text
},
);
Ok(())
}
@@ -1850,7 +1855,9 @@ mod tests {
assert!(!msg.rfc724_mid.is_empty());
let mut msg2 = Message::new(Viewtype::Text);
msg2.set_quote(ctx, &msg).await.expect("can't set quote");
msg2.set_quote(ctx, Some(&msg))
.await
.expect("can't set quote");
assert!(msg2.quoted_text() == msg.get_text());
let quoted_msg = msg2

View File

@@ -1688,7 +1688,7 @@ mod tests {
let mut new_msg = Message::new(Viewtype::Text);
new_msg.set_text(Some("Hi".to_string()));
if let Some(q) = quote {
new_msg.set_quote(t, q).await?;
new_msg.set_quote(t, Some(q)).await?;
}
let sent = t.send_msg(group_id, &mut new_msg).await;
get_subject(t, sent).await
@@ -1857,7 +1857,7 @@ mod tests {
}
if reply {
new_msg.set_quote(&t, &incoming_msg).await.unwrap();
new_msg.set_quote(&t, Some(&incoming_msg)).await.unwrap();
}
let mf = MimeFactory::from_msg(&t, &new_msg, false).await.unwrap();