mirror of
https://github.com/chatmail/core.git
synced 2026-04-25 17:36:30 +03:00
api: Contact::get_all(): Support listing address-contacts
Also test-cover `DC_GCL_ADD_SELF`.
This commit is contained in:
@@ -2137,6 +2137,7 @@ uint32_t dc_create_contact (dc_context_t* context, const char*
|
||||
#define DC_GCL_DEPRECATED_VERIFIED_ONLY 0x01
|
||||
|
||||
#define DC_GCL_ADD_SELF 0x02
|
||||
#define DC_GCL_ADDRESS 0x04
|
||||
|
||||
|
||||
/**
|
||||
@@ -2192,11 +2193,13 @@ dc_array_t* dc_import_vcard (dc_context_t* context, const char*
|
||||
* Returns known and unblocked contacts.
|
||||
*
|
||||
* To get information about a single contact, see dc_get_contact().
|
||||
* By default, key-contacts are listed.
|
||||
*
|
||||
* @memberof dc_context_t
|
||||
* @param context The context object.
|
||||
* @param flags A combination of flags:
|
||||
* - if the flag DC_GCL_ADD_SELF is set, SELF is added to the list unless filtered by other parameters
|
||||
* - DC_GCL_ADD_SELF: SELF is added to the list unless filtered by other parameters
|
||||
* - DC_GCL_ADDRESS: List address-contacts instead of key-contacts.
|
||||
* @param query A string to filter the list. Typically used to implement an
|
||||
* incremental search. NULL for no filtering.
|
||||
* @return An array containing all contact IDs. Must be dc_array_unref()'d
|
||||
|
||||
@@ -1505,6 +1505,14 @@ impl CommandApi {
|
||||
Ok(contacts)
|
||||
}
|
||||
|
||||
/// Returns ids of known and unblocked contacts.
|
||||
///
|
||||
/// By default, key-contacts are listed.
|
||||
///
|
||||
/// * `list_flags` - A combination of flags:
|
||||
/// - `DC_GCL_ADD_SELF` - Add SELF unless filtered by other parameters.
|
||||
/// - `DC_GCL_ADDRESS` - List address-contacts instead of key-contacts.
|
||||
/// * `query` - A string to filter the list.
|
||||
async fn get_contact_ids(
|
||||
&self,
|
||||
account_id: u32,
|
||||
@@ -1516,8 +1524,10 @@ impl CommandApi {
|
||||
Ok(contacts.into_iter().map(|c| c.to_u32()).collect())
|
||||
}
|
||||
|
||||
/// Get a list of contacts.
|
||||
/// (formerly called getContacts2 in desktop)
|
||||
/// Returns known and unblocked contacts.
|
||||
///
|
||||
/// Formerly called `getContacts2` in Desktop.
|
||||
/// See [`Self::get_contact_ids`] for parameters and more info.
|
||||
async fn get_contacts(
|
||||
&self,
|
||||
account_id: u32,
|
||||
|
||||
@@ -9,6 +9,7 @@ class ContactFlag(IntEnum):
|
||||
"""Bit flags for get_contacts() method."""
|
||||
|
||||
ADD_SELF = 0x02
|
||||
ADDRESS = 0x04
|
||||
|
||||
|
||||
class ChatlistFlag(IntEnum):
|
||||
|
||||
@@ -89,6 +89,7 @@ pub const DC_GCL_ADD_ALLDONE_HINT: usize = 0x04;
|
||||
pub const DC_GCL_FOR_FORWARDING: usize = 0x08;
|
||||
|
||||
pub const DC_GCL_ADD_SELF: u32 = 0x02;
|
||||
pub const DC_GCL_ADDRESS: u32 = 0x04;
|
||||
|
||||
// unchanged user avatars are resent to the recipients every some days
|
||||
pub(crate) const DC_RESEND_USER_AVATAR_DAYS: i64 = 14;
|
||||
|
||||
@@ -24,7 +24,7 @@ use crate::blob::BlobObject;
|
||||
use crate::chat::{ChatId, ChatIdBlocked, ProtectionStatus};
|
||||
use crate::color::str_to_color;
|
||||
use crate::config::Config;
|
||||
use crate::constants::{Blocked, Chattype, DC_GCL_ADD_SELF};
|
||||
use crate::constants::{self, Blocked, Chattype};
|
||||
use crate::context::Context;
|
||||
use crate::events::EventType;
|
||||
use crate::key::{
|
||||
@@ -1063,11 +1063,12 @@ impl Contact {
|
||||
/// Returns known and unblocked contacts.
|
||||
///
|
||||
/// To get information about a single contact, see get_contact().
|
||||
/// By default, key-contacts are listed.
|
||||
///
|
||||
/// `listflags` is a combination of flags:
|
||||
/// - if the flag DC_GCL_ADD_SELF is set, SELF is added to the list unless filtered by other parameters
|
||||
///
|
||||
/// `query` is a string to filter the list.
|
||||
/// * `listflags` - A combination of flags:
|
||||
/// - `DC_GCL_ADD_SELF` - Add SELF unless filtered by other parameters.
|
||||
/// - `DC_GCL_ADDRESS` - List address-contacts instead of key-contacts.
|
||||
/// * `query` - A string to filter the list.
|
||||
pub async fn get_all(
|
||||
context: &Context,
|
||||
listflags: u32,
|
||||
@@ -1080,7 +1081,8 @@ impl Contact {
|
||||
.collect::<HashSet<_>>();
|
||||
let mut add_self = false;
|
||||
let mut ret = Vec::new();
|
||||
let flag_add_self = (listflags & DC_GCL_ADD_SELF) != 0;
|
||||
let flag_add_self = (listflags & constants::DC_GCL_ADD_SELF) != 0;
|
||||
let flag_address = (listflags & constants::DC_GCL_ADDRESS) != 0;
|
||||
let minimal_origin = if context.get_config_bool(Config::Bot).await? {
|
||||
Origin::Unknown
|
||||
} else {
|
||||
@@ -1093,13 +1095,14 @@ impl Contact {
|
||||
.query_map(
|
||||
"SELECT c.id, c.addr FROM contacts c
|
||||
WHERE c.id>?
|
||||
AND c.fingerprint!='' \
|
||||
AND (c.fingerprint='')=?
|
||||
AND c.origin>=? \
|
||||
AND c.blocked=0 \
|
||||
AND (iif(c.name='',c.authname,c.name) LIKE ? OR c.addr LIKE ?) \
|
||||
ORDER BY c.last_seen DESC, c.id DESC;",
|
||||
(
|
||||
ContactId::LAST_SPECIAL,
|
||||
flag_address,
|
||||
minimal_origin,
|
||||
&s3str_like_cmd,
|
||||
&s3str_like_cmd,
|
||||
@@ -1149,11 +1152,11 @@ impl Contact {
|
||||
.query_map(
|
||||
"SELECT id, addr FROM contacts
|
||||
WHERE id>?
|
||||
AND fingerprint!=''
|
||||
AND (fingerprint='')=?
|
||||
AND origin>=?
|
||||
AND blocked=0
|
||||
ORDER BY last_seen DESC, id DESC;",
|
||||
(ContactId::LAST_SPECIAL, minimal_origin),
|
||||
(ContactId::LAST_SPECIAL, flag_address, minimal_origin),
|
||||
|row| {
|
||||
let id: ContactId = row.get(0)?;
|
||||
let addr: String = row.get(1)?;
|
||||
|
||||
@@ -69,6 +69,9 @@ async fn test_get_contacts() -> Result<()> {
|
||||
let contacts = Contact::get_all(&context.ctx, 0, Some("MyName")).await?;
|
||||
assert_eq!(contacts.len(), 0);
|
||||
|
||||
let claire_id = Contact::create(&context, "someone", "claire@example.org").await?;
|
||||
let dave_id = Contact::create(&context, "", "dave@example.org").await?;
|
||||
|
||||
let id = context.add_or_lookup_contact_id(&alice).await;
|
||||
assert_ne!(id, ContactId::UNDEFINED);
|
||||
|
||||
@@ -101,10 +104,35 @@ async fn test_get_contacts() -> Result<()> {
|
||||
let contacts = Contact::get_all(&context, 0, Some("MyName")).await?;
|
||||
assert_eq!(contacts.len(), 0);
|
||||
|
||||
// Search by display name (same as manually set name).
|
||||
let contacts = Contact::get_all(&context.ctx, 0, Some("someone")).await?;
|
||||
assert_eq!(contacts.len(), 1);
|
||||
assert_eq!(contacts.first(), Some(&id));
|
||||
for add_self in [0, constants::DC_GCL_ADD_SELF] {
|
||||
info!(&context, "add_self={add_self}");
|
||||
|
||||
// Search key-contacts by display name (same as manually set name).
|
||||
let contacts = Contact::get_all(&context.ctx, add_self, Some("someone")).await?;
|
||||
assert_eq!(contacts, vec![id]);
|
||||
|
||||
// Get all key-contacts.
|
||||
let contacts = Contact::get_all(&context, add_self, None).await?;
|
||||
match add_self {
|
||||
0 => assert_eq!(contacts, vec![id]),
|
||||
_ => assert_eq!(contacts, vec![id, ContactId::SELF]),
|
||||
}
|
||||
}
|
||||
|
||||
// Search address-contacts by display name.
|
||||
let contacts = Contact::get_all(&context, constants::DC_GCL_ADDRESS, Some("someone")).await?;
|
||||
assert_eq!(contacts, vec![claire_id]);
|
||||
|
||||
// Get all address-contacts. Newer contacts go first.
|
||||
let contacts = Contact::get_all(&context, constants::DC_GCL_ADDRESS, None).await?;
|
||||
assert_eq!(contacts, vec![dave_id, claire_id]);
|
||||
let contacts = Contact::get_all(
|
||||
&context,
|
||||
constants::DC_GCL_ADDRESS | constants::DC_GCL_ADD_SELF,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(contacts, vec![dave_id, claire_id, ContactId::SELF]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user