add can_send_edit_request() api

This commit is contained in:
B. Petersen
2025-02-22 22:12:03 +01:00
parent fbf3ff0112
commit b455344a14
5 changed files with 103 additions and 13 deletions

View File

@@ -3133,22 +3133,13 @@ pub async fn send_text_msg(
/// Sends chat members a request to edit the given message's text.
pub async fn send_edit_request(context: &Context, msg_id: MsgId, new_text: String) -> Result<()> {
let mut original_msg = Message::load_from_db(context, msg_id).await?;
ensure!(
original_msg.from_id == ContactId::SELF,
"Can edit only own messages"
);
ensure!(!original_msg.is_info(), "Cannot edit info messages");
ensure!(!original_msg.has_html(), "Cannot edit HTML messages");
ensure!(
original_msg.viewtype != Viewtype::VideochatInvitation,
"Cannot edit videochat invitations"
);
ensure!(
!original_msg.text.is_empty(), // avoid complexity in UI element changes. focus is typos and rewordings
"Cannot add text"
message::can_send_edit_request(context, msg_id).await?,
"Message cannot be edited"
);
ensure!(!new_text.trim().is_empty(), "Edited text cannot be empty");
let mut original_msg = Message::load_from_db(context, msg_id).await?;
if original_msg.text == new_text {
info!(context, "Text unchanged.");
return Ok(());

View File

@@ -1500,6 +1500,22 @@ pub async fn get_msg_read_receipts(
.await
}
/// Returns true if the message can be edited.
pub async fn can_send_edit_request(context: &Context, msg_id: MsgId) -> Result<bool> {
let msg = Message::load_from_db(context, msg_id).await?;
if msg.from_id != ContactId::SELF
|| msg.is_info()
|| msg.viewtype == Viewtype::VideochatInvitation
|| msg.has_html()
|| msg.text.is_empty()
{
return Ok(false);
}
let chat = Chat::load_from_db(context, msg.get_chat_id()).await?;
let can_send = chat.can_send(context).await?;
Ok(can_send)
}
pub(crate) fn guess_msgtype_from_suffix(msg: &Message) -> Option<(Viewtype, &'static str)> {
msg.param
.get(Param::Filename)

View File

@@ -783,3 +783,55 @@ async fn test_sanitize_filename_message() -> Result<()> {
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn text_can_send_edit_request() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let bob = tcm.bob().await;
let chat_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "My Group", &[&bob])
.await;
// Alice can edit her message
let sent1 = alice.send_text(chat_id, "foo").await;
assert!(can_send_edit_request(&alice, sent1.sender_msg_id).await?);
// Bob cannot edit Alice's message
let msg = bob.recv_msg(&sent1).await;
assert!(!can_send_edit_request(&bob, msg.id).await?);
// HTML messages cannot be edited
let mut msg = Message::new_text("plain text".to_string());
msg.set_html(Some("<b>html</b> text".to_string()));
let sent2 = alice.send_msg(chat_id, &mut msg).await;
assert!(!can_send_edit_request(&alice, sent2.sender_msg_id).await?);
// Info messages cannot be edited
chat::set_chat_name(&alice, chat_id, "bar").await?;
let msg = alice.get_last_msg().await;
assert!(msg.is_info());
assert_eq!(msg.from_id, ContactId::SELF);
assert!(!can_send_edit_request(&alice, msg.id).await?);
// Videochat invitations cannot be edited
alice
.set_config(Config::WebrtcInstance, Some("https://foo.bar"))
.await?;
let msg_id = chat::send_videochat_invitation(&alice, chat_id).await?;
assert!(!can_send_edit_request(&alice, msg_id).await?);
// If not text was given initally, there is nothing to edit
// (this also avoids complexity in UI element changes; focus is typos and rewordings)
let mut msg = Message::new(Viewtype::File);
msg.make_vcard(&alice, &[ContactId::SELF]).await?;
let sent3 = alice.send_msg(chat_id, &mut msg).await;
assert!(msg.text.is_empty());
assert!(!can_send_edit_request(&alice, sent3.sender_msg_id).await?);
// Messages in left groups cannot be edited any longer (as one cannot send to that group)
chat::remove_contact_from_chat(&alice, chat_id, ContactId::SELF).await?;
assert!(!can_send_edit_request(&alice, sent1.sender_msg_id).await?);
Ok(())
}