Commit 259380b7 authored by Frederic Peters's avatar Frederic Peters Committed by Michael Catanzaro

view: sort contacts by most recent event

parent 4ce63fa3
......@@ -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,
......@@ -138,6 +165,29 @@ out:
tp_weak_ref_destroy (wr);
}
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)
{
......@@ -291,10 +341,36 @@ presence_status_changed_cb (FolksIndividual *individual,
update_online (self);
}
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)
{
......
......@@ -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__*/
......@@ -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);
......@@ -625,6 +629,20 @@ contact_in_top (EmpathyRosterView *self,
return FALSE;
}
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);
......
......@@ -208,7 +208,7 @@ roster_window_auth_display (EmpathyRosterWindow *self,
gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_QUESTION);
gtk_widget_set_no_show_all (info_bar, TRUE);
gtk_box_pack_start (GTK_BOX (self->priv->auth_vbox), info_bar, FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (self->priv->auth_vbox), info_bar);
gtk_widget_show (info_bar);
icon_name = tp_account_get_icon_name (account);
......@@ -228,8 +228,8 @@ roster_window_auth_display (EmpathyRosterWindow *self,
g_free (str);
content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
gtk_box_pack_start (GTK_BOX (content_area), image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), image);
gtk_container_add (GTK_CONTAINER (content_area), label);
image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
add_button = gtk_button_new ();
......@@ -248,7 +248,7 @@ roster_window_auth_display (EmpathyRosterWindow *self,
gtk_widget_show (action_grid);
action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
gtk_box_pack_start (GTK_BOX (action_area), action_grid, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (action_area), action_grid);
gtk_grid_attach (GTK_GRID (action_grid), add_button, 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (action_grid), close_button, 1, 0, 1, 1);
......@@ -608,7 +608,7 @@ roster_window_error_create_info_bar (EmpathyRosterWindow *self,
gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), message_type);
gtk_widget_set_no_show_all (info_bar, TRUE);
gtk_box_pack_start (GTK_BOX (self->priv->errors_vbox), info_bar, FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (self->priv->errors_vbox), info_bar);
gtk_widget_show (info_bar);
icon_name = tp_account_get_icon_name (account);
......@@ -623,8 +623,8 @@ roster_window_error_create_info_bar (EmpathyRosterWindow *self,
gtk_widget_show (label);
content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
gtk_box_pack_start (GTK_BOX (content_area), image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), image);
gtk_container_add (GTK_CONTAINER (content_area), label);
action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
gtk_orientable_set_orientation (GTK_ORIENTABLE (action_area),
......@@ -879,7 +879,7 @@ roster_window_setup_balance (EmpathyRosterWindow *self,
/* protocol icon */
image = gtk_image_new ();
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (hbox), image);
g_object_bind_property (account, "icon-name", image, "icon-name",
G_BINDING_SYNC_CREATE);
......@@ -887,14 +887,14 @@ roster_window_setup_balance (EmpathyRosterWindow *self,
label = gtk_label_new ("");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (hbox), label);
g_object_bind_property (account, "display-name", label, "label",
G_BINDING_SYNC_CREATE);
/* balance label */
label = gtk_label_new ("");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (hbox), label);
/* top up button */
uri = tp_connection_get_balance_uri (conn);
......@@ -909,7 +909,7 @@ roster_window_setup_balance (EmpathyRosterWindow *self,
GTK_ICON_SIZE_SMALL_TOOLBAR));
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_widget_set_tooltip_text (button, _("Top up account"));
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (hbox), button);
g_signal_connect_data (button, "clicked",
G_CALLBACK (empathy_url_show),
......@@ -917,7 +917,7 @@ roster_window_setup_balance (EmpathyRosterWindow *self,
0);
}
gtk_box_pack_start (GTK_BOX (self->priv->balance_vbox), hbox, FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (self->priv->balance_vbox), hbox);
gtk_widget_show_all (hbox);
g_object_set_data (G_OBJECT (account), "balance-money-label", label);
......@@ -2305,14 +2305,6 @@ roster_window_most_available_presence_changed_cb (TpAccountManager *manager,
set_notebook_page (self);
}
static void
show_offline_changed_cb (GSettings *settings,
const gchar *key,
EmpathyRosterWindow *self)
{
set_notebook_page (self);
}
static void
empathy_roster_window_init (EmpathyRosterWindow *self)
{
......@@ -2429,9 +2421,7 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
/* Set up presence chooser */
self->priv->presence_chooser = empathy_presence_chooser_new ();
gtk_widget_show (self->priv->presence_chooser);
gtk_box_pack_start (GTK_BOX (self->priv->presence_toolbar),
self->priv->presence_chooser,
TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (self->priv->presence_toolbar), self->priv->presence_chooser);
/* Set up the throbber */
self->priv->throbber = gtk_spinner_new ();
......@@ -2440,9 +2430,7 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
g_signal_connect (self->priv->throbber, "button-press-event",
G_CALLBACK (roster_window_throbber_button_press_event_cb),
self);
gtk_box_pack_start (GTK_BOX (self->priv->presence_toolbar),
self->priv->throbber,
FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (self->priv->presence_toolbar), self->priv->throbber);
self->priv->individual_manager = empathy_individual_manager_dup_singleton ();
......@@ -2506,7 +2494,7 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
self->priv->chat_window = GTK_WIDGET (empathy_chat_window_new ());
gtk_widget_show (GTK_WIDGET (self->priv->chat_window) );
gtk_box_pack_start (GTK_BOX (chat_vbox), self->priv->chat_window, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (chat_vbox), self->priv->chat_window);
/* Enable event handling */
self->priv->call_observer = empathy_call_observer_dup_singleton ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment