about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/event/client_events.c8
-rw-r--r--src/event/server_events.c16
-rw-r--r--src/ui/buffer.c2
-rw-r--r--src/ui/privwin.c30
-rw-r--r--src/ui/ui.h4
-rw-r--r--src/ui/win_types.h1
-rw-r--r--src/ui/window.c3
7 files changed, 60 insertions, 4 deletions
diff --git a/src/event/client_events.c b/src/event/client_events.c
index 2f227d9f..5413dea7 100644
--- a/src/event/client_events.c
+++ b/src/event/client_events.c
@@ -183,6 +183,10 @@ cl_ev_send_muc_msg(ProfMucWin *mucwin, const char *const msg)
 void
 cl_ev_send_priv_msg(ProfPrivateWin *privwin, const char *const msg)
 {
-    message_send_private(privwin->fulljid, msg);
-    privwin_outgoing_msg(privwin, msg);
+    if (privwin->occupant_offline) {
+        privwin_message_occupant_offline(privwin);
+    } else {
+        message_send_private(privwin->fulljid, msg);
+        privwin_outgoing_msg(privwin, msg);
+    }
 }
diff --git a/src/event/server_events.c b/src/event/server_events.c
index 105c7d72..e6738833 100644
--- a/src/event/server_events.c
+++ b/src/event/server_events.c
@@ -665,6 +665,14 @@ sv_ev_room_occupant_offline(const char *const room, const char *const nick,
         mucwin_occupant_offline(mucwin, nick);
     }
     prefs_free_string(muc_status_pref);
+
+    Jid *jidp = jid_create_from_bare_and_resource(room, nick);
+    ProfPrivateWin *privwin = wins_get_private(jidp->fulljid);
+    jid_destroy(jidp);
+    if (privwin != NULL) {
+        privwin_occupant_offline(privwin);
+    }
+
     occupantswin_occupants(room);
     rosterwin_roster();
 }
@@ -840,6 +848,14 @@ sv_ev_muc_occupant_online(const char *const room, const char *const nick, const
             mucwin_occupant_online(mucwin, nick, role, affiliation, show, status);
         }
         prefs_free_string(muc_status_pref);
+
+        Jid *jidp = jid_create_from_bare_and_resource(mucwin->roomjid, nick);
+        ProfPrivateWin *privwin = wins_get_private(jidp->fulljid);
+        jid_destroy(jidp);
+        if (privwin) {
+            privwin_occupant_online(privwin);
+        }
+
         occupantswin_occupants(room);
         rosterwin_roster();
         return;
diff --git a/src/ui/buffer.c b/src/ui/buffer.c
index 629aa9e7..0b9da448 100644
--- a/src/ui/buffer.c
+++ b/src/ui/buffer.c
@@ -88,7 +88,7 @@ buffer_push(ProfBuff buffer, const char show_char, int pad_indent, GDateTime *ti
     e->flags = flags;
     e->theme_item = theme_item;
     e->time = g_date_time_ref(time);
-    e->from = strdup(from);
+    e->from = from ? strdup(from) : NULL;
     e->message = strdup(message);
     e->receipt = receipt;
 
diff --git a/src/ui/privwin.c b/src/ui/privwin.c
index b6f1a04d..4b8217e2 100644
--- a/src/ui/privwin.c
+++ b/src/ui/privwin.c
@@ -111,6 +111,36 @@ privwin_outgoing_msg(ProfPrivateWin *privwin, const char *const message)
     win_print((ProfWin*)privwin, '-', 0, NULL, 0, THEME_TEXT_ME, "me", message);
 }
 
+void
+privwin_message_occupant_offline(ProfPrivateWin *privwin)
+{
+    assert(privwin != NULL);
+
+    win_print((ProfWin*)privwin, '-', 0, NULL, 0, THEME_ERROR, NULL, "Unable to send message, occupant no longer present in room.");
+}
+
+void
+privwin_occupant_offline(ProfPrivateWin *privwin)
+{
+    assert(privwin != NULL);
+
+    privwin->occupant_offline = TRUE;
+    Jid *jidp = jid_create(privwin->fulljid);
+    win_vprint((ProfWin*)privwin, '-', 0, NULL, 0, THEME_OFFLINE, NULL, "-- %s has left the room.", jidp->resourcepart);
+    jid_destroy(jidp);
+}
+
+void
+privwin_occupant_online(ProfPrivateWin *privwin)
+{
+    assert(privwin != NULL);
+
+    privwin->occupant_offline = FALSE;
+    Jid *jidp = jid_create(privwin->fulljid);
+    win_vprint((ProfWin*)privwin, '-', 0, NULL, 0, THEME_ONLINE, NULL, "-- %s has joined the room.", jidp->resourcepart);
+    jid_destroy(jidp);
+}
+
 char*
 privwin_get_string(ProfPrivateWin *privwin)
 {
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 835fd890..028eaa25 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -194,7 +194,11 @@ char* mucwin_get_string(ProfMucWin *mucwin);
 // MUC private chat window
 void privwin_incoming_msg(ProfPrivateWin *privatewin, const char *const message, GDateTime *timestamp);
 void privwin_outgoing_msg(ProfPrivateWin *privwin, const char *const message);
+void privwin_message_occupant_offline(ProfPrivateWin *privwin);
+
 char* privwin_get_string(ProfPrivateWin *privwin);
+void privwin_occupant_offline(ProfPrivateWin *privwin);
+void privwin_occupant_online(ProfPrivateWin *privwin);
 
 // MUC room config window
 void mucconfwin_handle_configuration(ProfMucConfWin *confwin, DataForm *form);
diff --git a/src/ui/win_types.h b/src/ui/win_types.h
index 53b5f49a..0e9f81d7 100644
--- a/src/ui/win_types.h
+++ b/src/ui/win_types.h
@@ -137,6 +137,7 @@ typedef struct prof_private_win_t {
     int unread;
     gboolean notify;
     unsigned long memcheck;
+    gboolean occupant_offline;
 } ProfPrivateWin;
 
 typedef struct prof_xml_win_t {
diff --git a/src/ui/window.c b/src/ui/window.c
index 33ea86e0..8ae04499 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -220,6 +220,7 @@ win_create_private(const char *const fulljid)
     new_win->fulljid = strdup(fulljid);
     new_win->unread = 0;
     new_win->notify = FALSE;
+    new_win->occupant_offline = FALSE;
 
     new_win->memcheck = PROFPRIVATEWIN_MEMCHECK;
 
@@ -1098,7 +1099,7 @@ _win_print(ProfWin *window, const char show_char, int pad_indent, GDateTime *tim
         }
     }
 
-    if (strlen(from) > 0) {
+    if (from && strlen(from) > 0) {
         if (flags & NO_ME) {
             colour = theme_attrs(THEME_THEM);
         }