Skip to content

Commit

Permalink
Handle presence received before roster
Browse files Browse the repository at this point in the history
Presence of contact not found in roster are filtered out.
But sometimes roster is received after a first few presences.

We choose to store presences until we receive roster and then process
this presences.

Fixes profanity-im#1050
  • Loading branch information
paulfariello committed Apr 17, 2019
1 parent 02d0f7f commit 448e868
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/event/server_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ sv_ev_roster_received(void)
ui_show_roster();
}

roster_process_pending_presence();
char *account_name = session_get_account_name();

#ifdef HAVE_LIBGPGME
Expand Down
43 changes: 43 additions & 0 deletions src/xmpp/roster_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@ typedef struct prof_roster_t {
GHashTable *group_count;
} ProfRoster;

typedef struct pending_presence {
char *barejid;
Resource *resource;
GDateTime *last_activity;
} ProfPendingPresence;

static ProfRoster *roster = NULL;
static gboolean roster_received = FALSE;
static GSList *roster_pending_presence = NULL;

static gboolean _key_equals(void *key1, void *key2);
static gboolean _datetimes_equal(GDateTime *dt1, GDateTime *dt2);
Expand All @@ -87,6 +95,9 @@ roster_create(void)
roster->name_to_barejid = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
roster->groups_ac = autocomplete_new();
roster->group_count = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);

roster_received = FALSE;
roster_pending_presence = NULL;
}

void
Expand Down Expand Up @@ -114,6 +125,18 @@ roster_update_presence(const char *const barejid, Resource *resource, GDateTime
assert(barejid != NULL);
assert(resource != NULL);

if (!roster_received) {
ProfPendingPresence *presence = malloc(sizeof(ProfPendingPresence));
presence->barejid = strdup(barejid);
presence->resource = resource;
presence->last_activity = last_activity;
if (last_activity) {
g_date_time_ref(last_activity);
}
roster_pending_presence = g_slist_append(roster_pending_presence, presence);
return FALSE;
}

PContact contact = roster_get_contact(barejid);
if (contact == NULL) {
return FALSE;
Expand Down Expand Up @@ -664,3 +687,23 @@ roster_compare_presence(PContact a, PContact b)
return roster_compare_name(a, b);
}
}

void
roster_process_pending_presence(void)
{
roster_received = TRUE;

GSList *iter;
for (iter = roster_pending_presence; iter != NULL; iter = iter->next) {
ProfPendingPresence *presence = iter->data;
roster_update_presence(presence->barejid, presence->resource, presence->last_activity);
free(presence->barejid);
/* seems like resource isn't free on the calling side */
if (presence->last_activity) {
g_date_time_unref(presence->last_activity);
}
}

g_slist_free(roster_pending_presence);
roster_pending_presence = NULL;
}
1 change: 1 addition & 0 deletions src/xmpp/roster_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,6 @@ GSList* roster_get_contacts_by_presence(const char *const presence);
char* roster_get_msg_display_name(const char *const barejid, const char *const resource);
gint roster_compare_name(PContact a, PContact b);
gint roster_compare_presence(PContact a, PContact b);
void roster_process_pending_presence(void);

#endif

0 comments on commit 448e868

Please sign in to comment.