xC/xP: relay and render channel modes
This commit is contained in:
parent
1f0e0b1ce4
commit
d3628928b9
4
xC-proto
4
xC-proto
@ -131,6 +131,8 @@ struct EventMessage {
|
|||||||
case CHANNEL:
|
case CHANNEL:
|
||||||
string server_name;
|
string server_name;
|
||||||
ItemData topic<>;
|
ItemData topic<>;
|
||||||
|
// This includes parameters, separated by spaces.
|
||||||
|
string modes;
|
||||||
case PRIVATE_MESSAGE:
|
case PRIVATE_MESSAGE:
|
||||||
string server_name;
|
string server_name;
|
||||||
} context;
|
} context;
|
||||||
@ -169,7 +171,7 @@ struct EventMessage {
|
|||||||
void;
|
void;
|
||||||
case REGISTERED:
|
case REGISTERED:
|
||||||
string user;
|
string user;
|
||||||
string user_mode;
|
string user_modes;
|
||||||
// Theoretically, we could also send user information in this state,
|
// Theoretically, we could also send user information in this state,
|
||||||
// but we'd have to duplicate both fields.
|
// but we'd have to duplicate both fields.
|
||||||
case DISCONNECTING:
|
case DISCONNECTING:
|
||||||
|
102
xC.c
102
xC.c
@ -1841,7 +1841,7 @@ struct server
|
|||||||
|
|
||||||
struct user *irc_user; ///< Our own user
|
struct user *irc_user; ///< Our own user
|
||||||
int nick_counter; ///< Iterates "nicks" when registering
|
int nick_counter; ///< Iterates "nicks" when registering
|
||||||
struct str irc_user_mode; ///< Our current user modes
|
struct str irc_user_modes; ///< Our current user modes
|
||||||
char *irc_user_host; ///< Our current user@host
|
char *irc_user_host; ///< Our current user@host
|
||||||
bool autoaway_active; ///< Autoaway is currently active
|
bool autoaway_active; ///< Autoaway is currently active
|
||||||
|
|
||||||
@ -1889,7 +1889,7 @@ static struct ispect_field g_server_ispect[] =
|
|||||||
// TODO: either rename the underlying field or fix the plugins
|
// TODO: either rename the underlying field or fix the plugins
|
||||||
{ "user", offsetof (struct server, irc_user),
|
{ "user", offsetof (struct server, irc_user),
|
||||||
ISPECT_REF, 0, g_user_ispect, false },
|
ISPECT_REF, 0, g_user_ispect, false },
|
||||||
{ "user_mode", offsetof (struct server, irc_user_mode),
|
{ "user_mode", offsetof (struct server, irc_user_modes),
|
||||||
ISPECT_STR, 0, NULL, false },
|
ISPECT_STR, 0, NULL, false },
|
||||||
|
|
||||||
{}
|
{}
|
||||||
@ -1978,7 +1978,7 @@ server_new (struct poller *poller)
|
|||||||
self->irc_buffer_map = str_map_make (NULL);
|
self->irc_buffer_map = str_map_make (NULL);
|
||||||
self->irc_buffer_map.key_xfrm = irc_strxfrm;
|
self->irc_buffer_map.key_xfrm = irc_strxfrm;
|
||||||
|
|
||||||
self->irc_user_mode = str_make ();
|
self->irc_user_modes = str_make ();
|
||||||
|
|
||||||
self->outstanding_joins = strv_make ();
|
self->outstanding_joins = strv_make ();
|
||||||
self->cap_ls_buf = strv_make ();
|
self->cap_ls_buf = strv_make ();
|
||||||
@ -2025,7 +2025,7 @@ server_destroy (struct server *self)
|
|||||||
|
|
||||||
if (self->irc_user)
|
if (self->irc_user)
|
||||||
user_unref (self->irc_user);
|
user_unref (self->irc_user);
|
||||||
str_free (&self->irc_user_mode);
|
str_free (&self->irc_user_modes);
|
||||||
free (self->irc_user_host);
|
free (self->irc_user_host);
|
||||||
|
|
||||||
strv_free (&self->outstanding_joins);
|
strv_free (&self->outstanding_joins);
|
||||||
@ -2976,6 +2976,45 @@ relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer,
|
|||||||
|
|
||||||
// TODO: Consider pushing this whole block of code much further down.
|
// TODO: Consider pushing this whole block of code much further down.
|
||||||
static void formatter_add (struct formatter *self, const char *format, ...);
|
static void formatter_add (struct formatter *self, const char *format, ...);
|
||||||
|
static char *irc_to_utf8 (const char *text);
|
||||||
|
|
||||||
|
static void
|
||||||
|
relay_prepare_channel_buffer_update (struct app_context *ctx,
|
||||||
|
struct buffer *buffer, struct relay_buffer_context_channel *e)
|
||||||
|
{
|
||||||
|
struct channel *channel = buffer->channel;
|
||||||
|
struct formatter f = formatter_make (ctx, buffer->server);
|
||||||
|
if (channel->topic)
|
||||||
|
formatter_add (&f, "#m", channel->topic);
|
||||||
|
e->topic = relay_items (ctx, f.items, &e->topic_len);
|
||||||
|
formatter_free (&f);
|
||||||
|
|
||||||
|
// As in make_prompt(), conceal the last known channel modes.
|
||||||
|
// XXX: This should use irc_channel_is_joined().
|
||||||
|
if (!channel->users_len)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct str modes = str_make ();
|
||||||
|
str_append_str (&modes, &channel->no_param_modes);
|
||||||
|
|
||||||
|
struct str params = str_make ();
|
||||||
|
struct str_map_iter iter = str_map_iter_make (&channel->param_modes);
|
||||||
|
const char *param;
|
||||||
|
while ((param = str_map_iter_next (&iter)))
|
||||||
|
{
|
||||||
|
str_append_c (&modes, iter.link->key[0]);
|
||||||
|
str_append_c (¶ms, ' ');
|
||||||
|
str_append (¶ms, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
str_append_str (&modes, ¶ms);
|
||||||
|
str_free (¶ms);
|
||||||
|
|
||||||
|
char *modes_utf8 = irc_to_utf8 (modes.str);
|
||||||
|
str_free (&modes);
|
||||||
|
e->modes = str_from_cstr (modes_utf8);
|
||||||
|
free (modes_utf8);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
relay_prepare_buffer_update (struct app_context *ctx, struct buffer *buffer)
|
relay_prepare_buffer_update (struct app_context *ctx, struct buffer *buffer)
|
||||||
@ -2997,18 +3036,10 @@ relay_prepare_buffer_update (struct app_context *ctx, struct buffer *buffer)
|
|||||||
server_name = &e->context.server.server_name;
|
server_name = &e->context.server.server_name;
|
||||||
break;
|
break;
|
||||||
case BUFFER_CHANNEL:
|
case BUFFER_CHANNEL:
|
||||||
{
|
|
||||||
e->context.kind = RELAY_BUFFER_KIND_CHANNEL;
|
e->context.kind = RELAY_BUFFER_KIND_CHANNEL;
|
||||||
server_name = &e->context.channel.server_name;
|
server_name = &e->context.channel.server_name;
|
||||||
|
relay_prepare_channel_buffer_update (ctx, buffer, &e->context.channel);
|
||||||
struct formatter f = formatter_make (ctx, buffer->server);
|
|
||||||
if (buffer->channel->topic)
|
|
||||||
formatter_add (&f, "#m", buffer->channel->topic);
|
|
||||||
e->context.channel.topic =
|
|
||||||
relay_items (ctx, f.items, &e->context.channel.topic_len);
|
|
||||||
formatter_free (&f);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case BUFFER_PM:
|
case BUFFER_PM:
|
||||||
e->context.kind = RELAY_BUFFER_KIND_PRIVATE_MESSAGE;
|
e->context.kind = RELAY_BUFFER_KIND_PRIVATE_MESSAGE;
|
||||||
server_name = &e->context.private_message.server_name;
|
server_name = &e->context.private_message.server_name;
|
||||||
@ -3086,9 +3117,6 @@ relay_server_state_for_server (struct server *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Consider pushing this whole block of code further down.
|
|
||||||
static char *irc_to_utf8 (const char *text);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
relay_prepare_server_update (struct app_context *ctx, struct server *s)
|
relay_prepare_server_update (struct app_context *ctx, struct server *s)
|
||||||
{
|
{
|
||||||
@ -3103,9 +3131,9 @@ relay_prepare_server_update (struct app_context *ctx, struct server *s)
|
|||||||
e->data.registered.user = str_from_cstr (user_utf8);
|
e->data.registered.user = str_from_cstr (user_utf8);
|
||||||
free (user_utf8);
|
free (user_utf8);
|
||||||
|
|
||||||
char *user_mode_utf8 = irc_to_utf8 (s->irc_user_mode.str);
|
char *user_modes_utf8 = irc_to_utf8 (s->irc_user_modes.str);
|
||||||
e->data.registered.user_mode = str_from_cstr (user_mode_utf8);
|
e->data.registered.user_modes = str_from_cstr (user_modes_utf8);
|
||||||
free (user_mode_utf8);
|
free (user_modes_utf8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5311,10 +5339,8 @@ irc_make_channel (struct server *s, char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_channel_set_topic (struct channel *channel, const char *topic)
|
irc_channel_broadcast_buffer_update (const struct channel *channel)
|
||||||
{
|
{
|
||||||
cstr_set (&channel->topic, xstrdup (topic));
|
|
||||||
|
|
||||||
struct server *s = channel->s;
|
struct server *s = channel->s;
|
||||||
struct buffer *buffer = str_map_find (&s->irc_buffer_map, channel->name);
|
struct buffer *buffer = str_map_find (&s->irc_buffer_map, channel->name);
|
||||||
if (buffer)
|
if (buffer)
|
||||||
@ -5324,6 +5350,13 @@ irc_channel_set_topic (struct channel *channel, const char *topic)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
irc_channel_set_topic (struct channel *channel, const char *topic)
|
||||||
|
{
|
||||||
|
cstr_set (&channel->topic, xstrdup (topic));
|
||||||
|
irc_channel_broadcast_buffer_update (channel);
|
||||||
|
}
|
||||||
|
|
||||||
static struct channel_user *
|
static struct channel_user *
|
||||||
irc_channel_get_user (struct channel *channel, struct user *user)
|
irc_channel_get_user (struct channel *channel, struct user *user)
|
||||||
{
|
{
|
||||||
@ -5349,6 +5382,9 @@ irc_left_channel (struct channel *channel)
|
|||||||
|
|
||||||
LIST_FOR_EACH (struct channel_user, iter, channel->users)
|
LIST_FOR_EACH (struct channel_user, iter, channel->users)
|
||||||
irc_channel_unlink_user (channel, iter);
|
irc_channel_unlink_user (channel, iter);
|
||||||
|
|
||||||
|
// Send empty channel modes.
|
||||||
|
irc_channel_broadcast_buffer_update (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@ -5693,7 +5729,7 @@ irc_destroy_state (struct server *s)
|
|||||||
s->irc_user = NULL;
|
s->irc_user = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
str_reset (&s->irc_user_mode);
|
str_reset (&s->irc_user_modes);
|
||||||
cstr_set (&s->irc_user_host, NULL);
|
cstr_set (&s->irc_user_host, NULL);
|
||||||
|
|
||||||
strv_reset (&s->outstanding_joins);
|
strv_reset (&s->outstanding_joins);
|
||||||
@ -6671,7 +6707,7 @@ make_chanmode_postfix (struct channel *channel, struct str *modes)
|
|||||||
str_append (modes, channel->no_param_modes.str);
|
str_append (modes, channel->no_param_modes.str);
|
||||||
|
|
||||||
struct str_map_iter iter = str_map_iter_make (&channel->param_modes);
|
struct str_map_iter iter = str_map_iter_make (&channel->param_modes);
|
||||||
char *param;
|
const char *param;
|
||||||
while ((param = str_map_iter_next (&iter)))
|
while ((param = str_map_iter_next (&iter)))
|
||||||
str_append_c (modes, iter.link->key[0]);
|
str_append_c (modes, iter.link->key[0]);
|
||||||
}
|
}
|
||||||
@ -6688,8 +6724,8 @@ make_server_postfix_registered (struct buffer *buffer, struct str *output)
|
|||||||
irc_get_channel_user_prefix (s, channel_user, output);
|
irc_get_channel_user_prefix (s, channel_user, output);
|
||||||
}
|
}
|
||||||
str_append (output, s->irc_user->nickname);
|
str_append (output, s->irc_user->nickname);
|
||||||
if (s->irc_user_mode.len)
|
if (s->irc_user_modes.len)
|
||||||
str_append_printf (output, "(%s)", s->irc_user_mode.str);
|
str_append_printf (output, "(%s)", s->irc_user_modes.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -6736,7 +6772,7 @@ make_prompt (struct app_context *ctx, struct str *output)
|
|||||||
buffer_get_index (ctx, buffer), buffer->name);
|
buffer_get_index (ctx, buffer), buffer->name);
|
||||||
// We remember old modes, don't show them while we're not on the channel
|
// We remember old modes, don't show them while we're not on the channel
|
||||||
if (buffer->type == BUFFER_CHANNEL
|
if (buffer->type == BUFFER_CHANNEL
|
||||||
&& buffer->channel->users_len)
|
&& irc_channel_is_joined (buffer->channel))
|
||||||
{
|
{
|
||||||
struct str modes = str_make ();
|
struct str modes = str_make ();
|
||||||
make_chanmode_postfix (buffer->channel, &modes);
|
make_chanmode_postfix (buffer->channel, &modes);
|
||||||
@ -7100,7 +7136,11 @@ irc_handle_mode_channel (struct channel *channel, char **params)
|
|||||||
{
|
{
|
||||||
struct mode_processor p = { .s = channel->s, .channel = channel };
|
struct mode_processor p = { .s = channel->s, .channel = channel };
|
||||||
mode_processor_run (&p, params, mode_processor_apply_channel);
|
mode_processor_run (&p, params, mode_processor_apply_channel);
|
||||||
return p.changes == p.usermode_changes;
|
if (p.changes == p.usermode_changes)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
irc_channel_broadcast_buffer_update (channel);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@ -7108,7 +7148,7 @@ irc_handle_mode_channel (struct channel *channel, char **params)
|
|||||||
static bool
|
static bool
|
||||||
mode_processor_apply_user (struct mode_processor *self)
|
mode_processor_apply_user (struct mode_processor *self)
|
||||||
{
|
{
|
||||||
mode_processor_toggle (self, &self->s->irc_user_mode);
|
mode_processor_toggle (self, &self->s->irc_user_modes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8191,7 +8231,7 @@ static void
|
|||||||
irc_on_registered (struct server *s, const char *nickname)
|
irc_on_registered (struct server *s, const char *nickname)
|
||||||
{
|
{
|
||||||
s->irc_user = irc_get_or_make_user (s, nickname);
|
s->irc_user = irc_get_or_make_user (s, nickname);
|
||||||
str_reset (&s->irc_user_mode);
|
str_reset (&s->irc_user_modes);
|
||||||
cstr_set (&s->irc_user_host, NULL);
|
cstr_set (&s->irc_user_host, NULL);
|
||||||
|
|
||||||
irc_set_state (s, IRC_REGISTERED);
|
irc_set_state (s, IRC_REGISTERED);
|
||||||
@ -8262,7 +8302,7 @@ irc_handle_rpl_umodeis (struct server *s, const struct irc_message *msg)
|
|||||||
if (msg->params.len < 2)
|
if (msg->params.len < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
str_reset (&s->irc_user_mode);
|
str_reset (&s->irc_user_modes);
|
||||||
irc_handle_mode_user (s, msg->params.vector + 1);
|
irc_handle_mode_user (s, msg->params.vector + 1);
|
||||||
|
|
||||||
// XXX: do we want to log a message?
|
// XXX: do we want to log a message?
|
||||||
|
@ -328,6 +328,7 @@ rpcEventHandlers.set(Relay.Event.BufferUpdate, e => {
|
|||||||
b.kind = e.context.kind
|
b.kind = e.context.kind
|
||||||
b.server = servers.get(e.context.serverName)
|
b.server = servers.get(e.context.serverName)
|
||||||
b.topic = e.context.topic
|
b.topic = e.context.topic
|
||||||
|
b.modes = e.context.modes
|
||||||
})
|
})
|
||||||
|
|
||||||
rpcEventHandlers.set(Relay.Event.BufferStats, e => {
|
rpcEventHandlers.set(Relay.Event.BufferStats, e => {
|
||||||
@ -702,6 +703,8 @@ let Status = {
|
|||||||
return m('.status', {}, 'Synchronizing...')
|
return m('.status', {}, 'Synchronizing...')
|
||||||
|
|
||||||
let status = `${bufferCurrent}`
|
let status = `${bufferCurrent}`
|
||||||
|
if (b.modes)
|
||||||
|
status += `(+${b.modes})`
|
||||||
if (b.hideUnimportant)
|
if (b.hideUnimportant)
|
||||||
status += `<H>`
|
status += `<H>`
|
||||||
return m('.status', {}, [status, m(Toolbar)])
|
return m('.status', {}, [status, m(Toolbar)])
|
||||||
@ -716,8 +719,8 @@ let Prompt = {
|
|||||||
|
|
||||||
if (b.server.data.user !== undefined) {
|
if (b.server.data.user !== undefined) {
|
||||||
let user = b.server.data.user
|
let user = b.server.data.user
|
||||||
if (b.server.data.userMode)
|
if (b.server.data.userModes)
|
||||||
user += `(${b.server.data.userMode})`
|
user += `(${b.server.data.userModes})`
|
||||||
return m('.prompt', {}, `${user}`)
|
return m('.prompt', {}, `${user}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user