about summary refs log tree commit diff stats
path: root/src/server_events.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server_events.c')
-rw-r--r--src/server_events.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/server_events.c b/src/server_events.c
index 0086bd7f..7dfff16e 100644
--- a/src/server_events.c
+++ b/src/server_events.c
@@ -738,15 +738,26 @@ handle_muc_self_online(const char * const room, const char * const nick, gboolea
 
 void
 handle_muc_occupant_online(const char * const room, const char * const nick, const char * const jid,
-    const char * const role, const char * const affiliation, const char * const show, const char * const status)
+    const char * const role, const char * const affiliation, const char * const actor, const char * const reason,
+    const char * const show, const char * const status)
 {
-    gboolean existing = muc_roster_contains_nick(room, nick);
+    Occupant *occupant = muc_roster_item(room, nick);
+
+    const char *old_role = NULL;
+    const char *old_affiliation = NULL;
+    if (occupant) {
+        old_role = muc_occupant_role_str(occupant);
+        old_affiliation = muc_occupant_affiliation_str(occupant);
+    }
+
     gboolean updated = muc_roster_add(room, nick, jid, role, affiliation, show, status);
 
+    // not yet finished joining room
     if (!muc_roster_complete(room)) {
         return;
     }
 
+    // handle nickname change
     char *old_nick = muc_roster_nick_change_complete(room, nick);
     if (old_nick) {
         ui_room_member_nick_change(room, old_nick, nick);
@@ -755,7 +766,8 @@ handle_muc_occupant_online(const char * const room, const char * const nick, con
         return;
     }
 
-    if (!existing) {
+    // joined room
+    if (!occupant) {
         char *muc_status_pref = prefs_get_string(PREF_STATUSES_MUC);
         if (g_strcmp0(muc_status_pref, "none") != 0) {
             ui_room_member_online(room, nick, role, affiliation, show, status);
@@ -765,6 +777,7 @@ handle_muc_occupant_online(const char * const room, const char * const nick, con
         return;
     }
 
+    // presence updated
     if (updated) {
         char *muc_status_pref = prefs_get_string(PREF_STATUSES_MUC);
         if (g_strcmp0(muc_status_pref, "all") == 0) {
@@ -772,8 +785,21 @@ handle_muc_occupant_online(const char * const room, const char * const nick, con
         }
         prefs_free_string(muc_status_pref);
         ui_muc_roster(room);
+
+    // presence unchanged, check for role/affiliation change
     } else {
+        // both changed
+        if ((g_strcmp0(role, old_role) != 0) && (g_strcmp0(affiliation, old_affiliation) != 0)) {
+            ui_room_occupant_role_and_affiliation_change(room, nick, role, affiliation, actor, reason);
+
+        // role changed
+        } else if (g_strcmp0(role, old_role) != 0) {
+            ui_room_occupant_role_change(room, nick, role, actor, reason);
+
+        // affiliation changed
+        } else if (g_strcmp0(affiliation, old_affiliation) != 0) {
+            ui_room_occupant_affiliation_change(room, nick, affiliation, actor, reason);
+        }
         ui_muc_roster(room);
     }
-
 }
\ No newline at end of file