From f1780f0017dde352a30192965233e25ef252d1f5 Mon Sep 17 00:00:00 2001 From: Thorben Günther Date: Fri, 5 Mar 2021 13:29:36 +0100 Subject: MUC: Show offline members in sidebar --- src/command/cmd_ac.c | 1 + src/command/cmd_funcs.c | 12 ++++++++ src/config/preferences.c | 3 ++ src/config/preferences.h | 1 + src/config/theme.c | 1 + src/ui/console.c | 5 ++++ src/ui/mucwin.c | 3 ++ src/ui/occupantswin.c | 74 +++++++++++++++++++++++++++++++++++++++++------- src/ui/win_types.h | 1 + src/ui/window.c | 5 ++++ 10 files changed, 96 insertions(+), 10 deletions(-) diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 65d73b33..40c8d7ed 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -790,6 +790,7 @@ cmd_ac_init(void) occupants_show_ac = autocomplete_new(); autocomplete_add(occupants_show_ac, "jid"); + autocomplete_add(occupants_show_ac, "offline"); occupants_char_ac = autocomplete_new(); autocomplete_add(occupants_char_ac, "none"); diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index d2cf2307..55965690 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -4370,6 +4370,9 @@ cmd_occupants(ProfWin* window, const char* const command, gchar** args) if (g_strcmp0(args[2], "jid") == 0) { cons_show("Occupant jids enabled."); prefs_set_boolean(PREF_OCCUPANTS_JID, TRUE); + } else if (g_strcmp0(args[2], "offline") == 0) { + cons_show("Occupants offline enabled."); + prefs_set_boolean(PREF_OCCUPANTS_OFFLINE, TRUE); } else { cons_show("Occupant list enabled."); prefs_set_boolean(PREF_OCCUPANTS, TRUE); @@ -4379,6 +4382,9 @@ cmd_occupants(ProfWin* window, const char* const command, gchar** args) if (g_strcmp0(args[2], "jid") == 0) { cons_show("Occupant jids disabled."); prefs_set_boolean(PREF_OCCUPANTS_JID, FALSE); + } else if (g_strcmp0(args[2], "offline") == 0) { + cons_show("Occupants offline disabled."); + prefs_set_boolean(PREF_OCCUPANTS_OFFLINE, FALSE); } else { cons_show("Occupant list disabled."); prefs_set_boolean(PREF_OCCUPANTS, FALSE); @@ -4430,6 +4436,9 @@ cmd_occupants(ProfWin* window, const char* const command, gchar** args) if (g_strcmp0(args[1], "jid") == 0) { mucwin->showjid = TRUE; mucwin_update_occupants(mucwin); + } else if (g_strcmp0(args[1], "offline") == 0) { + mucwin->showoffline = TRUE; + mucwin_update_occupants(mucwin); } else { mucwin_show_occupants(mucwin); } @@ -4437,6 +4446,9 @@ cmd_occupants(ProfWin* window, const char* const command, gchar** args) if (g_strcmp0(args[1], "jid") == 0) { mucwin->showjid = FALSE; mucwin_update_occupants(mucwin); + } else if (g_strcmp0(args[1], "offline") == 0) { + mucwin->showoffline = FALSE; + mucwin_update_occupants(mucwin); } else { mucwin_hide_occupants(mucwin); } diff --git a/src/config/preferences.c b/src/config/preferences.c index c2411507..f09cb746 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -1806,6 +1806,7 @@ _get_group(preference_t pref) case PREF_HISTORY: case PREF_OCCUPANTS: case PREF_OCCUPANTS_JID: + case PREF_OCCUPANTS_OFFLINE: case PREF_OCCUPANTS_WRAP: case PREF_STATUSES: case PREF_STATUSES_CONSOLE: @@ -1978,6 +1979,8 @@ _get_key(preference_t pref) return "occupants"; case PREF_OCCUPANTS_JID: return "occupants.jid"; + case PREF_OCCUPANTS_OFFLINE: + return "occupants.offline"; case PREF_OCCUPANTS_WRAP: return "occupants.wrap"; case PREF_MUC_PRIVILEGES: diff --git a/src/config/preferences.h b/src/config/preferences.h index 51d9ca12..49c2c438 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -67,6 +67,7 @@ typedef enum { PREF_OCCUPANTS, PREF_OCCUPANTS_SIZE, PREF_OCCUPANTS_JID, + PREF_OCCUPANTS_OFFLINE, PREF_ROSTER, PREF_ROSTER_SIZE, PREF_ROSTER_OFFLINE, diff --git a/src/config/theme.c b/src/config/theme.c index 2c653988..dd19dc57 100644 --- a/src/config/theme.c +++ b/src/config/theme.c @@ -305,6 +305,7 @@ _load_preferences(void) _set_boolean_preference("resource.message", PREF_RESOURCE_MESSAGE); _set_boolean_preference("occupants", PREF_OCCUPANTS); _set_boolean_preference("occupants.jid", PREF_OCCUPANTS_JID); + _set_boolean_preference("occupants.offline", PREF_OCCUPANTS_OFFLINE); _set_boolean_preference("occupants.wrap", PREF_OCCUPANTS_WRAP); _set_boolean_preference("roster", PREF_ROSTER); _set_boolean_preference("roster.offline", PREF_ROSTER_OFFLINE); diff --git a/src/ui/console.c b/src/ui/console.c index 190adeea..a2f5db60 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1255,6 +1255,11 @@ cons_occupants_setting(void) else cons_show("Occupant jids (/occupants) : hide"); + if (prefs_get_boolean(PREF_OCCUPANTS_OFFLINE)) + cons_show("Occupants offline (/occupants) : show"); + else + cons_show("Occupants offline (/occupants) : hide"); + if (prefs_get_boolean(PREF_OCCUPANTS_WRAP)) cons_show("Occupants wrap (/occupants) : ON"); else diff --git a/src/ui/mucwin.c b/src/ui/mucwin.c index 808567f4..a3300ab4 100644 --- a/src/ui/mucwin.c +++ b/src/ui/mucwin.c @@ -34,6 +34,7 @@ * */ +#include "ui.h" #define _GNU_SOURCE 1 #include @@ -67,6 +68,8 @@ mucwin_new(const char* const barejid) } #endif + // Force redraw here to show correct offline users; before this point muc_members returns a wrong list + ui_redraw_all_room_rosters(); return mucwin; } diff --git a/src/ui/occupantswin.c b/src/ui/occupantswin.c index 3bb95485..f72d1567 100644 --- a/src/ui/occupantswin.c +++ b/src/ui/occupantswin.c @@ -42,12 +42,15 @@ #include "ui/window_list.h" static void -_occuptantswin_occupant(ProfLayoutSplit* layout, Occupant* occupant, gboolean showjid) +_occuptantswin_occupant(ProfLayoutSplit* layout, GList* item, gboolean showjid, gboolean isoffline) { int colour = 0; //init to workaround compiler warning theme_item_t presence_colour = THEME_ROSTER_ONLINE; //init to workaround compiler warning + Occupant* occupant = item->data; - if (prefs_get_boolean(PREF_OCCUPANTS_COLOR_NICK)) { + if (isoffline) { + wattron(layout->subwin, theme_attrs(THEME_ROSTER_OFFLINE)); + } else if (prefs_get_boolean(PREF_OCCUPANTS_COLOR_NICK)) { colour = theme_hash_attrs(occupant->nick); wattron(layout->subwin, colour); @@ -79,12 +82,18 @@ _occuptantswin_occupant(ProfLayoutSplit* layout, Occupant* occupant, gboolean sh gboolean wrap = prefs_get_boolean(PREF_OCCUPANTS_WRAP); - g_string_append(msg, occupant->nick); + if (isoffline) { + Jid* jid = jid_create(item->data); + g_string_append(msg, jid->barejid); + jid_destroy(jid); + } else { + g_string_append(msg, occupant->nick); + } win_sub_newline_lazy(layout->subwin); win_sub_print(layout->subwin, msg->str, FALSE, wrap, current_indent); g_string_free(msg, TRUE); - if (showjid && occupant->jid) { + if (showjid && !isoffline && occupant->jid) { GString* msg = g_string_new(spaces->str); g_string_append(msg, " "); @@ -96,7 +105,9 @@ _occuptantswin_occupant(ProfLayoutSplit* layout, Occupant* occupant, gboolean sh g_string_free(spaces, TRUE); - if (prefs_get_boolean(PREF_OCCUPANTS_COLOR_NICK)) { + if (isoffline) { + wattroff(layout->subwin, theme_attrs(THEME_ROSTER_OFFLINE)); + } else if (prefs_get_boolean(PREF_OCCUPANTS_COLOR_NICK)) { wattroff(layout->subwin, colour); } else { wattroff(layout->subwin, theme_attrs(presence_colour)); @@ -124,6 +135,8 @@ occupantswin_occupants(const char* const roomjid) if (prefs_get_boolean(PREF_MUC_PRIVILEGES)) { + GList* online_occupants = { NULL }; + GString* role = g_string_new(prefix->str); g_string_append(role, "Moderators"); @@ -136,9 +149,10 @@ occupantswin_occupants(const char* const roomjid) while (roster_curr) { Occupant* occupant = roster_curr->data; if (occupant->role == MUC_ROLE_MODERATOR) { - _occuptantswin_occupant(layout, occupant, mucwin->showjid); + _occuptantswin_occupant(layout, roster_curr, mucwin->showjid, false); } roster_curr = g_list_next(roster_curr); + online_occupants = g_list_append(online_occupants, occupant->jid); } role = g_string_new(prefix->str); @@ -153,9 +167,10 @@ occupantswin_occupants(const char* const roomjid) while (roster_curr) { Occupant* occupant = roster_curr->data; if (occupant->role == MUC_ROLE_PARTICIPANT) { - _occuptantswin_occupant(layout, occupant, mucwin->showjid); + _occuptantswin_occupant(layout, roster_curr, mucwin->showjid, false); } roster_curr = g_list_next(roster_curr); + online_occupants = g_list_append(online_occupants, occupant->jid); } role = g_string_new(prefix->str); @@ -170,10 +185,50 @@ occupantswin_occupants(const char* const roomjid) while (roster_curr) { Occupant* occupant = roster_curr->data; if (occupant->role == MUC_ROLE_VISITOR) { - _occuptantswin_occupant(layout, occupant, mucwin->showjid); + _occuptantswin_occupant(layout, roster_curr, mucwin->showjid, false); } roster_curr = g_list_next(roster_curr); + online_occupants = g_list_append(online_occupants, occupant->jid); + } + + if (mucwin->showoffline) { + GList* members = muc_members(roomjid); + // offline_occupants is used to display the same account on multiple devices once + GList* offline_occupants = { NULL }; + + role = g_string_new(prefix->str); + g_string_append(role, "Offline"); + + wattron(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER)); + win_sub_newline_lazy(layout->subwin); + win_sub_print(layout->subwin, role->str, TRUE, FALSE, 0); + wattroff(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER)); + g_string_free(role, TRUE); + roster_curr = members; + while (roster_curr) { + Jid* jid = jid_create(roster_curr->data); + gboolean found = false; + GList* iter = online_occupants; + for (; iter != NULL; iter = iter->next) { + if (strstr(iter->data, jid->barejid)) { + found = true; + break; + } + } + + if (!found && g_list_index(offline_occupants, jid->barejid) == -1) { + _occuptantswin_occupant(layout, roster_curr, mucwin->showjid, true); + offline_occupants = g_list_append(offline_occupants, jid->barejid); + } + + jid_destroy(jid); + roster_curr = g_list_next(roster_curr); + } + g_list_free(members); + g_list_free(offline_occupants); } + g_list_free(online_occupants); + } else { GString* role = g_string_new(prefix->str); g_string_append(role, "Occupants\n"); @@ -186,8 +241,7 @@ occupantswin_occupants(const char* const roomjid) GList* roster_curr = occupants; while (roster_curr) { - Occupant* occupant = roster_curr->data; - _occuptantswin_occupant(layout, occupant, mucwin->showjid); + _occuptantswin_occupant(layout, roster_curr, mucwin->showjid, false); roster_curr = g_list_next(roster_curr); } } diff --git a/src/ui/win_types.h b/src/ui/win_types.h index 7beaca5f..e740b543 100644 --- a/src/ui/win_types.h +++ b/src/ui/win_types.h @@ -187,6 +187,7 @@ typedef struct prof_muc_win_t gboolean unread_mentions; gboolean unread_triggers; gboolean showjid; + gboolean showoffline; gboolean is_omemo; unsigned long memcheck; char* enctext; diff --git a/src/ui/window.c b/src/ui/window.c index 8afb23f4..b6676774 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -203,6 +203,11 @@ win_create_muc(const char* const roomjid) } else { new_win->showjid = FALSE; } + if (prefs_get_boolean(PREF_OCCUPANTS_OFFLINE)) { + new_win->showoffline = TRUE; + } else { + new_win->showoffline = FALSE; + } new_win->enctext = NULL; new_win->message_char = NULL; new_win->is_omemo = FALSE; -- cgit 1.4.1-2-gfad0