xC/xP: relay and render channel topics

This commit is contained in:
2022-09-21 12:13:30 +02:00
parent 414859d309
commit 919b12510b
4 changed files with 223 additions and 173 deletions

205
xC.c
View File

@@ -2883,84 +2883,9 @@ relay_prepare_ping (struct app_context *ctx)
relay_prepare (ctx)->data.event = RELAY_EVENT_PING;
}
static void
relay_prepare_buffer_update (struct app_context *ctx, struct buffer *buffer)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_update *e = &m->data.buffer_update;
e->event = RELAY_EVENT_BUFFER_UPDATE;
e->buffer_name = str_from_cstr (buffer->name);
e->hide_unimportant = buffer->hide_unimportant;
struct str *server_name = NULL;
switch (buffer->type)
{
case BUFFER_GLOBAL:
e->context.kind = RELAY_BUFFER_KIND_GLOBAL;
break;
case BUFFER_SERVER:
e->context.kind = RELAY_BUFFER_KIND_SERVER;
server_name = &e->context.server.server_name;
break;
case BUFFER_CHANNEL:
e->context.kind = RELAY_BUFFER_KIND_CHANNEL;
server_name = &e->context.channel.server_name;
break;
case BUFFER_PM:
e->context.kind = RELAY_BUFFER_KIND_PRIVATE_MESSAGE;
server_name = &e->context.private_message.server_name;
break;
}
if (server_name)
*server_name = str_from_cstr (buffer->server->name);
}
static void
relay_prepare_buffer_stats (struct app_context *ctx, struct buffer *buffer)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_stats *e = &m->data.buffer_stats;
e->event = RELAY_EVENT_BUFFER_STATS;
e->buffer_name = str_from_cstr (buffer->name);
e->new_messages = MIN (UINT32_MAX,
buffer->new_messages_count - buffer->new_unimportant_count);
e->new_unimportant_messages = MIN (UINT32_MAX,
buffer->new_unimportant_count);
e->highlighted = buffer->highlighted;
}
static void
relay_prepare_buffer_rename (struct app_context *ctx, struct buffer *buffer,
const char *new_name)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_rename *e = &m->data.buffer_rename;
e->event = RELAY_EVENT_BUFFER_RENAME;
e->buffer_name = str_from_cstr (buffer->name);
e->new = str_from_cstr (new_name);
}
static void
relay_prepare_buffer_remove (struct app_context *ctx, struct buffer *buffer)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_remove *e = &m->data.buffer_remove;
e->event = RELAY_EVENT_BUFFER_REMOVE;
e->buffer_name = str_from_cstr (buffer->name);
}
static void
relay_prepare_buffer_activate (struct app_context *ctx, struct buffer *buffer)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_activate *e = &m->data.buffer_activate;
e->event = RELAY_EVENT_BUFFER_ACTIVATE;
e->buffer_name = str_from_cstr (buffer->name);
}
static union relay_item_data *
relay_translate_formatter (struct app_context *ctx, union relay_item_data *p,
struct formatter_item *i)
const struct formatter_item *i)
{
// XXX: See attr_printer_decode_color(), this is a footgun.
int16_t c16 = i->color;
@@ -3016,6 +2941,23 @@ relay_translate_formatter (struct app_context *ctx, union relay_item_data *p,
return p;
}
static union relay_item_data *
relay_items (struct app_context *ctx, const struct formatter_item *items,
uint32_t *len)
{
size_t items_len = 0;
for (size_t i = 0; items[i].type; i++)
items_len++;
// Beware of the upper bound, currently dominated by FORMATTER_ITEM_ATTR.
union relay_item_data *a = xcalloc (items_len * 9, sizeof *a), *p = a;
for (const struct formatter_item *i = items; items_len--; i++)
p = relay_translate_formatter (ctx, p, i);
*len = p - a;
return a;
}
static void
relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer,
struct buffer_line *line, bool leak_to_active)
@@ -3029,17 +2971,94 @@ relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer,
e->rendition = 1 + line->r;
e->when = line->when * 1000;
e->leak_to_active = leak_to_active;
e->items = relay_items (ctx, line->items, &e->items_len);
}
size_t len = 0;
for (size_t i = 0; line->items[i].type; i++)
len++;
// TODO: Consider pushing this whole block of code much further down.
static void formatter_add (struct formatter *self, const char *format, ...);
// Beware of the upper bound, currently dominated by FORMATTER_ITEM_ATTR.
union relay_item_data *p = e->items = xcalloc (len * 9, sizeof *e->items);
for (struct formatter_item *i = line->items; len--; i++)
p = relay_translate_formatter (ctx, p, i);
static void
relay_prepare_buffer_update (struct app_context *ctx, struct buffer *buffer)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_update *e = &m->data.buffer_update;
e->event = RELAY_EVENT_BUFFER_UPDATE;
e->buffer_name = str_from_cstr (buffer->name);
e->hide_unimportant = buffer->hide_unimportant;
e->items_len = p - e->items;
struct str *server_name = NULL;
switch (buffer->type)
{
case BUFFER_GLOBAL:
e->context.kind = RELAY_BUFFER_KIND_GLOBAL;
break;
case BUFFER_SERVER:
e->context.kind = RELAY_BUFFER_KIND_SERVER;
server_name = &e->context.server.server_name;
break;
case BUFFER_CHANNEL:
{
e->context.kind = RELAY_BUFFER_KIND_CHANNEL;
server_name = &e->context.channel.server_name;
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;
}
case BUFFER_PM:
e->context.kind = RELAY_BUFFER_KIND_PRIVATE_MESSAGE;
server_name = &e->context.private_message.server_name;
break;
}
if (server_name)
*server_name = str_from_cstr (buffer->server->name);
}
static void
relay_prepare_buffer_stats (struct app_context *ctx, struct buffer *buffer)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_stats *e = &m->data.buffer_stats;
e->event = RELAY_EVENT_BUFFER_STATS;
e->buffer_name = str_from_cstr (buffer->name);
e->new_messages = MIN (UINT32_MAX,
buffer->new_messages_count - buffer->new_unimportant_count);
e->new_unimportant_messages = MIN (UINT32_MAX,
buffer->new_unimportant_count);
e->highlighted = buffer->highlighted;
}
static void
relay_prepare_buffer_rename (struct app_context *ctx, struct buffer *buffer,
const char *new_name)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_rename *e = &m->data.buffer_rename;
e->event = RELAY_EVENT_BUFFER_RENAME;
e->buffer_name = str_from_cstr (buffer->name);
e->new = str_from_cstr (new_name);
}
static void
relay_prepare_buffer_remove (struct app_context *ctx, struct buffer *buffer)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_remove *e = &m->data.buffer_remove;
e->event = RELAY_EVENT_BUFFER_REMOVE;
e->buffer_name = str_from_cstr (buffer->name);
}
static void
relay_prepare_buffer_activate (struct app_context *ctx, struct buffer *buffer)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_activate *e = &m->data.buffer_activate;
e->event = RELAY_EVENT_BUFFER_ACTIVATE;
e->buffer_name = str_from_cstr (buffer->name);
}
static void
@@ -5291,6 +5310,20 @@ irc_make_channel (struct server *s, char *name)
return channel;
}
static void
irc_channel_set_topic (struct channel *channel, const char *topic)
{
cstr_set (&channel->topic, xstrdup (topic));
struct server *s = channel->s;
struct buffer *buffer = str_map_find (&s->irc_buffer_map, channel->name);
if (buffer)
{
relay_prepare_buffer_update (s->ctx, buffer);
relay_broadcast (s->ctx);
}
}
static struct channel_user *
irc_channel_get_user (struct channel *channel, struct user *user)
{
@@ -8074,7 +8107,7 @@ irc_handle_topic (struct server *s, const struct irc_message *msg)
// It would be weird for this to be false
if (channel)
cstr_set (&channel->topic, xstrdup (topic));
irc_channel_set_topic (channel, topic);
if (buffer)
{
@@ -8486,7 +8519,7 @@ irc_handle_rpl_topic (struct server *s, const struct irc_message *msg)
hard_assert (channel || !buffer);
if (channel)
cstr_set (&channel->topic, xstrdup (topic));
irc_channel_set_topic (channel, topic);
if (buffer)
log_server_status (s, buffer, "The topic is: #m", topic);