diff --git a/src/command/command.c b/src/command/command.c index 36579990..5a7f4ca7 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -276,8 +276,8 @@ static struct cmd_t command_defs[] = CMD_SYN( "/roster", "/roster online", - "/roster show [offline|resource|presence|status|empty|count|priority]", - "/roster hide [offline|resource|presence|status|empty|count|priority]", + "/roster show [offline|resource|presence|status|empty|count|priority|rooms]", + "/roster hide [offline|resource|presence|status|empty|count|priority|rooms]", "/roster by group|presence|none", "/roster order name|presence", "/roster header char |none", @@ -307,6 +307,7 @@ static struct cmd_t command_defs[] = { "show empty", "When grouping by presence, show empty presence groups." }, { "show count", "Show number of contacts in group/presence." }, { "show priority", "Show resource priority." }, + { "show rooms", "Show chat rooms in roster panel." }, { "hide", "Hide the roster panel." }, { "hide offline", "Hide offline contacts in the roster panel." }, { "hide resource", "Hide contact's connected resources in the roster panel." }, @@ -315,6 +316,7 @@ static struct cmd_t command_defs[] = { "hide empty", "When grouping by presence, hide empty presence groups." }, { "hide count", "Hide number of contacts in group/presence." }, { "hide priority", "Hide resource priority." }, + { "hide rooms", "Hide chat rooms in roster panel." }, { "by group", "Group contacts in the roster panel by roster group." }, { "by presence", "Group contacts in the roster panel by presence." }, { "by none", "No grouping in the roster panel." }, @@ -2167,6 +2169,7 @@ cmd_init(void) autocomplete_add(roster_show_ac, "empty"); autocomplete_add(roster_show_ac, "count"); autocomplete_add(roster_show_ac, "priority"); + autocomplete_add(roster_show_ac, "rooms"); roster_by_ac = autocomplete_new(); autocomplete_add(roster_by_ac, "group"); diff --git a/src/command/commands.c b/src/command/commands.c index 192f241d..15b740e3 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2046,6 +2046,13 @@ cmd_roster(ProfWin *window, const char *const command, gchar **args) rosterwin_roster(); } return TRUE; + } else if (g_strcmp0(args[1], "rooms") == 0) { + cons_show("Roster rooms enabled"); + prefs_set_boolean(PREF_ROSTER_ROOMS, TRUE); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } + return TRUE; } else { cons_bad_cmd_usage(command); return TRUE; @@ -2107,6 +2114,13 @@ cmd_roster(ProfWin *window, const char *const command, gchar **args) rosterwin_roster(); } return TRUE; + } else if (g_strcmp0(args[1], "rooms") == 0) { + cons_show("Roster rooms disabled"); + prefs_set_boolean(PREF_ROSTER_ROOMS, FALSE); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } + return TRUE; } else { cons_bad_cmd_usage(command); return TRUE; diff --git a/src/config/preferences.c b/src/config/preferences.c index 8624921c..5447cec4 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -1046,6 +1046,7 @@ _get_group(preference_t pref) case PREF_ROSTER_PRIORITY: case PREF_ROSTER_WRAP: case PREF_ROSTER_RESOURCE_JOIN: + case PREF_ROSTER_ROOMS: case PREF_RESOURCE_TITLE: case PREF_RESOURCE_MESSAGE: case PREF_ENC_WARN: @@ -1240,6 +1241,8 @@ _get_key(preference_t pref) return "roster.wrap"; case PREF_ROSTER_RESOURCE_JOIN: return "roster.resource.join"; + case PREF_ROSTER_ROOMS: + return "roster.rooms"; case PREF_RESOURCE_TITLE: return "resource.title"; case PREF_RESOURCE_MESSAGE: @@ -1297,6 +1300,7 @@ _get_default_boolean(preference_t pref) case PREF_ROSTER_COUNT: case PREF_ROSTER_PRIORITY: case PREF_ROSTER_RESOURCE_JOIN: + case PREF_ROSTER_ROOMS: case PREF_TLS_SHOW: case PREF_LASTACTIVITY: return TRUE; diff --git a/src/config/preferences.h b/src/config/preferences.h index 80ed2696..da367b85 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -73,6 +73,7 @@ typedef enum { PREF_ROSTER_PRIORITY, PREF_ROSTER_WRAP, PREF_ROSTER_RESOURCE_JOIN, + PREF_ROSTER_ROOMS, PREF_MUC_PRIVILEGES, PREF_PRESENCE, PREF_WRAP, diff --git a/src/config/theme.c b/src/config/theme.c index 8ecc986d..6c346b91 100644 --- a/src/config/theme.c +++ b/src/config/theme.c @@ -467,6 +467,7 @@ _load_preferences(void) _set_string_preference("roster.order", PREF_ROSTER_ORDER); _set_boolean_preference("roster.count", PREF_ROSTER_COUNT); _set_boolean_preference("roster.priority", PREF_ROSTER_PRIORITY); + _set_boolean_preference("roster.rooms", PREF_ROSTER_ROOMS); if (g_key_file_has_key(theme, "ui", "roster.size", NULL)) { gint roster_size = g_key_file_get_integer(theme, "ui", "roster.size", NULL); prefs_set_roster_size(roster_size); diff --git a/src/event/server_events.c b/src/event/server_events.c index ec7e2e51..3842e0ea 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -283,6 +283,8 @@ sv_ev_room_message(const char *const room_jid, const char *const nick, notify_room_message(nick, jidp->localpart, ui_index, NULL); } jid_destroy(jidp); + + rosterwin_roster(); } void @@ -720,6 +722,8 @@ sv_ev_muc_self_online(const char *const room, const char *const nick, gboolean c } } + rosterwin_roster(); + // check for change in role/affiliation } else { ProfMucWin *mucwin = wins_get_muc(room); diff --git a/src/ui/console.c b/src/ui/console.c index 315e933c..a5406cab 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1325,6 +1325,11 @@ cons_roster_setting(void) else cons_show("Roster priority (/roster) : hide"); + if (prefs_get_boolean(PREF_ROSTER_ROOMS)) + cons_show("Roster rooms (/roster) : show"); + else + cons_show("Roster rooms (/roster) : hide"); + char *by = prefs_get_string(PREF_ROSTER_BY); cons_show("Roster by (/roster) : %s", by); prefs_free_string(by); diff --git a/src/ui/core.c b/src/ui/core.c index 83c8ed00..362a1ac8 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -644,6 +644,7 @@ ui_focus_win(ProfWin *window) if (i == 1) { title_bar_console(); + rosterwin_roster(); } else { title_bar_switch(); } diff --git a/src/ui/rosterwin.c b/src/ui/rosterwin.c index 4dd1178b..b7cf9396 100644 --- a/src/ui/rosterwin.c +++ b/src/ui/rosterwin.c @@ -369,6 +369,74 @@ _rosterwin_contacts_by_no_group(ProfLayoutSplit *layout, gboolean newline) g_slist_free(contacts); } +void +_rosterwin_room(ProfLayoutSplit *layout, ProfMucWin *mucwin) +{ + GString *msg = g_string_new(" "); + theme_item_t presence_colour = theme_main_presence_attrs("online"); + wattron(layout->subwin, theme_attrs(presence_colour)); + int indent = prefs_get_roster_contact_indent(); + int current_indent = 0; + if (indent > 0) { + current_indent += indent; + while (indent > 0) { + g_string_append(msg, " "); + indent--; + } + } + char ch = prefs_get_roster_contact_char(); + if (ch) { + g_string_append_printf(msg, "%c", ch); + } + + g_string_append(msg, mucwin->roomjid); + if (mucwin->unread > 0) { + g_string_append_printf(msg, " (%d)", mucwin->unread); + } + + win_sub_newline_lazy(layout->subwin); + gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); + win_sub_print(layout->subwin, msg->str, FALSE, wrap, current_indent); + g_string_free(msg, TRUE); + wattroff(layout->subwin, theme_attrs(presence_colour)); +} + +void +_rosterwin_rooms(ProfLayoutSplit *layout, gboolean newline) +{ + GList *rooms = muc_rooms(); + + // if this group has contacts, or if we want to show empty groups + if (rooms || prefs_get_boolean(PREF_ROSTER_EMPTY)) { + if (newline) { + win_sub_newline_lazy(layout->subwin); + } + wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + GString *title_str = g_string_new(" "); + char ch = prefs_get_roster_header_char(); + if (ch) { + g_string_append_printf(title_str, "%c", ch); + } + g_string_append(title_str, "Rooms"); + if (prefs_get_boolean(PREF_ROSTER_COUNT)) { + g_string_append_printf(title_str, " (%d)", g_list_length(rooms)); + } + gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); + win_sub_print(layout->subwin, title_str->str, FALSE, wrap, 1); + g_string_free(title_str, TRUE); + wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + + GList *curr_room = rooms; + while (curr_room) { + ProfMucWin *mucwin = wins_get_muc(curr_room->data); + _rosterwin_room(layout, mucwin); + curr_room = g_list_next(curr_room); + } + } + + g_list_free(rooms); +} + void rosterwin_roster(void) { @@ -443,4 +511,8 @@ rosterwin_roster(void) g_slist_free(contacts); } prefs_free_string(by); + + if (prefs_get_boolean(PREF_ROSTER_ROOMS)) { + _rosterwin_rooms(layout, TRUE); + } } diff --git a/themes/boothj5 b/themes/boothj5 index aea45c1d..3273d688 100644 --- a/themes/boothj5 +++ b/themes/boothj5 @@ -89,6 +89,7 @@ roster.resource.join=true roster.presence=true roster.presence.indent=-1 roster.status=true +roster.rooms=true occupants=true occupants.size=15 occupants.jid=false diff --git a/themes/complex b/themes/complex index 0d93a71b..21191d75 100644 --- a/themes/complex +++ b/themes/complex @@ -37,6 +37,7 @@ roster.resource.join=false roster.presence=true roster.presence.indent=1 roster.status=true +roster.rooms=true privileges=true presence=true intype=true diff --git a/themes/simple b/themes/simple index c9453390..2f9ace50 100644 --- a/themes/simple +++ b/themes/simple @@ -30,6 +30,7 @@ roster.contact.indent=0 roster.resource=false roster.presence=false roster.status=false +roster.rooms=false privileges=false presence=false intype=false