diff --git a/src/calls-best-match.c b/src/calls-best-match.c index caa72ec..7c13526 100644 --- a/src/calls-best-match.c +++ b/src/calls-best-match.c @@ -23,6 +23,7 @@ */ #include "calls-best-match.h" +#include "calls-contacts-provider.h" #include "util.h" #include @@ -34,6 +35,7 @@ struct _CallsBestMatch CallsBestMatchView *view; FolksIndividual *best_match; + gchar *phone_number; gulong display_name_notify_handler_id; gulong avatar_notify_handler_id; }; @@ -43,13 +45,26 @@ G_DEFINE_TYPE (CallsBestMatch, calls_best_match, G_TYPE_OBJECT); enum { PROP_0, - PROP_VIEW, + PROP_PHONE_NUMBER, PROP_NAME, PROP_AVATAR, PROP_LAST_PROP, }; static GParamSpec *props[PROP_LAST_PROP]; +static void +search_view_prepare_cb (FolksSearchView *view, + GAsyncResult *res, + gpointer *user_data) +{ + g_autoptr (GError) error = NULL; + + folks_search_view_prepare_finish (view, res, &error); + + if (error) + g_warning ("Failed to prepare Folks search view: %s", error->message); +} + static void notify_name (CallsBestMatch *self) { @@ -191,9 +206,8 @@ set_property (GObject *object, switch (property_id) { - case PROP_VIEW: - g_set_object (&self->view, - CALLS_BEST_MATCH_VIEW (g_value_get_object (value))); + case PROP_PHONE_NUMBER: + calls_best_match_set_phone_number (self, g_value_get_string (value)); break; default: @@ -202,22 +216,6 @@ set_property (GObject *object, } } - -static void -constructed (GObject *object) -{ - CallsBestMatch *self = CALLS_BEST_MATCH (object); - - - g_signal_connect_swapped (self->view, - "notify::best-match", - G_CALLBACK (update_best_match), - self); - - G_OBJECT_CLASS (calls_best_match_parent_class)->constructed (object); -} - - static void get_property (GObject *object, guint property_id, @@ -228,6 +226,11 @@ get_property (GObject *object, switch (property_id) { + case PROP_PHONE_NUMBER: + g_value_set_string (value, + calls_best_match_get_phone_number (self)); + break; + case PROP_NAME: g_value_set_string (value, calls_best_match_get_name (self)); @@ -251,6 +254,7 @@ dispose (GObject *object) CallsBestMatch *self = CALLS_BEST_MATCH (object); g_clear_object (&self->view); + g_clear_pointer (&self->phone_number, g_free); G_OBJECT_CLASS (calls_best_match_parent_class)->dispose (object); } @@ -262,16 +266,15 @@ calls_best_match_class_init (CallsBestMatchClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = set_property; - object_class->constructed = constructed; object_class->get_property = get_property; object_class->dispose = dispose; - props[PROP_VIEW] = - g_param_spec_object ("view", - "View", - "The CallsBestMatchView to monitor", - CALLS_TYPE_BEST_MATCH_VIEW, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); + props[PROP_PHONE_NUMBER] = + g_param_spec_string ("phone_number", + "Phone number", + "The phone number of the best match", + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); props[PROP_NAME] = g_param_spec_string ("name", @@ -299,15 +302,69 @@ calls_best_match_init (CallsBestMatch *self) CallsBestMatch * -calls_best_match_new (CallsBestMatchView *view) +calls_best_match_new (const gchar *number) { - g_return_val_if_fail (CALLS_IS_BEST_MATCH_VIEW (view), NULL); - return g_object_new (CALLS_TYPE_BEST_MATCH, - "view", view, + "phone_number", number, NULL); } +const gchar * +calls_best_match_get_phone_number (CallsBestMatch *self) +{ + g_return_val_if_fail (CALLS_IS_BEST_MATCH (self), NULL); + + return self->phone_number; +} + +void +calls_best_match_set_phone_number (CallsBestMatch *self, + const gchar *phone_number) +{ + g_autoptr (EPhoneNumber) number = NULL; + g_autoptr (CallsPhoneNumberQuery) query = NULL; + g_autoptr (GError) error = NULL; + + g_return_if_fail (CALLS_IS_BEST_MATCH (self)); + + + if (self->phone_number == phone_number) + return; + + g_clear_pointer (&self->phone_number, g_free); + + // Consider empty string phone numbers as NULL + if (phone_number[0] != '\0') + self->phone_number = g_strdup (phone_number); + + g_clear_object (&self->view); + + if (self->phone_number) { + /* FIXME: parsing the phone number can add the wrong country code if the default region + * for the app isn't set correctly.See: + * https://developer.gnome.org/eds/stable/eds-e-phone-number.html#e-phone-number-get-default-region + */ + number = e_phone_number_from_string (phone_number, NULL, &error); + + if (!number) { + g_warning ("Failed to convert %s to a phone number: %s", phone_number, error->message); + } else { + query = calls_phone_number_query_new (number); + self->view = calls_best_match_view_new (folks_individual_aggregator_dup (), FOLKS_QUERY (query)); + + g_signal_connect_swapped (self->view, + "notify::best-match", + G_CALLBACK (update_best_match), + self); + + folks_search_view_prepare (FOLKS_SEARCH_VIEW (self->view), + (GAsyncReadyCallback) search_view_prepare_cb, + NULL); + } + } + + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_PHONE_NUMBER]); +} const gchar * calls_best_match_get_name (CallsBestMatch *self) diff --git a/src/calls-best-match.h b/src/calls-best-match.h index fa233cd..85ce825 100644 --- a/src/calls-best-match.h +++ b/src/calls-best-match.h @@ -35,9 +35,12 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (CallsBestMatch, calls_best_match, CALLS, BEST_MATCH, GObject); -CallsBestMatch *calls_best_match_new (CallsBestMatchView *view); -const gchar * calls_best_match_get_name (CallsBestMatch *self); -GLoadableIcon *calls_best_match_get_avatar (CallsBestMatch *self); +CallsBestMatch *calls_best_match_new (const gchar *phone_number); +const gchar * calls_best_match_get_phone_number (CallsBestMatch *self); +void calls_best_match_set_phone_number (CallsBestMatch *self, + const gchar *phone_number); +const gchar * calls_best_match_get_name (CallsBestMatch *self); +GLoadableIcon *calls_best_match_get_avatar (CallsBestMatch *self); G_END_DECLS diff --git a/src/calls-contacts-provider.c b/src/calls-contacts-provider.c index c1fbe34..39f3686 100644 --- a/src/calls-contacts-provider.c +++ b/src/calls-contacts-provider.c @@ -76,19 +76,6 @@ folks_individual_has_phone_numbers (FolksIndividual *individual) return !gee_collection_get_is_empty (GEE_COLLECTION (phone_numbers)); } -static void -search_view_prepare_cb (FolksSearchView *view, - GAsyncResult *res, - gpointer *user_data) -{ - g_autoptr (GError) error = NULL; - - folks_search_view_prepare_finish (view, res, &error); - - if (error) - g_warning ("Failed to prepare Folks search view: %s", error->message); -} - static void folks_individual_property_changed_cb (CallsContactsProvider *self, GParamSpec *pspec, @@ -275,10 +262,6 @@ calls_contacts_provider_lookup_phone_number (CallsContactsProvider *self, const gchar *number) { g_autoptr (CallsBestMatch) best_match = NULL; - g_autoptr (GError) error = NULL; - g_autoptr (EPhoneNumber) phone_number = NULL; - g_autoptr (CallsPhoneNumberQuery) query = NULL; - g_autoptr (CallsBestMatchView) view = NULL; g_return_val_if_fail (CALLS_IS_CONTACTS_PROVIDER (self), NULL); @@ -290,29 +273,9 @@ calls_contacts_provider_lookup_phone_number (CallsContactsProvider *self, return g_steal_pointer (&best_match); } - /* FIXME: parsing the phone number can add the wrong country code if the default region - * for the app isn't set correctly. - * See https://developer.gnome.org/eds/stable/eds-e-phone-number.html#e-phone-number-get-default-region - */ - phone_number = e_phone_number_from_string (number, NULL, &error); + best_match = calls_best_match_new (number); - if (!phone_number) { - g_warning ("Failed to convert %s to a phone number: %s", number, error->message); - return NULL; - } - - query = calls_phone_number_query_new (phone_number); - - view = calls_best_match_view_new (self->folks_aggregator, FOLKS_QUERY (query)); - - folks_search_view_prepare (FOLKS_SEARCH_VIEW (view), - (GAsyncReadyCallback) search_view_prepare_cb, - NULL); - - best_match = calls_best_match_new (view); - - if (best_match) - g_hash_table_insert (self->phone_number_best_matches, g_strdup (number), g_object_ref (best_match)); + g_hash_table_insert (self->phone_number_best_matches, g_strdup (number), g_object_ref (best_match)); return g_steal_pointer (&best_match); }