[empathy/wip/ui-refresh: 6/6] sort contacts by most recent event
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [empathy/wip/ui-refresh: 6/6] sort contacts by most recent event
- Date: Sun, 9 Oct 2016 13:53:47 +0000 (UTC)
commit ac5be92f345b767b423f70befdb9bfbb199474b4
Author: Frédéric Péters <fpeters 0d be>
Date: Sun May 3 14:35:29 2015 +0200
sort contacts by most recent event
libempathy-gtk/empathy-roster-contact.c | 121 +++++++++++++++++++++++++++++++
libempathy-gtk/empathy-roster-contact.h | 5 ++
libempathy-gtk/empathy-roster-view.c | 22 +++++-
3 files changed, 146 insertions(+), 2 deletions(-)
---
diff --git a/libempathy-gtk/empathy-roster-contact.c b/libempathy-gtk/empathy-roster-contact.c
index df57a87..d98ca13 100644
--- a/libempathy-gtk/empathy-roster-contact.c
+++ b/libempathy-gtk/empathy-roster-contact.c
@@ -18,6 +18,7 @@ enum
PROP_GROUP,
PROP_ONLINE,
PROP_ALIAS,
+ PROP_MOST_RECENT_EVENT,
N_PROPS
};
@@ -33,12 +34,17 @@ static guint signals[LAST_SIGNAL];
struct _EmpathyRosterContactPriv
{
FolksIndividual *individual;
+ EmpathyContact *contact;
gchar *group;
+ TplLogManager *log_manager;
+ TplEvent *most_recent_event;
+
GtkWidget *avatar;
GtkWidget *first_line_alig;
GtkWidget *alias;
GtkWidget *presence_msg;
+ GtkWidget *most_recent_msg;
GtkWidget *presence_icon;
GtkWidget *phone_icon;
@@ -77,6 +83,9 @@ empathy_roster_contact_get_property (GObject *object,
case PROP_ALIAS:
g_value_set_string (value, get_alias (self));
break;
+ case PROP_MOST_RECENT_EVENT:
+ g_value_set_object (value, self->priv->most_recent_event);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -107,6 +116,24 @@ empathy_roster_contact_set_property (GObject *object,
}
}
+gint64
+empathy_roster_contact_get_most_recent_timestamp (EmpathyRosterContact *contact)
+{
+ if (contact->priv->most_recent_event) {
+ return tpl_event_get_timestamp (contact->priv->most_recent_event);
+ }
+ return 0;
+}
+
+static const gchar*
+get_most_recent_message (EmpathyRosterContact *contact)
+{
+ if (contact->priv->most_recent_event) {
+ return tpl_text_event_get_message (TPL_TEXT_EVENT(contact->priv->most_recent_event));
+ }
+ return NULL;
+}
+
static void
avatar_loaded_cb (GObject *source,
GAsyncResult *result,
@@ -139,6 +166,29 @@ out:
}
static void
+update_most_recent_msg (EmpathyRosterContact *self)
+{
+ const gchar* msg = get_most_recent_message (self);
+
+ if (tp_str_empty (msg))
+ {
+ gtk_alignment_set (GTK_ALIGNMENT (self->priv->first_line_alig),
+ 0, 0.5, 1, 1);
+ gtk_widget_hide (self->priv->most_recent_msg);
+ }
+ else
+ {
+ gchar *tmp = g_strdup (msg);
+ if (strchr(tmp, '\n')) strchr(tmp, '\n')[0] = 0;
+ gtk_label_set_text (GTK_LABEL (self->priv->most_recent_msg), tmp);
+ gtk_alignment_set (GTK_ALIGNMENT (self->priv->first_line_alig),
+ 0, 0.75, 1, 1);
+ gtk_misc_set_alignment (GTK_MISC (self->priv->most_recent_msg), 0, 0.25);
+ g_free (tmp);
+ }
+}
+
+static void
update_avatar (EmpathyRosterContact *self)
{
empathy_pixbuf_avatar_from_individual_scaled_async (self->priv->individual,
@@ -292,9 +342,35 @@ presence_status_changed_cb (FolksIndividual *individual,
}
static void
+get_filtered_events (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ EmpathyRosterContact *contact = EMPATHY_ROSTER_CONTACT (user_data);
+ GError *error;
+ GList *events;
+
+ error = NULL;
+ if (!tpl_log_manager_get_filtered_events_finish (contact->priv->log_manager, res, &events, &error))
+ {
+ g_warning ("Unable to get events: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ if (events) {
+ contact->priv->most_recent_event = TPL_EVENT (events->data);
+ g_object_notify (G_OBJECT (contact), "most-recent-event");
+ update_most_recent_msg (contact);
+ }
+
+ out:
+ return;
+}
+
+static void
empathy_roster_contact_constructed (GObject *object)
{
EmpathyRosterContact *self = EMPATHY_ROSTER_CONTACT (object);
+ TplEntity *tpl_entity;
void (*chain_up) (GObject *) =
((GObjectClass *) empathy_roster_contact_parent_class)->constructed;
@@ -303,6 +379,26 @@ empathy_roster_contact_constructed (GObject *object)
g_assert (FOLKS_IS_INDIVIDUAL (self->priv->individual));
+ self->priv->contact = empathy_contact_dup_best_for_action (
+ self->priv->individual,
+ EMPATHY_ACTION_CHAT);
+
+ self->priv->log_manager = tpl_log_manager_dup_singleton ();
+
+ tpl_entity = tpl_entity_new_from_tp_contact (
+ empathy_contact_get_tp_contact (self->priv->contact),
+ TPL_ENTITY_CONTACT);
+ tpl_log_manager_get_filtered_events_async(
+ self->priv->log_manager,
+ empathy_contact_get_account (self->priv->contact),
+ tpl_entity,
+ TPL_EVENT_MASK_TEXT,
+ 1,
+ NULL,
+ NULL,
+ get_filtered_events,
+ object);
+
tp_g_signal_connect_object (self->priv->individual, "notify::avatar",
G_CALLBACK (avatar_changed_cb), self, 0);
tp_g_signal_connect_object (self->priv->individual, "notify::alias",
@@ -343,6 +439,7 @@ empathy_roster_contact_finalize (GObject *object)
g_free (self->priv->group);
g_free (self->priv->event_icon);
+ g_object_unref (self->priv->log_manager);
if (chain_up != NULL)
chain_up (object);
@@ -385,6 +482,12 @@ empathy_roster_contact_class_init (
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (oclass, PROP_ALIAS, spec);
+ spec = g_param_spec_object ("most-recent-event", "Most recent event",
+ "Most recent event",
+ TPL_TYPE_EVENT,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (oclass, PROP_MOST_RECENT_EVENT, spec);
+
g_type_class_add_private (klass, sizeof (EmpathyRosterContactPriv));
}
@@ -445,12 +548,24 @@ empathy_roster_contact_init (EmpathyRosterContact *self)
self->priv->presence_msg = gtk_label_new (NULL);
gtk_label_set_ellipsize (GTK_LABEL (self->priv->presence_msg),
PANGO_ELLIPSIZE_END);
+ /*
gtk_box_pack_start (GTK_BOX (box), self->priv->presence_msg, TRUE, TRUE, 0);
gtk_widget_show (self->priv->presence_msg);
+ */
context = gtk_widget_get_style_context (self->priv->presence_msg);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL);
+ /* Most recent message */
+ self->priv->most_recent_msg = gtk_label_new (NULL);
+ gtk_label_set_ellipsize (GTK_LABEL (self->priv->most_recent_msg),
+ PANGO_ELLIPSIZE_END);
+ gtk_box_pack_start (GTK_BOX (box), self->priv->most_recent_msg, TRUE, TRUE, 0);
+ gtk_widget_show (self->priv->most_recent_msg);
+
+ context = gtk_widget_get_style_context (self->priv->most_recent_msg);
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL);
+
/* Presence icon */
self->priv->presence_icon = gtk_image_new ();
@@ -481,6 +596,12 @@ empathy_roster_contact_get_individual (EmpathyRosterContact *self)
return self->priv->individual;
}
+EmpathyContact *
+empathy_roster_contact_get_contact (EmpathyRosterContact *self)
+{
+ return self->priv->contact;
+}
+
gboolean
empathy_roster_contact_is_online (EmpathyRosterContact *self)
{
diff --git a/libempathy-gtk/empathy-roster-contact.h b/libempathy-gtk/empathy-roster-contact.h
index 6e05959..1dc463a 100644
--- a/libempathy-gtk/empathy-roster-contact.h
+++ b/libempathy-gtk/empathy-roster-contact.h
@@ -3,6 +3,7 @@
#include <gtk/gtk.h>
#include <folks/folks.h>
+#include "empathy-contact.h"
G_BEGIN_DECLS
@@ -52,6 +53,8 @@ GtkWidget * empathy_roster_contact_new (FolksIndividual *individual,
FolksIndividual * empathy_roster_contact_get_individual (EmpathyRosterContact *self);
+EmpathyContact * empathy_roster_contact_get_contact (EmpathyRosterContact *self);
+
const gchar * empathy_roster_contact_get_group (EmpathyRosterContact *self);
gboolean empathy_roster_contact_is_online (EmpathyRosterContact *self);
@@ -62,6 +65,8 @@ void empathy_roster_contact_set_event_icon (EmpathyRosterContact *self,
GdkPixbuf * empathy_roster_contact_get_avatar_pixbuf (
EmpathyRosterContact *self);
+gint64 empathy_roster_contact_get_most_recent_timestamp (EmpathyRosterContact *contact);
+
G_END_DECLS
#endif /* #ifndef __EMPATHY_ROSTER_CONTACT_H__*/
diff --git a/libempathy-gtk/empathy-roster-view.c b/libempathy-gtk/empathy-roster-view.c
index 0dab3ba..e463bd9 100644
--- a/libempathy-gtk/empathy-roster-view.c
+++ b/libempathy-gtk/empathy-roster-view.c
@@ -189,6 +189,10 @@ add_roster_contact (EmpathyRosterView *self,
g_signal_connect (contact, "notify::alias",
G_CALLBACK (roster_contact_changed_cb), self);
+ /* Need to resort if most recent event changed */
+ g_signal_connect (contact, "notify::most-recent-event",
+ G_CALLBACK (roster_contact_changed_cb), self);
+
gtk_widget_show (contact);
gtk_container_add (GTK_CONTAINER (self), contact);
@@ -626,6 +630,20 @@ contact_in_top (EmpathyRosterView *self,
}
static gint
+compare_roster_contacts_by_conversation_time (EmpathyRosterContact *a,
+ EmpathyRosterContact *b)
+{
+ gint64 ts_a, ts_b;
+
+ ts_a = empathy_roster_contact_get_most_recent_timestamp (a);
+ ts_b = empathy_roster_contact_get_most_recent_timestamp (b);
+
+ if (ts_a == ts_b) return 0;
+ if (ts_a > ts_b) return -1;
+ return 1;
+}
+
+static gint
compare_roster_contacts_by_alias (EmpathyRosterContact *a,
EmpathyRosterContact *b)
{
@@ -654,7 +672,7 @@ compare_roster_contacts_no_group (EmpathyRosterView *self,
if (top_a == top_b)
/* Both contacts are in the top of the roster (or not). Sort them
* alphabetically */
- return compare_roster_contacts_by_alias (a, b);
+ return compare_roster_contacts_by_conversation_time (a, b);
else if (top_a)
return -1;
else
@@ -691,7 +709,7 @@ compare_roster_contacts_with_groups (EmpathyRosterView *self,
if (!tp_strdiff (group_a, group_b))
/* Same group, compare the contacts */
- return compare_roster_contacts_by_alias (a, b);
+ return compare_roster_contacts_by_conversation_time (a, b);
/* Sort by group */
return compare_group_names (group_a, group_b);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]