]> www.infradead.org Git - pidgin-chime.git/commitdiff
Sort room list and implement 'Leave Room'
authorDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 18 Nov 2019 11:43:14 +0000 (11:43 +0000)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 18 Nov 2019 11:43:14 +0000 (11:43 +0000)
We can't leave rooms from the room list display because Pidgin doesn't
let us add action buttons there, but we could do our own version as a
search results box, triggered from the account menu.

Also haven't implemented 'delete room' yet.

chime/chime-room.c
chime/chime-room.h
prpl/chat.c
prpl/rooms.c

index 8167932198591d45a21176fbce7aa637b7bf4115..b195d9d0350d12139f6d66048ff532acea9edbcf 100644 (file)
@@ -305,6 +305,56 @@ const gchar *chime_room_get_last_mentioned(ChimeRoom *self)
        return self->last_mentioned;
 }
 
+const gchar *chime_room_get_last_read(ChimeRoom *self)
+{
+       g_return_val_if_fail(CHIME_IS_ROOM(self), NULL);
+
+       return self->last_read;
+}
+
+const gchar *chime_room_get_last_sent(ChimeRoom *self)
+{
+       g_return_val_if_fail(CHIME_IS_ROOM(self), NULL);
+
+       return self->last_sent;
+}
+
+const gchar *chime_room_get_created_on(ChimeRoom *self)
+{
+       g_return_val_if_fail(CHIME_IS_ROOM(self), NULL);
+
+       return self->created_on;
+}
+
+static gboolean cmp_time(const char *ev, const char *last_read)
+{
+       GTimeVal ev_time, read_time;
+
+       if (!ev || !g_time_val_from_iso8601(ev, &ev_time))
+               return FALSE;
+
+       if (!last_read || !g_time_val_from_iso8601(last_read, &read_time))
+               return TRUE;
+
+       return (ev_time.tv_sec > read_time.tv_sec ||
+               (ev_time.tv_sec == read_time.tv_sec && ev_time.tv_usec > read_time.tv_usec));
+}
+
+gboolean chime_room_has_mention(ChimeRoom *self)
+{
+       g_return_val_if_fail(CHIME_IS_ROOM(self), FALSE);
+
+       return cmp_time(self->last_mentioned, self->last_read);
+}
+
+gboolean chime_room_has_unread(ChimeRoom *self)
+{
+       g_return_val_if_fail(CHIME_IS_ROOM(self), FALSE);
+
+       return cmp_time(self->last_sent, self->last_read);
+}
+
+
 static gboolean parse_privacy(JsonNode *node, const gchar *member, gboolean *val)
 {
        const gchar *str;
index c869ea966163eed82cc7efbd0a7f1a44be3dc5a0..5575090f48ad57ace42a1e8bce7cadadb9eba0c4 100644 (file)
@@ -50,6 +50,12 @@ gboolean chime_room_get_visibility(ChimeRoom *self);
 const gchar *chime_room_get_channel(ChimeRoom *self);
 
 const gchar *chime_room_get_last_mentioned(ChimeRoom *self);
+const gchar *chime_room_get_last_read(ChimeRoom *self);
+const gchar *chime_room_get_last_sent(ChimeRoom *self);
+const gchar *chime_room_get_created_on(ChimeRoom *self);
+
+gboolean chime_room_has_mention(ChimeRoom *self);
+gboolean chime_room_has_unread(ChimeRoom *self);
 
 ChimeRoom *chime_connection_room_by_name(ChimeConnection *cxn,
                                         const gchar *name);
index d48985b484c4610be7b34f7a1e482c8cdfe62660..425af16ac55533a90c9eb5c8c91a2888a88ba8b3 100644 (file)
@@ -1169,6 +1169,30 @@ static void join_audio(PurpleBuddy *buddy, gpointer _chat)
                chime_call_set_silent(chat->call, FALSE);
 }
 
+static void leave_room_cb(GObject *source, GAsyncResult *result, gpointer _chat)
+{
+        struct chime_chat *chat = _chat;
+        ChimeConnection *cxn = CHIME_CONNECTION(source);
+        GError *error = NULL;
+
+        if (!chime_connection_remove_room_member_finish(cxn, result, &error)) {
+                purple_conversation_write(chat->conv, NULL, error->message,
+                                          PURPLE_MESSAGE_ERROR, time(NULL));
+        }
+        /* If it succeeds, that's self-evident. */
+}
+
+static void leave_room(PurpleBuddy *buddy, gpointer _chat)
+{
+       struct chime_chat *chat = _chat;
+       ChimeConnection *cxn = PURPLE_CHIME_CXN(chat->conv->account->gc);
+       ChimeRoom *room = CHIME_ROOM(chat->m.obj);
+       ChimeContact *me = chime_connection_contact_by_id(cxn,
+                                                         chime_connection_get_profile_id(cxn));
+
+       chime_connection_remove_room_member_async(cxn, room, me, NULL, leave_room_cb, chat);
+}
+
 GList *chime_purple_chat_menu(PurpleChat *pchat)
 {
 
@@ -1209,6 +1233,10 @@ GList *chime_purple_chat_menu(PurpleChat *pchat)
                items = g_list_append(items,
                                      purple_menu_action_new(_("Share screen..."),
                                                             PURPLE_CALLBACK(select_screen_share), chat, NULL));
+       } else if (CHIME_IS_ROOM(chat->m.obj)) {
+               items = g_list_append(items,
+                                     purple_menu_action_new(_("Leave room"),
+                                                            PURPLE_CALLBACK(leave_room), chat, NULL));
        }
 
        return items;
