diff --git a/xC-proto b/xC-proto index 03c40d7..ea39b86 100644 --- a/xC-proto +++ b/xC-proto @@ -155,13 +155,25 @@ struct EventMessage { case SERVER_UPDATE: string server_name; - enum ServerState { + union ServerData switch (enum ServerState { DISCONNECTED, CONNECTING, CONNECTED, REGISTERED, DISCONNECTING, - } state; + } state) { + case DISCONNECTED: + case CONNECTING: + case CONNECTED: + void; + case REGISTERED: + string user; + string user_mode; + // Theoretically, we could also send user information in this state, + // but we'd have to duplicate both fields. + case DISCONNECTING: + void; + } data; case SERVER_RENAME: // Buffers aren't sent updates for in this circumstance, // as that wouldn't be sufficiently atomic anyway. diff --git a/xC.c b/xC.c index 22252ff..ecb3c2d 100644 --- a/xC.c +++ b/xC.c @@ -3067,6 +3067,9 @@ relay_server_state_for_server (struct server *s) return 0; } +// TODO: Consider pushing this whole block of code further down. +static char *irc_to_utf8 (const char *text); + static void relay_prepare_server_update (struct app_context *ctx, struct server *s) { @@ -3074,7 +3077,17 @@ relay_prepare_server_update (struct app_context *ctx, struct server *s) struct relay_event_data_server_update *e = &m->data.server_update; e->event = RELAY_EVENT_SERVER_UPDATE; e->server_name = str_from_cstr (s->name); - e->state = relay_server_state_for_server (s); + e->data.state = relay_server_state_for_server (s); + if (s->state == IRC_REGISTERED) + { + char *user_utf8 = irc_to_utf8 (s->irc_user->nickname); + e->data.registered.user = str_from_cstr (user_utf8); + free (user_utf8); + + char *user_mode_utf8 = irc_to_utf8 (s->irc_user_mode.str); + e->data.registered.user_mode = str_from_cstr (user_mode_utf8); + free (user_mode_utf8); + } } static void @@ -7071,6 +7084,9 @@ irc_handle_mode_user (struct server *s, char **params) { struct mode_processor p = { .s = s }; mode_processor_run (&p, params, mode_processor_apply_user); + + relay_prepare_server_update (s->ctx, s); + relay_broadcast (s->ctx); } // --- Output processing ------------------------------------------------------- @@ -7681,7 +7697,7 @@ irc_handle_nick (struct server *s, const struct irc_message *msg) if (lexicographically_different) hard_assert (!str_map_find (&s->irc_users, new_nickname)); - // Now we can rename the PM buffer to reflect the new nickname + // Now we can rename everything to reflect the new nickname if (pm_buffer) { str_map_set (&s->irc_buffer_map, user->nickname, NULL); @@ -7692,8 +7708,17 @@ irc_handle_nick (struct server *s, const struct irc_message *msg) free (x); } - if (irc_is_this_us (s, msg->prefix)) + str_map_set (&s->irc_users, user->nickname, NULL); + str_map_set (&s->irc_users, new_nickname, user); + + cstr_set (&user->nickname, xstrdup (new_nickname)); + + // Finally broadcast the event to relay clients and secondary buffers + if (irc_is_this_us (s, new_nickname)) { + relay_prepare_server_update (s->ctx, s); + relay_broadcast (s->ctx); + log_nick_self (s, s->buffer, new_nickname); // Log a message in all open buffers on this server @@ -7717,12 +7742,6 @@ irc_handle_nick (struct server *s, const struct irc_message *msg) log_nick (s, buffer, msg->prefix, new_nickname); } } - - // Finally rename the user as it should be safe now - str_map_set (&s->irc_users, user->nickname, NULL); - str_map_set (&s->irc_users, new_nickname, user); - - cstr_set (&user->nickname, xstrdup (new_nickname)); } static void diff --git a/xP/public/xP.js b/xP/public/xP.js index 93fe642..144647e 100644 --- a/xP/public/xP.js +++ b/xP/public/xP.js @@ -388,7 +388,7 @@ rpcEventHandlers.set(Relay.Event.ServerUpdate, e => { let s = servers.get(e.serverName) if (s === undefined) servers.set(e.serverName, (s = {})) - s.state = e.state + s.data = e.data }) rpcEventHandlers.set(Relay.Event.ServerRename, e => { @@ -693,14 +693,21 @@ let Status = { let Prompt = { view: vnode => { - // This should be handled differently, so don't mind the lookup. let b = buffers.get(bufferCurrent) if (b === undefined || b.server === undefined) return - let state = b.server.state + if (b.server.data.user !== undefined) { + let user = b.server.data.user + if (b.server.data.userMode) + user += `(${b.server.data.userMode})` + return m('.prompt', {}, `${user}`) + } + + // This might certainly be done more systematically. + let state = b.server.data.state for (const s in Relay.ServerState) - if (Relay.ServerState[s] == b.server.state) { + if (Relay.ServerState[s] == state) { state = s break }