From 0bd6d7f2a594dad0062bdbd99e6c722db81f66df Mon Sep 17 00:00:00 2001 From: Evangelos Ribeiro Tzaras Date: Mon, 5 Apr 2021 04:55:55 +0200 Subject: [PATCH] best-match: Lookup contact if country code changed Closes #217 --- src/calls-best-match.c | 42 +++++++++++++++++++---- src/calls-contacts-provider.c | 64 +++++++++++++++++++++++++++++++++++ src/calls-manager.c | 3 ++ 3 files changed, 103 insertions(+), 6 deletions(-) diff --git a/src/calls-best-match.c b/src/calls-best-match.c index 2aa8385..3430fae 100644 --- a/src/calls-best-match.c +++ b/src/calls-best-match.c @@ -38,6 +38,8 @@ struct _CallsBestMatch FolksSearchView *view; FolksIndividual *best_match; gchar *phone_number; + gchar *country_code; + gboolean had_country_code_last_time; }; G_DEFINE_TYPE (CallsBestMatch, calls_best_match, G_TYPE_OBJECT); @@ -49,6 +51,7 @@ enum { PROP_NAME, PROP_AVATAR, PROP_HAS_INDIVIDUAL, + PROP_COUNTRY_CODE, PROP_LAST_PROP, }; static GParamSpec *props[PROP_LAST_PROP]; @@ -128,6 +131,7 @@ set_property (GObject *object, GParamSpec *pspec) { CallsBestMatch *self = CALLS_BEST_MATCH (object); + const gchar *country_code; switch (property_id) { @@ -135,6 +139,16 @@ set_property (GObject *object, calls_best_match_set_phone_number (self, g_value_get_string (value)); break; + case PROP_COUNTRY_CODE: + country_code = g_value_get_string (value); + if (country_code) { + g_autofree gchar *number = g_strdup (self->phone_number); + g_free (self->country_code); + self->country_code = g_strdup (country_code); + calls_best_match_set_phone_number (self, number); + } + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -161,6 +175,10 @@ get_property (GObject *object, calls_best_match_get_phone_number (self)); break; + case PROP_COUNTRY_CODE: + g_value_set_string (value, self->country_code); + break; + case PROP_NAME: g_value_set_string (value, calls_best_match_get_name (self)); @@ -185,6 +203,7 @@ dispose (GObject *object) g_clear_object (&self->view); g_clear_pointer (&self->phone_number, g_free); + g_clear_pointer (&self->country_code, g_free); if (self->best_match) { g_signal_handlers_disconnect_by_data (self->best_match, self); @@ -218,6 +237,13 @@ calls_best_match_class_init (CallsBestMatchClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); + props[PROP_COUNTRY_CODE] = + g_param_spec_string ("country-code", + "Country code", + "The country code used for matching", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + props[PROP_NAME] = g_param_spec_string ("name", "Name", @@ -240,6 +266,9 @@ calls_best_match_class_init (CallsBestMatchClass *klass) static void calls_best_match_init (CallsBestMatch *self) { + g_object_bind_property (calls_manager_get_default (), "country-code", + self, "country-code", + G_BINDING_SYNC_CREATE); } @@ -274,14 +303,18 @@ calls_best_match_set_phone_number (CallsBestMatch *self, g_autoptr (EPhoneNumber) number = NULL; g_autoptr (CallsPhoneNumberQuery) query = NULL; g_autoptr (GError) error = NULL; - g_autofree gchar *country_code = NULL; + gboolean have_country_code_now = FALSE; g_return_if_fail (CALLS_IS_BEST_MATCH (self)); + have_country_code_now = !!self->country_code; - if (self->phone_number == phone_number) + if (self->phone_number == phone_number && + self->had_country_code_last_time == have_country_code_now) return; + self->had_country_code_last_time = have_country_code_now; + g_clear_pointer (&self->phone_number, g_free); // Consider empty string phone numbers as NULL @@ -291,10 +324,7 @@ calls_best_match_set_phone_number (CallsBestMatch *self, g_clear_object (&self->view); if (self->phone_number) { - g_object_get (calls_manager_get_default (), - "country-code", &country_code, - NULL); - number = e_phone_number_from_string (phone_number, country_code, &error); + number = e_phone_number_from_string (phone_number, self->country_code, &error); if (!number) { g_warning ("Failed to convert %s to a phone number: %s", phone_number, error->message); diff --git a/src/calls-contacts-provider.c b/src/calls-contacts-provider.c index ce50adf..4ee9820 100644 --- a/src/calls-contacts-provider.c +++ b/src/calls-contacts-provider.c @@ -50,10 +50,18 @@ struct _CallsContactsProvider FolksIndividualAggregator *folks_aggregator; GHashTable *phone_number_best_matches; + gchar *country_code; }; G_DEFINE_TYPE (CallsContactsProvider, calls_contacts_provider, G_TYPE_OBJECT) +enum { + PROP_0, + PROP_COUNTRY_CODE, + PROP_LAST_PROP +}; +static GParamSpec *props[PROP_LAST_PROP]; + enum { SIGNAL_ADDED, SIGNAL_REMOVED, @@ -160,11 +168,52 @@ folks_prepare_cb (GObject *obj, g_warning ("Failed to load Folks contacts: %s", error->message); } +static void +calls_contacts_provider_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + CallsContactsProvider *self = CALLS_CONTACTS_PROVIDER (object); + + switch (property_id) { + case PROP_COUNTRY_CODE: + g_free (self->country_code); + self->country_code = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +calls_contacts_provider_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + CallsContactsProvider *self = CALLS_CONTACTS_PROVIDER (object); + + switch (property_id) { + case PROP_COUNTRY_CODE: + g_value_set_string (value, self->country_code); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + static void calls_contacts_provider_finalize (GObject *object) { CallsContactsProvider *self = CALLS_CONTACTS_PROVIDER (object); + g_clear_object (&self->country_code); g_clear_object (&self->folks_aggregator); g_clear_pointer (&self->phone_number_best_matches, g_hash_table_unref); @@ -177,6 +226,8 @@ calls_contacts_provider_class_init (CallsContactsProviderClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->get_property = calls_contacts_provider_get_property; + object_class->set_property = calls_contacts_provider_set_property; object_class->finalize = calls_contacts_provider_finalize; signals[SIGNAL_ADDED] = @@ -198,6 +249,14 @@ calls_contacts_provider_class_init (CallsContactsProviderClass *klass) G_TYPE_NONE, 1, FOLKS_TYPE_INDIVIDUAL); + + props[PROP_COUNTRY_CODE] = g_param_spec_string ("country-code", + "country code", + "The default country code to use", + NULL, + G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, PROP_LAST_PROP, props); } @@ -262,6 +321,7 @@ calls_contacts_provider_lookup_phone_number (CallsContactsProvider *self, const gchar *number) { g_autoptr (CallsBestMatch) best_match = NULL; + g_autofree gchar *country_code = NULL; g_return_val_if_fail (CALLS_IS_CONTACTS_PROVIDER (self), NULL); @@ -270,6 +330,10 @@ calls_contacts_provider_lookup_phone_number (CallsContactsProvider *self, if (best_match) { g_object_ref (best_match); + g_object_get (best_match, "country-code", &country_code, NULL); + if (g_strcmp0 (country_code, self->country_code) != 0) + calls_best_match_set_phone_number (best_match, number); + return g_steal_pointer (&best_match); } diff --git a/src/calls-manager.c b/src/calls-manager.c index 7a741a6..b0c1af1 100644 --- a/src/calls-manager.c +++ b/src/calls-manager.c @@ -472,6 +472,9 @@ calls_manager_init (CallsManager *self) // Load the contacts provider self->contacts_provider = calls_contacts_provider_new (); + g_object_bind_property (self, "country-code", + self->contacts_provider, "country-code", + G_BINDING_DEFAULT); }