mirror of
https://github.com/chatmail/core.git
synced 2026-04-23 08:26:30 +03:00
Implement receiving mailing lists (#1964)
* Copypaste-merge my old work * Start implementing mailinglists the new way * Create pseudo contact * Fine-tune docs * Remove some unnecessary changes * style * Make a stock str * Fix a crash. Yes, this line caused a panic when reconfiguring on Android (without a reasonable error log). Also, I could not receive any messages anymore. * rfmt * Add tests and make them pass * Even more tests * rfmt * Enhance test and fix bug * Don't update the sender name when prefetching because maybe it's a mailing list * Use an enum instead of numbers for the decision * Don't remove anyone from mailing lists * Fix bug in the regex * Adjust error msg * Compile error after rebase * Correctly emit event * Add dc_msg_is_mailing_list so that you can find out whether messages in the deaddrop belong to mailing lists. * Add received headers to unit tests * Comments, small tweaks * Use dc_msg_get_override_sender_name instead of dc_msg_get_sender_name * Add dc_msg_get_sender_first_name() because sometimes the first name was not correctly shown in mailing lists * small fixes, don't let the user modify mailing list groups * Hide contacts for addresses like noreply@github.com and reply+AEJ...@reply.github.com When testing mailing lists, I noticed that sometimes a mailing list contact got a name (like, hocuri <noreply@github.com>). It turned out that ages ago, I had accidentally written an email to - in this example - hocuri <noreply@github.com> and it had been added to the contacts list. This hides email addresses from the contacts list that are obviously not meant to be written at and prevents updating the names. * Comment, clippy * Replace u32 with ChatId * Resolve lost of small issues from the reviews * remove dc_msg_get_sender_first_name * add dc_msg_get_real_chat_id() this allows to check if a contact request belongs to a mailing list and to show name/avatar/whatever of the mailinglist. another approach was to duplicate some chat-apis for messages (eg. dc_msg_is_mailing_list()) however that would require far more new apis. the idea to change the behavior of dc_msg_get_chat_id() would be more clean, however, that easily breaks existing implementations and can led to hard to find bugs. * remove now unused Message.is_mailing_list() * if a name for a mailing list is missing, use List-ID * fix comment * fix error message * document how dc_get_chat_contacts() works for mailing lists * refine decide api (#2185) * add DC_DECIDE* constants to deltachat.h, tweak documentation * use StartChat/Block/NotNow instead of Yes/Never/NotNow * decide_on_contact_request works on ctx/msg-id functions working on message-objects usually do not read or write directly on the database. therefore, decide_on_contact_request() should not work with message-objects as well, it is even a bit misleading, as eg. chat-id of the object is not modified. instead, the function works on context, similar to dc_send_msg(), dc_create_chat() and so on. for now, i moved it to context, could maybe be part od MsgId. * Update src/chatlist.rs Co-authored-by: Hocuri <hocuri@gmx.de> Co-authored-by: Hocuri <hocuri@gmx.de> * refine documentation * re-add accidentally deleted Param::MailingList * remove pseudo-contact in domain @mailing.list 1. the pseudo-contact was added to the mailing list contacts, which is not needed. might be that we want to add the recent contacts there in a subsequent pr (we do not know all contacts of a mailing list) 2. the pseudo-contact was used to block mailing lists; this is done by setting the chat to Blocked::Manually now 3- the pseudo-contact was used for unblocking; as it is very neat not to require additional ui for mailing list unblocking, might be that we introduce a similar pseudo-contact for this limited purpose in a subsequent pr, however, the pseudo-contact needs to exist only during unblocking then, maybe also the special domain is not needed, we'll see :) * Move dc_decide_on_contact_request() up to the dc_context section as it's a member of dc_context now More specifically, to the "handle messages" section * re-introduce Chattype::Mailinglist (#2195) * re-introduce Chattype::Mailinglist * exhaustive chattype-check in fetch_existing_msgs() and get_summary2() * exhaustive chattype-check in ndn_maybe_add_info_msg() * exhaustive chattype-check in message::fill() * remove dc_chat_is_mailing_list() from ffi Co-authored-by: B. Petersen <r10s@b44t.com>
This commit is contained in:
19
src/chat.rs
19
src/chat.rs
@@ -221,6 +221,7 @@ impl ChatId {
|
||||
}
|
||||
}
|
||||
}
|
||||
Chattype::Mailinglist => bail!("Cannot protect mailing lists"),
|
||||
Chattype::Undefined => bail!("Undefined group type"),
|
||||
},
|
||||
ProtectionStatus::Unprotected => {}
|
||||
@@ -828,9 +829,13 @@ impl Chat {
|
||||
self.param.exists(Param::Devicetalk)
|
||||
}
|
||||
|
||||
pub fn is_mailing_list(&self) -> bool {
|
||||
self.typ == Chattype::Mailinglist
|
||||
}
|
||||
|
||||
/// Returns true if user can send messages to this chat.
|
||||
pub fn can_send(&self) -> bool {
|
||||
!self.id.is_special() && !self.is_device_talk()
|
||||
!self.id.is_special() && !self.is_device_talk() && !self.is_mailing_list()
|
||||
}
|
||||
|
||||
pub async fn update_param(&mut self, context: &Context) -> Result<(), Error> {
|
||||
@@ -1321,7 +1326,11 @@ pub async fn create_by_msg_id(context: &Context, msg_id: MsgId) -> Result<ChatId
|
||||
msg_id: MsgId::new(0),
|
||||
});
|
||||
}
|
||||
Contact::scaleup_origin_by_id(context, msg.from_id, Origin::CreateChat).await;
|
||||
|
||||
// If the message is from a mailing list, the contacts are not counted as "known"
|
||||
if !chat.is_mailing_list() {
|
||||
Contact::scaleup_origin_by_id(context, msg.from_id, Origin::CreateChat).await;
|
||||
}
|
||||
Ok(chat.id)
|
||||
}
|
||||
|
||||
@@ -2273,6 +2282,7 @@ pub(crate) async fn add_contact_to_chat_ex(
|
||||
"invalid contact_id {} for adding to group",
|
||||
contact_id
|
||||
);
|
||||
ensure!(!chat.is_mailing_list(), "Mailing lists can't be changed");
|
||||
|
||||
if !is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF as u32).await {
|
||||
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
|
||||
@@ -2528,6 +2538,7 @@ pub async fn remove_contact_from_chat(
|
||||
/* we do not check if "contact_id" exists but just delete all records with the id from chats_contacts */
|
||||
/* this allows to delete pending references to deleted contacts. Of course, this should _not_ happen. */
|
||||
if let Ok(chat) = Chat::load_from_db(context, chat_id).await {
|
||||
ensure!(!chat.is_mailing_list(), "Mailing lists can't be changed");
|
||||
if real_group_exists(context, chat_id).await {
|
||||
if !is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF).await {
|
||||
emit_event!(
|
||||
@@ -2654,7 +2665,7 @@ pub async fn set_chat_name(
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
if chat.is_promoted() {
|
||||
if chat.is_promoted() && !chat.is_mailing_list() {
|
||||
msg.viewtype = Viewtype::Text;
|
||||
msg.text = Some(
|
||||
context
|
||||
@@ -2746,7 +2757,7 @@ pub async fn set_chat_profile_image(
|
||||
);
|
||||
}
|
||||
chat.update_param(context).await?;
|
||||
if chat.is_promoted() {
|
||||
if chat.is_promoted() && !chat.is_mailing_list() {
|
||||
msg.id = send_msg(context, chat_id, &mut msg).await?;
|
||||
emit_event!(
|
||||
context,
|
||||
|
||||
Reference in New Issue
Block a user