From e1d58706cebecbd2566e024449cdb12944e09ec8 Mon Sep 17 00:00:00 2001 From: link2xt Date: Fri, 18 Sep 2026 17:35:50 +0000 Subject: [PATCH] api!: remove Contact.get_name_n_addr() and related APIs UIs should use display name everywhere and avoid displaying email addresses. BREAKING CHANGE: dc_contact_get_name_n_addr() CFFI is removed BREAKING CHANGE: JSON-RPC contact objects don't have nameAndAddr field anymore --- deltachat-contact-tools/src/lib.rs | 2 +- deltachat-ffi/deltachat.h | 20 +---------------- deltachat-ffi/src/lib.rs | 12 ---------- deltachat-jsonrpc/src/api/types/contact.rs | 2 -- deltachat-repl/src/cmdline.rs | 6 ++--- src/contact.rs | 26 +++------------------- src/contact/contact_tests.rs | 9 -------- 7 files changed, 8 insertions(+), 69 deletions(-) diff --git a/deltachat-contact-tools/src/lib.rs b/deltachat-contact-tools/src/lib.rs index 5282f512d..06fb50e51 100644 --- a/deltachat-contact-tools/src/lib.rs +++ b/deltachat-contact-tools/src/lib.rs @@ -104,7 +104,7 @@ pub fn sanitize_name_and_addr(name: &str, addr: &str) -> (String, String) { let mut name = sanitize_name(name); // If the 'display name' is just the address, remove it: - // Otherwise, the contact would sometimes be shown as "alice@example.com (alice@example.com)" (see `get_name_n_addr()`). + // Otherwise, the contact would sometimes be shown as "alice@example.com (alice@example.com)". // If the display name is empty, DC will just show the address when it needs a display name. if name == addr { name = "".to_string(); diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 5274e6c14..8ca28e7cf 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -4927,7 +4927,6 @@ uint32_t dc_msg_get_saved_msg_id (const dc_msg_t* msg); * By default, these names are equal, * but functions working with contact names * (e.g. dc_contact_get_name(), dc_contact_get_display_name(), - * dc_contact_get_name_n_addr(), * dc_create_contact() or dc_add_address_book()) * only affect the given-name. */ @@ -4977,7 +4976,7 @@ char* dc_contact_get_addr (const dc_contact_t* contact); * The function does not return the contact name as received from the network. * * This name is typically used in a form where the user can edit the name of a contact. - * To get a fine name to display in lists etc., use dc_contact_get_display_name() or dc_contact_get_name_n_addr(). + * To get a fine name to display in lists etc., use dc_contact_get_display_name(). * * @memberof dc_contact_t * @param contact The contact object. @@ -5032,23 +5031,6 @@ char* dc_contact_get_display_name (const dc_contact_t* contact); #define dc_contact_get_first_name dc_contact_get_display_name -/** - * Get a summary of name and address. - * - * The returned string is either "Name (email@domain.com)" or just - * "email@domain.com" if the name is unset. - * - * The summary is typically used when asking the user something about the contact. - * The attached e-mail address makes the question unique, e.g. "Chat with Alan Miller (am@uniquedomain.com)?" - * - * @memberof dc_contact_t - * @param contact The contact object. - * @return A summary string, must be released using dc_str_unref(). - * Never returns NULL. - */ -char* dc_contact_get_name_n_addr (const dc_contact_t* contact); - - /** * Get the contact's profile image. * This is the image set by each remote user on their own diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index d13335977..d2910d665 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -3979,18 +3979,6 @@ pub unsafe extern "C" fn dc_contact_get_display_name( ffi_contact.contact.get_display_name().strdup() } -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dc_contact_get_name_n_addr( - contact: *mut dc_contact_t, -) -> *mut libc::c_char { - if contact.is_null() { - eprintln!("ignoring careless call to dc_contact_get_name_n_addr()"); - return "".strdup(); - } - let ffi_contact = unsafe { &*contact }; - ffi_contact.contact.get_name_n_addr().strdup() -} - #[unsafe(no_mangle)] pub unsafe extern "C" fn dc_contact_get_profile_image( contact: *mut dc_contact_t, diff --git a/deltachat-jsonrpc/src/api/types/contact.rs b/deltachat-jsonrpc/src/api/types/contact.rs index 6f1312250..8dfb4ba2c 100644 --- a/deltachat-jsonrpc/src/api/types/contact.rs +++ b/deltachat-jsonrpc/src/api/types/contact.rs @@ -17,7 +17,6 @@ pub struct ContactObject { id: u32, name: String, profile_image: Option, // BLOBS - name_and_addr: String, is_blocked: bool, /// Is the contact a key contact. @@ -57,7 +56,6 @@ impl ContactObject { id: contact.id.to_u32(), name: contact.get_name().to_owned(), profile_image, //BLOBS - name_and_addr: contact.get_name_n_addr(), is_blocked: contact.is_blocked(), is_key_contact: contact.is_key_contact(), e2ee_avail: contact.e2ee_avail(context).await?, diff --git a/deltachat-repl/src/cmdline.rs b/deltachat-repl/src/cmdline.rs index 50611e3ff..910c95353 100644 --- a/deltachat-repl/src/cmdline.rs +++ b/deltachat-repl/src/cmdline.rs @@ -1113,11 +1113,11 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu let contact_id = ContactId::new(arg1.parse()?); let contact = Contact::get_by_id(&context, contact_id).await?; - let name_n_addr = contact.get_name_n_addr(); + let name = contact.get_display_name(); + let addr = contact.get_addr(); let mut res = format!( - "Contact info for: {}:\nIcon: {}\n", - name_n_addr, + "Contact info for: {name} ({addr}):\nIcon: {}\n", match contact.get_profile_image(&context).await? { Some(image) => image.to_str().unwrap().to_string(), None => "NoIcon".to_string(), diff --git a/src/contact.rs b/src/contact.rs index 9acd67be5..d5d5b9353 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -486,8 +486,8 @@ pub struct Contact { /// The contact ID. pub id: ContactId, - /// Contact name. It is recommended to use `Contact::get_name`, - /// `Contact::get_display_name` or `Contact::get_name_n_addr` to access this field. + /// Contact name. It is recommended to use `Contact::get_name` + /// or `Contact::get_display_name` to access this field. /// May be empty, initially set to `authname`. name: String, @@ -1576,7 +1576,7 @@ WHERE addr=? /// May be an empty string. /// /// This name is typically used in a form where the user can edit the name of a contact. - /// To get a fine name to display in lists etc., use `Contact::get_display_name` or `Contact::get_name_n_addr`. + /// To get a fine name to display in lists etc., use `Contact::get_display_name`. pub fn get_name(&self) -> &str { &self.name } @@ -1596,26 +1596,6 @@ WHERE addr=? &self.addr } - /// Get a summary of name and address. - /// - /// The returned string is either "Name (email@domain.com)" or just - /// "email@domain.com" if the name is unset. - /// - /// The result should only be used locally and never sent over the network - /// as it leaks the local contact name. - /// - /// The summary is typically used when asking the user something about the contact. - /// The attached email address makes the question unique, eg. "Chat with Alan Miller (am@uniquedomain.com)?" - pub fn get_name_n_addr(&self) -> String { - if !self.name.is_empty() { - format!("{} ({})", self.name, self.addr) - } else if !self.authname.is_empty() { - format!("{} ({})", self.authname, self.addr) - } else { - (&self.addr).into() - } - } - /// Get the contact's profile image. /// This is the image set by each remote user on their own /// using set_config(context, "selfavatar", image). diff --git a/src/contact/contact_tests.rs b/src/contact/contact_tests.rs index e73e4b965..c0181cf7d 100644 --- a/src/contact/contact_tests.rs +++ b/src/contact/contact_tests.rs @@ -253,7 +253,6 @@ async fn test_add_or_lookup() { assert_eq!(contact.get_authname(), "bla foo"); assert_eq!(contact.get_display_name(), "Name one"); assert_eq!(contact.get_addr(), "one@eins.org"); - assert_eq!(contact.get_name_n_addr(), "Name one (one@eins.org)"); // modify first added contact let (contact_id_test, sth_modified) = Contact::add_or_lookup( @@ -286,7 +285,6 @@ async fn test_add_or_lookup() { assert_eq!(contact.get_name(), ""); assert_eq!(contact.get_display_name(), "three@drei.sam"); assert_eq!(contact.get_addr(), "three@drei.sam"); - assert_eq!(contact.get_name_n_addr(), "three@drei.sam"); // add name to third contact from incoming message (this becomes authorized name) let (contact_id_test, sth_modified) = Contact::add_or_lookup( @@ -300,7 +298,6 @@ async fn test_add_or_lookup() { assert_eq!(contact_id, contact_id_test); assert_eq!(sth_modified, Modifier::Modified); let contact = Contact::get_by_id(&t, contact_id).await.unwrap(); - assert_eq!(contact.get_name_n_addr(), "m. serious (three@drei.sam)"); assert!(!contact.is_blocked()); // manually edit name of third contact (does not changed authorized name) @@ -316,7 +313,6 @@ async fn test_add_or_lookup() { assert_eq!(sth_modified, Modifier::Modified); let contact = Contact::get_by_id(&t, contact_id).await.unwrap(); assert_eq!(contact.get_authname(), "m. serious"); - assert_eq!(contact.get_name_n_addr(), "schnucki (three@drei.sam)"); assert!(!contact.is_blocked()); // Fourth contact: @@ -334,7 +330,6 @@ async fn test_add_or_lookup() { assert_eq!(contact.get_name(), "Wonderland, Alice"); assert_eq!(contact.get_display_name(), "Wonderland, Alice"); assert_eq!(contact.get_addr(), "alice@w.de"); - assert_eq!(contact.get_name_n_addr(), "Wonderland, Alice (alice@w.de)"); // check SELF let contact = Contact::get_by_id(&t, ContactId::SELF).await.unwrap(); @@ -373,7 +368,6 @@ async fn test_contact_name_changes() -> Result<()> { assert_eq!(contact.get_authname(), ""); assert_eq!(contact.get_name(), ""); assert_eq!(contact.get_display_name(), "f@example.org"); - assert_eq!(contact.get_name_n_addr(), "f@example.org"); let contacts = Contact::get_all(&t, 0, Some("f@example.org")).await?; assert_eq!(contacts.len(), 0); @@ -399,7 +393,6 @@ async fn test_contact_name_changes() -> Result<()> { assert_eq!(contact.get_authname(), "Flobbyfoo"); assert_eq!(contact.get_name(), ""); assert_eq!(contact.get_display_name(), "Flobbyfoo"); - assert_eq!(contact.get_name_n_addr(), "Flobbyfoo (f@example.org)"); let contacts = Contact::get_all(&t, 0, Some("f@example.org")).await?; assert_eq!(contacts.len(), 0); let contacts = Contact::get_all(&t, 0, Some("flobbyfoo")).await?; @@ -429,7 +422,6 @@ async fn test_contact_name_changes() -> Result<()> { assert_eq!(contact.get_authname(), "Foo Flobby"); assert_eq!(contact.get_name(), ""); assert_eq!(contact.get_display_name(), "Foo Flobby"); - assert_eq!(contact.get_name_n_addr(), "Foo Flobby (f@example.org)"); let contacts = Contact::get_all(&t, 0, Some("f@example.org")).await?; assert_eq!(contacts.len(), 0); let contacts = Contact::get_all(&t, 0, Some("flobbyfoo")).await?; @@ -447,7 +439,6 @@ async fn test_contact_name_changes() -> Result<()> { assert_eq!(contact.get_authname(), "Foo Flobby"); assert_eq!(contact.get_name(), "Falk"); assert_eq!(contact.get_display_name(), "Falk"); - assert_eq!(contact.get_name_n_addr(), "Falk (f@example.org)"); let contacts = Contact::get_all(&t, 0, Some("f@example.org")).await?; assert_eq!(contacts.len(), 0); let contacts = Contact::get_all(&t, 0, Some("falk")).await?;