about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command/command.c47
-rw-r--r--src/muc.c68
-rw-r--r--src/muc.h10
-rw-r--r--src/profanity.c12
-rw-r--r--src/tools/autocomplete.c6
-rw-r--r--src/tools/autocomplete.h1
-rw-r--r--src/ui/console.c37
-rw-r--r--src/ui/notifier.c14
-rw-r--r--src/ui/notifier.h3
-rw-r--r--src/ui/ui.h1
10 files changed, 174 insertions, 25 deletions
diff --git a/src/command/command.c b/src/command/command.c
index 6cbfdac9..d9207763 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -102,6 +102,8 @@ static gboolean _cmd_close(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_clear(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_join(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_invite(gchar **args, struct cmd_help_t help);
+static gboolean _cmd_invites(gchar **args, struct cmd_help_t help);
+static gboolean _cmd_decline(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_rooms(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_disco(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_set_beep(gchar **args, struct cmd_help_t help);
@@ -349,6 +351,24 @@ static struct cmd_t main_commands[] =
           "If a message is supplied it will be send as the reason for the invite.",
           NULL } } },
 
+    { "/invites",
+        _cmd_invites, parse_args_with_freetext, 0, 0,
+        { "/invites", "Show outstanding chat room invites.",
+        { "/invites",
+          "--------",
+          "Show all rooms that you have been invited to, and have not yet been accepted or declind.",
+          "Use \"/join <room>\" to accept a room invitation.",
+          "Use \"/decline <room>\" to decline a room invitation.",
+          NULL } } },
+
+    { "/decline",
+        _cmd_decline, parse_args_with_freetext, 1, 1,
+        { "/decline room", "Decline a chat room invite.",
+        { "/decline room",
+          "-------------",
+          "Decline invitation to a chat room, the room will no longer be in the list of outstanding invites.",
+          NULL } } },
+
     { "/rooms",
         _cmd_rooms, parse_args, 0, 1,
         { "/rooms [conference-service]", "List chat rooms.",
@@ -914,6 +934,7 @@ void
 cmd_reset_autocomplete()
 {
     contact_list_reset_search_attempts();
+    muc_reset_invites_ac();
     accounts_reset_all_search();
     accounts_reset_enabled_search();
     prefs_reset_boolean_choice();
@@ -1114,6 +1135,9 @@ _cmd_complete_parameters(char *input, int *size)
     }
 
     _parameter_autocomplete(input, size, "/invite", contact_list_find_contact);
+    _parameter_autocomplete(input, size, "/decline", muc_find_invite);
+    _parameter_autocomplete(input, size, "/join", muc_find_invite);
+
 
     _parameter_autocomplete(input, size, "/connect",
         accounts_find_enabled);
@@ -2201,6 +2225,7 @@ _cmd_join(gchar **args, struct cmd_help_t help)
         presence_join_room(room_jid);
     }
     ui_room_join(room_jid);
+    muc_remove_invite(room);
 
     jid_destroy(room_jid);
     jid_destroy(my_jid);
@@ -2241,6 +2266,28 @@ _cmd_invite(gchar **args, struct cmd_help_t help)
 }
 
 static gboolean
+_cmd_invites(gchar **args, struct cmd_help_t help)
+{
+    GSList *invites = muc_get_invites();
+    cons_show_room_invites(invites);
+    g_slist_free_full(invites, g_free);
+    return TRUE;
+}
+
+static gboolean
+_cmd_decline(gchar **args, struct cmd_help_t help)
+{
+    if (!muc_invites_include(args[0])) {
+        cons_show("No such invite exists.");
+    } else {
+        muc_remove_invite(args[0]);
+        cons_show("Declined invite to %s.", args[0]);
+    }
+
+    return TRUE;
+}
+
+static gboolean
 _cmd_rooms(gchar **args, struct cmd_help_t help)
 {
     jabber_conn_status_t conn_status = jabber_get_connection_status();
diff --git a/src/muc.c b/src/muc.c
index dfa3f194..4f308f1d 100644
--- a/src/muc.c
+++ b/src/muc.c
@@ -29,6 +29,8 @@
 #include "jid.h"
 #include "tools/autocomplete.h"
 
+#include "ui/ui.h"
+
 typedef struct _muc_room_t {
     char *room; // e.g. test@conference.server
     char *nick; // e.g. Some User
@@ -41,9 +43,75 @@ typedef struct _muc_room_t {
 } ChatRoom;
 
 GHashTable *rooms = NULL;
+Autocomplete invite_ac;
 
 static void _free_room(ChatRoom *room);
 
+void
+muc_init(void)
+{
+    invite_ac = autocomplete_new();
+}
+
+void
+muc_add_invite(char *room)
+{
+    autocomplete_add(invite_ac, strdup(room));
+}
+
+void
+muc_remove_invite(char *room)
+{
+    autocomplete_remove(invite_ac, room);
+}
+
+gint
+muc_invite_count(void)
+{
+    return autocomplete_length(invite_ac);
+}
+
+GSList *
+muc_get_invites(void)
+{
+    return autocomplete_get_list(invite_ac);
+}
+
+gboolean
+muc_invites_include(const char * const room)
+{
+    GSList *invites = autocomplete_get_list(invite_ac);
+    GSList *curr = invites;
+    while (curr != NULL) {
+        if (strcmp(curr->data, room) == 0) {
+            g_slist_free_full(invites, g_free);
+            return TRUE;
+        } else {
+            curr = g_slist_next(curr);
+        }
+    }
+    g_slist_free_full(invites, g_free);
+    return FALSE;
+}
+
+void
+muc_reset_invites_ac(void)
+{
+    autocomplete_reset(invite_ac);
+}
+
+char *
+muc_find_invite(char *search_str)
+{
+    return autocomplete_complete(invite_ac, search_str);
+}
+
+void
+muc_clear_invites(void)
+{
+    autocomplete_clear(invite_ac);
+}
+
 /*
  * Join the chat room with the specified nickname
  */
diff --git a/src/muc.h b/src/muc.h
index 86ebabcb..b0458378 100644
--- a/src/muc.h
+++ b/src/muc.h
@@ -29,6 +29,7 @@
 #include "jid.h"
 #include "tools/autocomplete.h"
 
+void muc_init(void);
 void muc_join_room(const char * const room, const char * const nick);
 void muc_leave_room(const char * const room);
 gboolean muc_room_is_active(Jid *jid);
@@ -56,4 +57,13 @@ void muc_set_roster_pending_nick_change(const char * const room,
 char* muc_complete_roster_nick_change(const char * const room,
     const char * const nick);
 
+void muc_add_invite(const char *room);
+void muc_remove_invite(const char * const room);
+gint muc_invite_count(void);
+GSList* muc_get_invites(void);
+gboolean muc_invites_include(const char * const room);
+void muc_reset_invites_ac(void);
+char* muc_find_invite(char *search_str);
+void muc_clear_invites(void);
+
 #endif
diff --git a/src/profanity.c b/src/profanity.c
index 052575a9..61e540c0 100644
--- a/src/profanity.c
+++ b/src/profanity.c
@@ -224,6 +224,7 @@ prof_handle_lost_connection(void)
 {
     cons_show_error("Lost connection.");
     contact_list_clear();
+    muc_clear_invites();
     chat_sessions_clear();
     ui_disconnected();
     ui_current_page_off();
@@ -235,6 +236,7 @@ prof_handle_disconnect(const char * const jid)
     cons_show("%s logged out successfully.", jid);
     jabber_disconnect();
     contact_list_clear();
+    muc_clear_invites();
     chat_sessions_clear();
     ui_disconnected();
     ui_current_page_off();
@@ -322,8 +324,13 @@ void prof_handle_room_invite(jabber_invite_t invite_type,
     const char * const invitor, const char * const room,
     const char * const reason)
 {
-    cons_show_room_invite(invitor, room, reason);
-    ui_current_page_off();
+    Jid *room_jid = jid_create(room);
+    if (!muc_room_is_active(room_jid) && !muc_invites_include(room)) {
+        cons_show_room_invite(invitor, room, reason);
+        muc_add_invite(room);
+        ui_current_page_off();
+    }
+    jid_destroy(room_jid);
 }
 
 void
@@ -557,6 +564,7 @@ _init(const int disable_tls, char *log_level)
     cmd_init();
     log_info("Initialising contact list");
     contact_list_init();
+    muc_init();
     atexit(_shutdown);
 }
 
diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c
index baeeecb2..72abcba4 100644
--- a/src/tools/autocomplete.c
+++ b/src/tools/autocomplete.c
@@ -71,6 +71,12 @@ autocomplete_free(Autocomplete ac)
     ac = NULL;
 }
 
+gint
+autocomplete_length(Autocomplete ac)
+{
+    return g_slist_length(ac->items);
+}
+
 gboolean
 autocomplete_add(Autocomplete ac, void *item)
 {
diff --git a/src/tools/autocomplete.h b/src/tools/autocomplete.h
index 03f4a013..79f1a094 100644
--- a/src/tools/autocomplete.h
+++ b/src/tools/autocomplete.h
@@ -41,5 +41,6 @@ gboolean autocomplete_add(Autocomplete ac, void *item);
 gboolean autocomplete_remove(Autocomplete ac, const char * const item);
 GSList * autocomplete_get_list(Autocomplete ac);
 gchar * autocomplete_complete(Autocomplete ac, gchar *search_str);
+gint autocomplete_length(Autocomplete ac);
 
 #endif
diff --git a/src/ui/console.c b/src/ui/console.c
index 36358635..ef94f58c 100644
--- a/src/ui/console.c
+++ b/src/ui/console.c
@@ -314,6 +314,24 @@ cons_show_wins(void)
 }
 
 void
+cons_show_room_invites(GSList *invites)
+{
+    cons_show("");
+    if (invites == NULL) {
+        cons_show("No outstanding chat room invites.");
+    } else {
+        cons_show("Chat room invites, use /join or /decline commands:");
+        while (invites != NULL) {
+            cons_show("  %s", invites->data);
+            invites = g_slist_next(invites);
+        }
+    }
+
+    ui_console_dirty();
+    _cons_alert();
+}
+
+void
 cons_show_info(PContact pcontact)
 {
     const char *barejid = p_contact_barejid(pcontact);
@@ -653,12 +671,6 @@ void
 cons_show_room_invite(const char * const invitor, const char * const room,
     const char * const reason)
 {
-    char *display_room = NULL;
-    char *domain = strdup(jabber_get_domain());
-    Jid *room_jid = jid_create(room);
-    GString *default_service = g_string_new("conference.");
-    g_string_append(default_service, domain);
-
     cons_show("");
     cons_show("Chat room invite received:");
     cons_show("  From   : %s", invitor);
@@ -668,21 +680,12 @@ cons_show_room_invite(const char * const invitor, const char * const room,
         cons_show("  Message: %s", reason);
     }
 
-    if (strcmp(room_jid->domainpart, default_service->str) == 0) {
-        display_room = room_jid->localpart;
-    } else {
-        display_room = room_jid->barejid;
-    }
-
-    cons_show("Type \"/join %s\" to accept the invitation", display_room);
+    cons_show("Use /join or /decline");
 
     if (prefs_get_boolean(PREF_NOTIFY_INVITE)) {
-        notify_invite(invitor, room);
+        notify_invite(invitor, room, reason);
     }
 
-    jid_destroy(room_jid);
-    g_string_free(default_service, TRUE);
-
     ui_console_dirty();
     _cons_alert();
 }
diff --git a/src/ui/notifier.c b/src/ui/notifier.c
index 941feba9..54951fde 100644
--- a/src/ui/notifier.c
+++ b/src/ui/notifier.c
@@ -33,6 +33,7 @@
 #endif
 
 #include "log.h"
+#include "muc.h"
 #include "ui/ui.h"
 
 static void _notify(const char * const message, int timeout,
@@ -66,12 +67,16 @@ notify_typing(const char * const from)
 }
 
 void
-notify_invite(const char * const from, const char * const room)
+notify_invite(const char * const from, const char * const room,
+    const char * const reason)
 {
     GString *message = g_string_new("Room invite\nfrom: ");
     g_string_append(message, from);
     g_string_append(message, "\nto: ");
     g_string_append(message, room);
+    if (reason != NULL) {
+        g_string_append_printf(message, "\n\"%s\"", reason);
+    }
 
     _notify(message->str, 10000, "Incoming message");
 
@@ -91,8 +96,7 @@ void
 notify_remind(void)
 {
     gint unread = ui_unread();
-    //gint open = jabber_open_invites();
-    gint open = 0;
+    gint open = muc_invite_count();
 
     GString *text = g_string_new("");
 
@@ -109,9 +113,9 @@ notify_remind(void)
             g_string_append(text, "\n");
         }
         if (open == 1) {
-            g_string_append(text, "1 open invite");
+            g_string_append(text, "1 room invite");
         } else {
-            g_string_append_printf(text, "%d open invites", open);
+            g_string_append_printf(text, "%d room invites", open);
         }
     }
 
diff --git a/src/ui/notifier.h b/src/ui/notifier.h
index 60b2e337..8565f771 100644
--- a/src/ui/notifier.h
+++ b/src/ui/notifier.h
@@ -26,4 +26,5 @@ void notifier_uninit(void);
 void notify_typing(const char * const from);
 void notify_message(const char * const short_from);
 void notify_remind(void);
-void notify_invite(const char * const from, const char * const room);
+void notify_invite(const char * const from, const char * const room,
+    const char * const reason);
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 4dbde5ee..36e0fd56 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -166,6 +166,7 @@ void cons_show_room_invite(const char * const invitor, const char * const room,
 void cons_check_version(gboolean not_available_msg);
 void cons_show_typing(const char * const short_from);
 void cons_show_incoming_message(const char * const short_from, const int win_index);
+void cons_show_room_invites(GSList *invites);
 
 // status bar actions
 void status_bar_refresh(void);