index 99edc3b59ea8ac0fe264af0a0ec03662919d2910..087b3a7d3e03f4db2673702928feae067e1d705a 100644 (file)
 
 #include <libsoup/soup.h>
 
-static void add_room_to_list(ChimeConnection *cxn, ChimeRoom *room, gpointer _roomlist)
+struct room_sort {
+       struct room_sort *next;
+       gboolean unread;
+       gboolean mention;
+       GTimeVal when;
+       ChimeRoom *room;
+};
+
+static gboolean cmp_room(struct room_sort *a, struct room_sort *b)
 {
-       PurpleRoomlist *roomlist = _roomlist;
-
-       PurpleRoomlistRoom *proom = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM,
-                                                            chime_room_get_name(room), NULL);
-       purple_roomlist_room_add_field(roomlist, proom, chime_room_get_id(room));
-       purple_roomlist_room_add_field(roomlist, proom, GUINT_TO_POINTER(chime_room_get_visibility(room)));
-       purple_roomlist_room_add_field(roomlist, proom, GUINT_TO_POINTER(chime_room_get_privacy(room)));
-       purple_roomlist_room_add(roomlist, proom);
+       if (a->mention != b->mention)
+               return a->mention;
+       if (a->unread != b->unread)
+               return a->unread;
+       if (a->when.tv_sec > b->when.tv_sec)
+               return TRUE;
+       if (a->when.tv_sec == b->when.tv_sec &&
+           a->when.tv_usec > b->when.tv_sec)
+               return TRUE;
+       return FALSE;
+}
+
+static void sort_room(ChimeConnection *cxn, ChimeRoom *room, gpointer _rs_list)
+{
+       struct room_sort **rs_list = _rs_list;
+       struct room_sort *rs = g_new0(struct room_sort, 1);
+       const char *tm;
+
+       rs->room = room;
+       rs->unread = chime_room_has_unread(room);
+       rs->mention = chime_room_has_mention(room);
+
+       tm = chime_room_get_last_sent(room);
+       if (!tm || !g_time_val_from_iso8601(tm, &rs->when)) {
+               tm = chime_room_get_created_on(room);
+               if (tm)
+                       g_time_val_from_iso8601(tm, &rs->when);
+       }
+       while (*rs_list && cmp_room(*rs_list, rs))
+               rs_list = &((*rs_list)->next);
+       rs->next = *rs_list;
+       *rs_list = rs;
 }
 
 PurpleRoomlist *chime_purple_roomlist_get_list(PurpleConnection *conn)
 {
        ChimeConnection *cxn = PURPLE_CHIME_CXN(conn);
        PurpleRoomlist *roomlist;
+       struct room_sort *rooms = NULL, *tmp_rs;
        GList *fields = NULL;
 
        roomlist = purple_roomlist_new(conn->account);
        fields = g_list_append(fields, purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "RoomId", TRUE));
-       fields = g_list_append(fields, purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_BOOL, _("Visible"), "Visibility", FALSE));
-       fields = g_list_append(fields, purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_BOOL, _("Private"), "Privacy", FALSE));
+       fields = g_list_append(fields, purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Status"), "Status", FALSE));
+       fields = g_list_append(fields, purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Last Sent"), "Last Sent", FALSE));
        purple_roomlist_set_fields(roomlist, fields);
 
-       chime_connection_foreach_room(cxn, add_room_to_list, roomlist);
+       chime_connection_foreach_room(cxn, sort_room, &rooms);
+
+       while (rooms) {
+               ChimeRoom *room = rooms->room;
+               PurpleRoomlistRoom *proom = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM,
+                                                                    chime_room_get_name(room), NULL);
+               purple_roomlist_room_add_field(roomlist, proom, chime_room_get_id(room));
+               purple_roomlist_room_add_field(roomlist, proom, rooms->mention ? "@" : (rooms->unread ? "•" : ""));
+               purple_roomlist_room_add_field(roomlist, proom, chime_room_get_last_sent(room) ? : chime_room_get_created_on(room));
+               purple_roomlist_room_add(roomlist, proom);
+               tmp_rs = rooms;
+               rooms = rooms->next;
+               g_free(tmp_rs);
+       }
 
        purple_roomlist_set_in_progress(roomlist, FALSE);
        return roomlist;