Skip to content

Commit 7e4d4cf

Browse files
committed
api: Contact::get_all(): Support listing address-contacts
Also test-cover `DC_GCL_ADD_SELF`.
1 parent 0a73c2b commit 7e4d4cf

File tree

6 files changed

+62
-16
lines changed

6 files changed

+62
-16
lines changed

deltachat-ffi/deltachat.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2137,6 +2137,7 @@ uint32_t dc_create_contact (dc_context_t* context, const char*
21372137
#define DC_GCL_DEPRECATED_VERIFIED_ONLY 0x01
21382138

21392139
#define DC_GCL_ADD_SELF 0x02
2140+
#define DC_GCL_ADDRESS 0x04
21402141

21412142

21422143
/**
@@ -2192,11 +2193,13 @@ dc_array_t* dc_import_vcard (dc_context_t* context, const char*
21922193
* Returns known and unblocked contacts.
21932194
*
21942195
* To get information about a single contact, see dc_get_contact().
2196+
* By default, key-contacts are listed.
21952197
*
21962198
* @memberof dc_context_t
21972199
* @param context The context object.
21982200
* @param flags A combination of flags:
2199-
* - if the flag DC_GCL_ADD_SELF is set, SELF is added to the list unless filtered by other parameters
2201+
* - DC_GCL_ADD_SELF: SELF is added to the list unless filtered by other parameters
2202+
* - DC_GCL_ADDRESS: List address-contacts instead of key-contacts.
22002203
* @param query A string to filter the list. Typically used to implement an
22012204
* incremental search. NULL for no filtering.
22022205
* @return An array containing all contact IDs. Must be dc_array_unref()'d

deltachat-jsonrpc/src/api.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,14 @@ impl CommandApi {
15051505
Ok(contacts)
15061506
}
15071507

1508+
/// Returns ids of known and unblocked contacts.
1509+
///
1510+
/// By default, key-contacts are listed.
1511+
///
1512+
/// * `list_flags` - A combination of flags:
1513+
/// - `DC_GCL_ADD_SELF` - Add SELF unless filtered by other parameters.
1514+
/// - `DC_GCL_ADDRESS` - List address-contacts instead of key-contacts.
1515+
/// * `query` - A string to filter the list.
15081516
async fn get_contact_ids(
15091517
&self,
15101518
account_id: u32,
@@ -1516,8 +1524,10 @@ impl CommandApi {
15161524
Ok(contacts.into_iter().map(|c| c.to_u32()).collect())
15171525
}
15181526

1519-
/// Get a list of contacts.
1520-
/// (formerly called getContacts2 in desktop)
1527+
/// Returns known and unblocked contacts.
1528+
///
1529+
/// Formerly called `getContacts2` in Desktop.
1530+
/// See [`Self::get_contact_ids`] for parameters and more info.
15211531
async fn get_contacts(
15221532
&self,
15231533
account_id: u32,

deltachat-rpc-client/src/deltachat_rpc_client/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class ContactFlag(IntEnum):
99
"""Bit flags for get_contacts() method."""
1010

1111
ADD_SELF = 0x02
12+
ADDRESS = 0x04
1213

1314

1415
class ChatlistFlag(IntEnum):

src/constants.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub const DC_GCL_ADD_ALLDONE_HINT: usize = 0x04;
8989
pub const DC_GCL_FOR_FORWARDING: usize = 0x08;
9090

9191
pub const DC_GCL_ADD_SELF: u32 = 0x02;
92+
pub const DC_GCL_ADDRESS: u32 = 0x04;
9293

9394
// unchanged user avatars are resent to the recipients every some days
9495
pub(crate) const DC_RESEND_USER_AVATAR_DAYS: i64 = 14;

src/contact.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::blob::BlobObject;
2424
use crate::chat::{ChatId, ChatIdBlocked, ProtectionStatus};
2525
use crate::color::str_to_color;
2626
use crate::config::Config;
27-
use crate::constants::{Blocked, Chattype, DC_GCL_ADD_SELF};
27+
use crate::constants::{self, Blocked, Chattype};
2828
use crate::context::Context;
2929
use crate::events::EventType;
3030
use crate::key::{
@@ -1063,11 +1063,12 @@ impl Contact {
10631063
/// Returns known and unblocked contacts.
10641064
///
10651065
/// To get information about a single contact, see get_contact().
1066+
/// By default, key-contacts are listed.
10661067
///
1067-
/// `listflags` is a combination of flags:
1068-
/// - if the flag DC_GCL_ADD_SELF is set, SELF is added to the list unless filtered by other parameters
1069-
///
1070-
/// `query` is a string to filter the list.
1068+
/// * `listflags` - A combination of flags:
1069+
/// - `DC_GCL_ADD_SELF` - Add SELF unless filtered by other parameters.
1070+
/// - `DC_GCL_ADDRESS` - List address-contacts instead of key-contacts.
1071+
/// * `query` - A string to filter the list.
10711072
pub async fn get_all(
10721073
context: &Context,
10731074
listflags: u32,
@@ -1080,7 +1081,8 @@ impl Contact {
10801081
.collect::<HashSet<_>>();
10811082
let mut add_self = false;
10821083
let mut ret = Vec::new();
1083-
let flag_add_self = (listflags & DC_GCL_ADD_SELF) != 0;
1084+
let flag_add_self = (listflags & constants::DC_GCL_ADD_SELF) != 0;
1085+
let flag_address = (listflags & constants::DC_GCL_ADDRESS) != 0;
10841086
let minimal_origin = if context.get_config_bool(Config::Bot).await? {
10851087
Origin::Unknown
10861088
} else {
@@ -1093,13 +1095,14 @@ impl Contact {
10931095
.query_map(
10941096
"SELECT c.id, c.addr FROM contacts c
10951097
WHERE c.id>?
1096-
AND c.fingerprint!='' \
1098+
AND (c.fingerprint='')=?
10971099
AND c.origin>=? \
10981100
AND c.blocked=0 \
10991101
AND (iif(c.name='',c.authname,c.name) LIKE ? OR c.addr LIKE ?) \
11001102
ORDER BY c.last_seen DESC, c.id DESC;",
11011103
(
11021104
ContactId::LAST_SPECIAL,
1105+
flag_address,
11031106
minimal_origin,
11041107
&s3str_like_cmd,
11051108
&s3str_like_cmd,
@@ -1149,11 +1152,11 @@ impl Contact {
11491152
.query_map(
11501153
"SELECT id, addr FROM contacts
11511154
WHERE id>?
1152-
AND fingerprint!=''
1155+
AND (fingerprint='')=?
11531156
AND origin>=?
11541157
AND blocked=0
11551158
ORDER BY last_seen DESC, id DESC;",
1156-
(ContactId::LAST_SPECIAL, minimal_origin),
1159+
(ContactId::LAST_SPECIAL, flag_address, minimal_origin),
11571160
|row| {
11581161
let id: ContactId = row.get(0)?;
11591162
let addr: String = row.get(1)?;

src/contact/contact_tests.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ async fn test_get_contacts() -> Result<()> {
6969
let contacts = Contact::get_all(&context.ctx, 0, Some("MyName")).await?;
7070
assert_eq!(contacts.len(), 0);
7171

72+
let claire_id = Contact::create(&context, "someone", "claire@example.org").await?;
73+
let dave_id = Contact::create(&context, "", "dave@example.org").await?;
74+
7275
let id = context.add_or_lookup_contact_id(&alice).await;
7376
assert_ne!(id, ContactId::UNDEFINED);
7477

@@ -101,10 +104,35 @@ async fn test_get_contacts() -> Result<()> {
101104
let contacts = Contact::get_all(&context, 0, Some("MyName")).await?;
102105
assert_eq!(contacts.len(), 0);
103106

104-
// Search by display name (same as manually set name).
105-
let contacts = Contact::get_all(&context.ctx, 0, Some("someone")).await?;
106-
assert_eq!(contacts.len(), 1);
107-
assert_eq!(contacts.first(), Some(&id));
107+
for add_self in [0, constants::DC_GCL_ADD_SELF] {
108+
info!(&context, "add_self={add_self}");
109+
110+
// Search key-contacts by display name (same as manually set name).
111+
let contacts = Contact::get_all(&context.ctx, add_self, Some("someone")).await?;
112+
assert_eq!(contacts, vec![id]);
113+
114+
// Get all key-contacts.
115+
let contacts = Contact::get_all(&context, add_self, None).await?;
116+
match add_self {
117+
0 => assert_eq!(contacts, vec![id]),
118+
_ => assert_eq!(contacts, vec![id, ContactId::SELF]),
119+
}
120+
}
121+
122+
// Search address-contacts by display name.
123+
let contacts = Contact::get_all(&context, constants::DC_GCL_ADDRESS, Some("someone")).await?;
124+
assert_eq!(contacts, vec![claire_id]);
125+
126+
// Get all address-contacts. Newer contacts go first.
127+
let contacts = Contact::get_all(&context, constants::DC_GCL_ADDRESS, None).await?;
128+
assert_eq!(contacts, vec![dave_id, claire_id]);
129+
let contacts = Contact::get_all(
130+
&context,
131+
constants::DC_GCL_ADDRESS | constants::DC_GCL_ADD_SELF,
132+
None,
133+
)
134+
.await?;
135+
assert_eq!(contacts, vec![dave_id, claire_id, ContactId::SELF]);
108136

109137
Ok(())
110138
}

0 commit comments

Comments
 (0)