diff --git a/src/chat.rs b/src/chat.rs index 6e58d1d2d..405772c2f 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -32,6 +32,7 @@ use crate::receive_imf::ReceivedMsg; use crate::scheduler::InterruptInfo; use crate::smtp::send_msg_to_smtp; use crate::stock_str; +use crate::stock_str::ByContact; use crate::tools::{ create_id, create_outgoing_rfc724_mid, create_smeared_timestamp, create_smeared_timestamps, get_abs_path, gm2local_offset, improve_single_line_input, time, IsNoneOrEmpty, @@ -2744,7 +2745,7 @@ pub(crate) async fn add_contact_to_chat_ex( msg.viewtype = Viewtype::Text; msg.text = - Some(stock_str::msg_add_member(context, contact.get_addr(), ContactId::SELF).await); + Some(stock_str::msg_add_member(context, contact.get_addr(), ByContact::SelfName).await); msg.param.set_cmd(SystemMessage::MemberAddedToGroup); msg.param.set(Param::Arg, contact.get_addr()); msg.param.set_int(Param::Arg2, from_handshake.into()); @@ -2877,13 +2878,13 @@ pub async fn remove_contact_from_chat( if contact.id == ContactId::SELF { set_group_explicitly_left(context, &chat.grpid).await?; msg.text = - Some(stock_str::msg_group_left(context, ContactId::SELF).await); + Some(stock_str::msg_group_left(context, ByContact::SelfName).await); } else { msg.text = Some( stock_str::msg_del_member( context, contact.get_addr(), - ContactId::SELF, + ByContact::SelfName, ) .await, ); @@ -2976,7 +2977,8 @@ pub async fn set_chat_name(context: &Context, chat_id: ChatId, new_name: &str) - if chat.is_promoted() && !chat.is_mailing_list() && chat.typ != Chattype::Broadcast { msg.viewtype = Viewtype::Text; msg.text = Some( - stock_str::msg_grp_name(context, &chat.name, &new_name, ContactId::SELF).await, + stock_str::msg_grp_name(context, &chat.name, &new_name, ByContact::SelfName) + .await, ); msg.param.set_cmd(SystemMessage::GroupNameChanged); if !chat.name.is_empty() { @@ -3026,14 +3028,14 @@ pub async fn set_chat_profile_image( if new_image.as_ref().is_empty() { chat.param.remove(Param::ProfileImage); msg.param.remove(Param::Arg); - msg.text = Some(stock_str::msg_grp_img_deleted(context, ContactId::SELF).await); + msg.text = Some(stock_str::msg_grp_img_deleted(context, ByContact::SelfName).await); } else { let mut image_blob = BlobObject::new_from_path(context, Path::new(new_image.as_ref())).await?; image_blob.recode_to_avatar_size(context).await?; chat.param.set(Param::ProfileImage, image_blob.as_name()); msg.param.set(Param::Arg, image_blob.as_name()); - msg.text = Some(stock_str::msg_grp_img_changed(context, ContactId::SELF).await); + msg.text = Some(stock_str::msg_grp_img_changed(context, ByContact::SelfName).await); } chat.update_param(context).await?; if chat.is_promoted() && !chat.is_mailing_list() { diff --git a/src/config.rs b/src/config.rs index e516c0b27..fa070062b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -282,6 +282,21 @@ impl Context { } } + pub async fn get_config_self_name(&self) -> String { + match self + .get_config(Config::Displayname) + .await + .unwrap_or_default() + { + Some(name) => name, + None => self + .get_config(Config::Addr) + .await + .unwrap_or_default() + .unwrap_or_default(), + } + } + /// Set the given config key. /// If `None` is passed as a value the value is cleared and set to the default if there is one. pub async fn set_config(&self, key: Config, value: Option<&str>) -> Result<()> { diff --git a/src/receive_imf.rs b/src/receive_imf.rs index d1fe9c18b..a2df684fc 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -37,6 +37,7 @@ use crate::reaction::{set_msg_reaction, Reaction}; use crate::securejoin::{self, handle_securejoin_handshake, observe_securejoin_on_other_device}; use crate::sql; use crate::stock_str; +use crate::stock_str::ByContact; use crate::tools::{create_id, extract_grpid_from_rfc724_mid, smeared_time}; /// This is the struct that is returned after receiving one email (aka MIME message). @@ -1601,9 +1602,16 @@ async fn apply_group_changes( match removed_id { Some(contact_id) => { better_msg = if contact_id == from_id { - Some(stock_str::msg_group_left(context, from_id).await) + Some(stock_str::msg_group_left(context, ByContact::YouOrName(from_id)).await) } else { - Some(stock_str::msg_del_member(context, &removed_addr, from_id).await) + Some( + stock_str::msg_del_member( + context, + &removed_addr, + ByContact::YouOrName(from_id), + ) + .await, + ) }; } None => warn!(context, "removed {:?} has no contact_id", removed_addr), @@ -1614,7 +1622,10 @@ async fn apply_group_changes( .get_header(HeaderDef::ChatGroupMemberAdded) .cloned() { - better_msg = Some(stock_str::msg_add_member(context, &added_member, from_id).await); + better_msg = Some( + stock_str::msg_add_member(context, &added_member, ByContact::YouOrName(from_id)) + .await, + ); recreate_member_list = true; } else if let Some(old_name) = mime_parser.get_header(HeaderDef::ChatGroupNameChanged) { if let Some(grpname) = mime_parser @@ -1636,8 +1647,15 @@ async fn apply_group_changes( send_event_chat_modified = true; } - better_msg = - Some(stock_str::msg_grp_name(context, old_name, grpname, from_id).await); + better_msg = Some( + stock_str::msg_grp_name( + context, + old_name, + grpname, + ByContact::YouOrName(from_id), + ) + .await, + ); } } else if let Some(value) = mime_parser.get_header(HeaderDef::ChatContent) { if value == "group-avatar-changed" { @@ -1645,12 +1663,14 @@ async fn apply_group_changes( // this is just an explicit message containing the group-avatar, // apart from that, the group-avatar is send along with various other messages better_msg = match avatar_action { - AvatarAction::Delete => { - Some(stock_str::msg_grp_img_deleted(context, from_id).await) - } - AvatarAction::Change(_) => { - Some(stock_str::msg_grp_img_changed(context, from_id).await) - } + AvatarAction::Delete => Some( + stock_str::msg_grp_img_deleted(context, ByContact::YouOrName(from_id)) + .await, + ), + AvatarAction::Change(_) => Some( + stock_str::msg_grp_img_changed(context, ByContact::YouOrName(from_id)) + .await, + ), }; } } diff --git a/src/stock_str.rs b/src/stock_str.rs index f1b7894db..5db005e4d 100644 --- a/src/stock_str.rs +++ b/src/stock_str.rs @@ -404,6 +404,11 @@ pub enum StockMessage { ProtectionDisabledBy = 161, } +pub(crate) enum ByContact { + YouOrName(ContactId), + SelfName, +} + impl StockMessage { /// Default untranslated strings for stock messages. /// @@ -553,29 +558,45 @@ pub(crate) async fn msg_grp_name( context: &Context, from_group: impl AsRef, to_group: impl AsRef, - by_contact: ContactId, + by_contact: ByContact, ) -> String { - if by_contact == ContactId::SELF { - translated(context, StockMessage::MsgYouChangedGrpName) + match by_contact { + ByContact::YouOrName(by_contact) => { + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouChangedGrpName) + .await + .replace1(from_group) + .replace2(to_group) + } else { + translated(context, StockMessage::MsgGrpNameChangedBy) + .await + .replace1(from_group) + .replace2(to_group) + .replace3(by_contact.get_stock_name(context).await) + } + } + ByContact::SelfName => translated(context, StockMessage::MsgGrpNameChangedBy) .await .replace1(from_group) .replace2(to_group) - } else { - translated(context, StockMessage::MsgGrpNameChangedBy) - .await - .replace1(from_group) - .replace2(to_group) - .replace3(by_contact.get_stock_name(context).await) + .replace3(context.get_config_self_name().await), } } -pub(crate) async fn msg_grp_img_changed(context: &Context, by_contact: ContactId) -> String { - if by_contact == ContactId::SELF { - translated(context, StockMessage::MsgYouChangedGrpImg).await - } else { - translated(context, StockMessage::MsgGrpImgChangedBy) +pub(crate) async fn msg_grp_img_changed(context: &Context, by_contact: ByContact) -> String { + match by_contact { + ByContact::YouOrName(by_contact) => { + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouChangedGrpImg).await + } else { + translated(context, StockMessage::MsgGrpImgChangedBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } + } + ByContact::SelfName => translated(context, StockMessage::MsgGrpImgChangedBy) .await - .replace1(by_contact.get_stock_name(context).await) + .replace1(context.get_config_self_name().await), } } @@ -586,7 +607,7 @@ pub(crate) async fn msg_grp_img_changed(context: &Context, by_contact: ContactId pub(crate) async fn msg_add_member( context: &Context, added_member_addr: impl AsRef, - by_contact: ContactId, + by_contact: ByContact, ) -> String { let addr = added_member_addr.as_ref(); let who = match Contact::lookup_id_by_addr(context, addr, Origin::Unknown).await { @@ -596,15 +617,23 @@ pub(crate) async fn msg_add_member( .unwrap_or_else(|_| addr.to_string()), _ => addr.to_string(), }; - if by_contact == ContactId::SELF { - translated(context, StockMessage::MsgYouAddMember) + match by_contact { + ByContact::YouOrName(by_contact) => { + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouAddMember) + .await + .replace1(who) + } else { + translated(context, StockMessage::MsgAddMemberBy) + .await + .replace1(who) + .replace2(by_contact.get_stock_name(context).await) + } + } + ByContact::SelfName => translated(context, StockMessage::MsgAddMemberBy) .await .replace1(who) - } else { - translated(context, StockMessage::MsgAddMemberBy) - .await - .replace1(who) - .replace2(by_contact.get_stock_name(context).await) + .replace2(context.get_config_self_name().await), } } @@ -615,7 +644,7 @@ pub(crate) async fn msg_add_member( pub(crate) async fn msg_del_member( context: &Context, removed_member_addr: impl AsRef, - by_contact: ContactId, + by_contact: ByContact, ) -> String { let addr = removed_member_addr.as_ref(); let who = match Contact::lookup_id_by_addr(context, addr, Origin::Unknown).await { @@ -625,26 +654,41 @@ pub(crate) async fn msg_del_member( .unwrap_or_else(|_| addr.to_string()), _ => addr.to_string(), }; - if by_contact == ContactId::SELF { - translated(context, StockMessage::MsgYouDelMember) + match by_contact { + ByContact::YouOrName(by_contact) => { + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouDelMember) + .await + .replace1(who) + } else { + translated(context, StockMessage::MsgDelMemberBy) + .await + .replace1(who) + .replace2(by_contact.get_stock_name(context).await) + } + } + ByContact::SelfName => translated(context, StockMessage::MsgDelMemberBy) .await .replace1(who) - } else { - translated(context, StockMessage::MsgDelMemberBy) - .await - .replace1(who) - .replace2(by_contact.get_stock_name(context).await) + .replace2(context.get_config_self_name().await), } } /// Stock string: `Group left.`. -pub(crate) async fn msg_group_left(context: &Context, by_contact: ContactId) -> String { - if by_contact == ContactId::SELF { - translated(context, StockMessage::MsgYouLeftGroup).await - } else { - translated(context, StockMessage::MsgGroupLeftBy) +pub(crate) async fn msg_group_left(context: &Context, by_contact: ByContact) -> String { + match by_contact { + ByContact::YouOrName(by_contact) => { + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouLeftGroup).await + } else { + translated(context, StockMessage::MsgGroupLeftBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } + } + ByContact::SelfName => translated(context, StockMessage::MsgGroupLeftBy) .await - .replace1(by_contact.get_stock_name(context).await) + .replace1(context.get_config_self_name().await), } } @@ -691,13 +735,20 @@ pub(crate) async fn read_rcpt_mail_body(context: &Context, message: impl AsRef String { - if by_contact == ContactId::SELF { - translated(context, StockMessage::MsgYouDeletedGrpImg).await - } else { - translated(context, StockMessage::MsgGrpImgDeletedBy) +pub(crate) async fn msg_grp_img_deleted(context: &Context, by_contact: ByContact) -> String { + match by_contact { + ByContact::YouOrName(by_contact) => { + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouDeletedGrpImg).await + } else { + translated(context, StockMessage::MsgGrpImgDeletedBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } + } + ByContact::SelfName => translated(context, StockMessage::MsgGrpImgDeletedBy) .await - .replace1(by_contact.get_stock_name(context).await) + .replace1(context.get_config_self_name().await), } } @@ -1394,7 +1445,12 @@ mod tests { async fn test_stock_system_msg_add_member_by_me() { let t = TestContext::new().await; assert_eq!( - msg_add_member(&t, "alice@example.org", ContactId::SELF).await, + msg_add_member( + &t, + "alice@example.org", + ByContact::YouOrName(ContactId::SELF) + ) + .await, "You added member alice@example.org." ) } @@ -1406,7 +1462,12 @@ mod tests { .await .expect("failed to create contact"); assert_eq!( - msg_add_member(&t, "alice@example.org", ContactId::SELF).await, + msg_add_member( + &t, + "alice@example.org", + ByContact::YouOrName(ContactId::SELF) + ) + .await, "You added member Alice (alice@example.org)." ); } @@ -1423,7 +1484,7 @@ mod tests { .expect("failed to create bob") }; assert_eq!( - msg_add_member(&t, "alice@example.org", contact_id,).await, + msg_add_member(&t, "alice@example.org", ByContact::YouOrName(contact_id)).await, "Member Alice (alice@example.org) added by Bob (bob@example.com)." ); }