mirror of
https://github.com/chatmail/core.git
synced 2026-04-02 05:22:14 +03:00
Compare commits
4 Commits
v2.23.0
...
r10s/can-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48c9945be5 | ||
|
|
2281f36ce5 | ||
|
|
307b61a2c0 | ||
|
|
b455344a14 |
@@ -1039,6 +1039,20 @@ uint32_t dc_send_msg_sync (dc_context_t* context, uint32
|
||||
uint32_t dc_send_text_msg (dc_context_t* context, uint32_t chat_id, const char* text_to_send);
|
||||
|
||||
|
||||
/**
|
||||
* Check if a message can be edited using dc_send_edit_request().
|
||||
*
|
||||
* Messages that cannot be edited are eg. info messages or messages not sent by self.
|
||||
* UI will usually check this function whether to display an "Edit" option or not.
|
||||
*
|
||||
* @memberof dc_context_t
|
||||
* @param context The context object.
|
||||
* @param msg_id The message ID to check.
|
||||
* @return 1=message can be edited, 0=message cannot be edited.
|
||||
*/
|
||||
int dc_can_send_edit_request (dc_context_t* context, uint32_t msg_id);
|
||||
|
||||
|
||||
/**
|
||||
* Send chat members a request to edit the given message's text.
|
||||
*
|
||||
|
||||
@@ -1041,6 +1041,22 @@ pub unsafe extern "C" fn dc_send_text_msg(
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_can_send_edit_request(
|
||||
context: *mut dc_context_t,
|
||||
msg_id: u32,
|
||||
) -> libc::c_int {
|
||||
if context.is_null() {
|
||||
eprintln!("ignoring careless call to dc_can_send_edit_request()");
|
||||
return 0;
|
||||
}
|
||||
let ctx = &*context;
|
||||
|
||||
block_on(chat::can_send_edit_request(ctx, MsgId::new(msg_id)))
|
||||
.log_err(ctx)
|
||||
.unwrap_or_default() as libc::c_int
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_send_edit_request(
|
||||
context: *mut dc_context_t,
|
||||
|
||||
41
src/chat.rs
41
src/chat.rs
@@ -3131,24 +3131,39 @@ pub async fn send_text_msg(
|
||||
send_msg(context, chat_id, &mut msg).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 !can_send_edit_request_for_msg(&msg) {
|
||||
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)
|
||||
}
|
||||
|
||||
fn can_send_edit_request_for_msg(msg: &Message) -> bool {
|
||||
if msg.from_id != ContactId::SELF
|
||||
|| msg.is_info()
|
||||
|| msg.viewtype == Viewtype::VideochatInvitation
|
||||
|| msg.has_html()
|
||||
|| msg.text.is_empty()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// 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<()> {
|
||||
ensure!(!new_text.trim().is_empty(), "Edited text cannot be empty");
|
||||
|
||||
let mut original_msg = Message::load_from_db(context, msg_id).await?;
|
||||
ensure!(
|
||||
original_msg.from_id == ContactId::SELF,
|
||||
"Can edit only own messages"
|
||||
can_send_edit_request_for_msg(&original_msg),
|
||||
"Message cannot be edited"
|
||||
);
|
||||
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"
|
||||
);
|
||||
ensure!(!new_text.trim().is_empty(), "Edited text cannot be empty");
|
||||
|
||||
if original_msg.text == new_text {
|
||||
info!(context, "Text unchanged.");
|
||||
return Ok(());
|
||||
|
||||
@@ -3646,6 +3646,58 @@ async fn test_one_to_one_chat_no_group_member_timestamps() {
|
||||
assert!(!payload.contains("Chat-Group-Member-Timestamps:"));
|
||||
}
|
||||
|
||||
#[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
|
||||
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 = 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)
|
||||
remove_contact_from_chat(&alice, chat_id, ContactId::SELF).await?;
|
||||
assert!(!can_send_edit_request(&alice, sent1.sender_msg_id).await?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_send_edit_request() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
|
||||
Reference in New Issue
Block a user