xC/xP: relay and render channel topics
This commit is contained in:
parent
414859d309
commit
919b12510b
73
xC-proto
73
xC-proto
@ -53,12 +53,12 @@ struct EventMessage {
|
|||||||
u32 event_seq;
|
u32 event_seq;
|
||||||
union EventData switch (enum Event {
|
union EventData switch (enum Event {
|
||||||
PING,
|
PING,
|
||||||
|
BUFFER_LINE,
|
||||||
BUFFER_UPDATE,
|
BUFFER_UPDATE,
|
||||||
BUFFER_STATS,
|
BUFFER_STATS,
|
||||||
BUFFER_RENAME,
|
BUFFER_RENAME,
|
||||||
BUFFER_REMOVE,
|
BUFFER_REMOVE,
|
||||||
BUFFER_ACTIVATE,
|
BUFFER_ACTIVATE,
|
||||||
BUFFER_LINE,
|
|
||||||
BUFFER_CLEAR,
|
BUFFER_CLEAR,
|
||||||
SERVER_UPDATE,
|
SERVER_UPDATE,
|
||||||
SERVER_RENAME,
|
SERVER_RENAME,
|
||||||
@ -69,41 +69,6 @@ struct EventMessage {
|
|||||||
case PING:
|
case PING:
|
||||||
void;
|
void;
|
||||||
|
|
||||||
case BUFFER_UPDATE:
|
|
||||||
string buffer_name;
|
|
||||||
bool hide_unimportant;
|
|
||||||
union BufferContext switch (enum BufferKind {
|
|
||||||
GLOBAL,
|
|
||||||
SERVER,
|
|
||||||
CHANNEL,
|
|
||||||
PRIVATE_MESSAGE,
|
|
||||||
} kind) {
|
|
||||||
case GLOBAL:
|
|
||||||
void;
|
|
||||||
case SERVER:
|
|
||||||
string server_name;
|
|
||||||
case CHANNEL:
|
|
||||||
string server_name;
|
|
||||||
case PRIVATE_MESSAGE:
|
|
||||||
string server_name;
|
|
||||||
} context;
|
|
||||||
case BUFFER_STATS:
|
|
||||||
string buffer_name;
|
|
||||||
// These are cumulative, even for lines flushed out from buffers.
|
|
||||||
// Updates to these values aren't broadcasted, thus handle:
|
|
||||||
// - BUFFER_LINE by bumping/setting them as appropriate,
|
|
||||||
// - BUFFER_ACTIVATE by clearing them for the previous buffer
|
|
||||||
// (this way, they can be used to mark unread messages).
|
|
||||||
u32 new_messages;
|
|
||||||
u32 new_unimportant_messages;
|
|
||||||
bool highlighted;
|
|
||||||
case BUFFER_RENAME:
|
|
||||||
string buffer_name;
|
|
||||||
string new;
|
|
||||||
case BUFFER_REMOVE:
|
|
||||||
string buffer_name;
|
|
||||||
case BUFFER_ACTIVATE:
|
|
||||||
string buffer_name;
|
|
||||||
case BUFFER_LINE:
|
case BUFFER_LINE:
|
||||||
string buffer_name;
|
string buffer_name;
|
||||||
// Whether the line should also be displayed in the active buffer.
|
// Whether the line should also be displayed in the active buffer.
|
||||||
@ -150,6 +115,42 @@ struct EventMessage {
|
|||||||
case FLIP_MONOSPACE:
|
case FLIP_MONOSPACE:
|
||||||
void;
|
void;
|
||||||
} items<>;
|
} items<>;
|
||||||
|
case BUFFER_UPDATE:
|
||||||
|
string buffer_name;
|
||||||
|
bool hide_unimportant;
|
||||||
|
union BufferContext switch (enum BufferKind {
|
||||||
|
GLOBAL,
|
||||||
|
SERVER,
|
||||||
|
CHANNEL,
|
||||||
|
PRIVATE_MESSAGE,
|
||||||
|
} kind) {
|
||||||
|
case GLOBAL:
|
||||||
|
void;
|
||||||
|
case SERVER:
|
||||||
|
string server_name;
|
||||||
|
case CHANNEL:
|
||||||
|
string server_name;
|
||||||
|
ItemData topic<>;
|
||||||
|
case PRIVATE_MESSAGE:
|
||||||
|
string server_name;
|
||||||
|
} context;
|
||||||
|
case BUFFER_STATS:
|
||||||
|
string buffer_name;
|
||||||
|
// These are cumulative, even for lines flushed out from buffers.
|
||||||
|
// Updates to these values aren't broadcasted, thus handle:
|
||||||
|
// - BUFFER_LINE by bumping/setting them as appropriate,
|
||||||
|
// - BUFFER_ACTIVATE by clearing them for the previous buffer
|
||||||
|
// (this way, they can be used to mark unread messages).
|
||||||
|
u32 new_messages;
|
||||||
|
u32 new_unimportant_messages;
|
||||||
|
bool highlighted;
|
||||||
|
case BUFFER_RENAME:
|
||||||
|
string buffer_name;
|
||||||
|
string new;
|
||||||
|
case BUFFER_REMOVE:
|
||||||
|
string buffer_name;
|
||||||
|
case BUFFER_ACTIVATE:
|
||||||
|
string buffer_name;
|
||||||
case BUFFER_CLEAR:
|
case BUFFER_CLEAR:
|
||||||
string buffer_name;
|
string buffer_name;
|
||||||
|
|
||||||
|
205
xC.c
205
xC.c
@ -2883,84 +2883,9 @@ relay_prepare_ping (struct app_context *ctx)
|
|||||||
relay_prepare (ctx)->data.event = RELAY_EVENT_PING;
|
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 *
|
static union relay_item_data *
|
||||||
relay_translate_formatter (struct app_context *ctx, union relay_item_data *p,
|
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.
|
// XXX: See attr_printer_decode_color(), this is a footgun.
|
||||||
int16_t c16 = i->color;
|
int16_t c16 = i->color;
|
||||||
@ -3016,6 +2941,23 @@ relay_translate_formatter (struct app_context *ctx, union relay_item_data *p,
|
|||||||
return 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
|
static void
|
||||||
relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer,
|
relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer,
|
||||||
struct buffer_line *line, bool leak_to_active)
|
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->rendition = 1 + line->r;
|
||||||
e->when = line->when * 1000;
|
e->when = line->when * 1000;
|
||||||
e->leak_to_active = leak_to_active;
|
e->leak_to_active = leak_to_active;
|
||||||
|
e->items = relay_items (ctx, line->items, &e->items_len);
|
||||||
|
}
|
||||||
|
|
||||||
size_t len = 0;
|
// TODO: Consider pushing this whole block of code much further down.
|
||||||
for (size_t i = 0; line->items[i].type; i++)
|
static void formatter_add (struct formatter *self, const char *format, ...);
|
||||||
len++;
|
|
||||||
|
|
||||||
// Beware of the upper bound, currently dominated by FORMATTER_ITEM_ATTR.
|
static void
|
||||||
union relay_item_data *p = e->items = xcalloc (len * 9, sizeof *e->items);
|
relay_prepare_buffer_update (struct app_context *ctx, struct buffer *buffer)
|
||||||
for (struct formatter_item *i = line->items; len--; i++)
|
{
|
||||||
p = relay_translate_formatter (ctx, p, i);
|
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
|
static void
|
||||||
@ -5291,6 +5310,20 @@ irc_make_channel (struct server *s, char *name)
|
|||||||
return channel;
|
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 *
|
static struct channel_user *
|
||||||
irc_channel_get_user (struct channel *channel, struct user *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
|
// It would be weird for this to be false
|
||||||
if (channel)
|
if (channel)
|
||||||
cstr_set (&channel->topic, xstrdup (topic));
|
irc_channel_set_topic (channel, topic);
|
||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
{
|
{
|
||||||
@ -8486,7 +8519,7 @@ irc_handle_rpl_topic (struct server *s, const struct irc_message *msg)
|
|||||||
hard_assert (channel || !buffer);
|
hard_assert (channel || !buffer);
|
||||||
|
|
||||||
if (channel)
|
if (channel)
|
||||||
cstr_set (&channel->topic, xstrdup (topic));
|
irc_channel_set_topic (channel, topic);
|
||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
log_server_status (s, buffer, "The topic is: #m", topic);
|
log_server_status (s, buffer, "The topic is: #m", topic);
|
||||||
|
@ -30,11 +30,16 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
|
column-gap: .3em;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
border-top: 3px solid #ccc;
|
border-top: 3px solid #ccc;
|
||||||
border-bottom: 2px solid #888;
|
border-bottom: 2px solid #888;
|
||||||
}
|
}
|
||||||
|
.title {
|
||||||
|
/* To approximate right-aligned space-between. */
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
.title:before, .status:before {
|
.title:before, .status:before {
|
||||||
content: " ";
|
content: " ";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -57,7 +62,7 @@ body {
|
|||||||
.toolbar {
|
.toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
gap: .3em;
|
column-gap: .3em;
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
font: inherit;
|
font: inherit;
|
||||||
@ -129,11 +134,13 @@ button:hover:active {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.log, .content {
|
.log, .content {
|
||||||
padding: .1em .3em;
|
|
||||||
/* Note: https://bugs.chromium.org/p/chromium/issues/detail?id=1261435 */
|
/* Note: https://bugs.chromium.org/p/chromium/issues/detail?id=1261435 */
|
||||||
white-space: break-spaces;
|
white-space: break-spaces;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
.log, .buffer .content {
|
||||||
|
padding: .1em .3em;
|
||||||
|
}
|
||||||
|
|
||||||
.leaked {
|
.leaked {
|
||||||
opacity: 50%;
|
opacity: 50%;
|
||||||
|
107
xP/public/xP.js
107
xP/public/xP.js
@ -254,12 +254,58 @@ rpc.addEventListener('event', event => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
rpcEventHandlers['Ping'] = e => {
|
rpcEventHandlers.set(Relay.Event.Ping, e => {
|
||||||
rpc.send({command: 'PingResponse', eventSeq: e.eventSeq})
|
rpc.send({command: 'PingResponse', eventSeq: e.eventSeq})
|
||||||
}
|
})
|
||||||
|
|
||||||
// ~~~ Buffer events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~ Buffer events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
rpcEventHandlers.set(Relay.Event.BufferLine, e => {
|
||||||
|
let b = buffers.get(e.bufferName), line = {...e}
|
||||||
|
delete line.event
|
||||||
|
delete line.eventSeq
|
||||||
|
delete line.leakToActive
|
||||||
|
if (b === undefined)
|
||||||
|
return
|
||||||
|
|
||||||
|
// Initial sync: skip all other processing, let highlights be.
|
||||||
|
if (bufferCurrent === undefined) {
|
||||||
|
b.lines.push(line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let visible = document.visibilityState !== 'hidden' &&
|
||||||
|
bufferLog === undefined &&
|
||||||
|
bufferAutoscroll &&
|
||||||
|
(e.bufferName == bufferCurrent || e.leakToActive)
|
||||||
|
b.lines.push({...line})
|
||||||
|
if (!(visible || e.leakToActive) ||
|
||||||
|
b.newMessages || b.newUnimportantMessages) {
|
||||||
|
if (line.isUnimportant)
|
||||||
|
b.newUnimportantMessages++
|
||||||
|
else
|
||||||
|
b.newMessages++
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.leakToActive) {
|
||||||
|
let bc = buffers.get(bufferCurrent)
|
||||||
|
bc.lines.push({...line, leaked: true})
|
||||||
|
if (!visible || bc.newMessages || bc.newUnimportantMessages) {
|
||||||
|
if (line.isUnimportant)
|
||||||
|
bc.newUnimportantMessages++
|
||||||
|
else
|
||||||
|
bc.newMessages++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.isHighlight || (!visible && !line.isUnimportant &&
|
||||||
|
b.kind === Relay.BufferKind.PrivateMessage)) {
|
||||||
|
beep()
|
||||||
|
if (!visible)
|
||||||
|
b.highlighted = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
rpcEventHandlers.set(Relay.Event.BufferUpdate, e => {
|
rpcEventHandlers.set(Relay.Event.BufferUpdate, e => {
|
||||||
let b = buffers.get(e.bufferName)
|
let b = buffers.get(e.bufferName)
|
||||||
if (b === undefined) {
|
if (b === undefined) {
|
||||||
@ -274,6 +320,7 @@ rpcEventHandlers.set(Relay.Event.BufferUpdate, e => {
|
|||||||
b.hideUnimportant = e.hideUnimportant
|
b.hideUnimportant = e.hideUnimportant
|
||||||
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
|
||||||
})
|
})
|
||||||
|
|
||||||
rpcEventHandlers.set(Relay.Event.BufferStats, e => {
|
rpcEventHandlers.set(Relay.Event.BufferStats, e => {
|
||||||
@ -332,52 +379,6 @@ rpcEventHandlers.set(Relay.Event.BufferActivate, e => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
rpcEventHandlers.set(Relay.Event.BufferLine, e => {
|
|
||||||
let b = buffers.get(e.bufferName), line = {...e}
|
|
||||||
delete line.event
|
|
||||||
delete line.eventSeq
|
|
||||||
delete line.leakToActive
|
|
||||||
if (b === undefined)
|
|
||||||
return
|
|
||||||
|
|
||||||
// Initial sync: skip all other processing, let highlights be.
|
|
||||||
if (bufferCurrent === undefined) {
|
|
||||||
b.lines.push(line)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let visible = document.visibilityState !== 'hidden' &&
|
|
||||||
bufferLog === undefined &&
|
|
||||||
bufferAutoscroll &&
|
|
||||||
(e.bufferName == bufferCurrent || e.leakToActive)
|
|
||||||
b.lines.push({...line})
|
|
||||||
if (!(visible || e.leakToActive) ||
|
|
||||||
b.newMessages || b.newUnimportantMessages) {
|
|
||||||
if (line.isUnimportant)
|
|
||||||
b.newUnimportantMessages++
|
|
||||||
else
|
|
||||||
b.newMessages++
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.leakToActive) {
|
|
||||||
let bc = buffers.get(bufferCurrent)
|
|
||||||
bc.lines.push({...line, leaked: true})
|
|
||||||
if (!visible || bc.newMessages || bc.newUnimportantMessages) {
|
|
||||||
if (line.isUnimportant)
|
|
||||||
bc.newUnimportantMessages++
|
|
||||||
else
|
|
||||||
bc.newMessages++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.isHighlight || (!visible && !line.isUnimportant &&
|
|
||||||
b.kind === Relay.BufferKind.PrivateMessage)) {
|
|
||||||
beep()
|
|
||||||
if (!visible)
|
|
||||||
b.highlighted = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
rpcEventHandlers.set(Relay.Event.BufferClear, e => {
|
rpcEventHandlers.set(Relay.Event.BufferClear, e => {
|
||||||
let b = buffers.get(e.bufferName)
|
let b = buffers.get(e.bufferName)
|
||||||
if (b !== undefined)
|
if (b !== undefined)
|
||||||
@ -548,6 +549,14 @@ let Content = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Topic = {
|
||||||
|
view: vnode => {
|
||||||
|
let b = buffers.get(bufferCurrent)
|
||||||
|
if (b !== undefined && b.topic !== undefined)
|
||||||
|
return m(Content, {}, {items: b.topic})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
let Buffer = {
|
let Buffer = {
|
||||||
controller: new AbortController(),
|
controller: new AbortController(),
|
||||||
|
|
||||||
@ -945,7 +954,7 @@ let Main = {
|
|||||||
|
|
||||||
return m('.xP', {}, [
|
return m('.xP', {}, [
|
||||||
overlay,
|
overlay,
|
||||||
m('.title', {}, `xP`),
|
m('.title', {}, [m('b', {}, `xP`), m(Topic)]),
|
||||||
m('.middle', {}, [m(BufferList), m(BufferContainer)]),
|
m('.middle', {}, [m(BufferList), m(BufferContainer)]),
|
||||||
m(Status),
|
m(Status),
|
||||||
m('.input', {}, [m(Prompt), m(Input)]),
|
m('.input', {}, [m(Prompt), m(Input)]),
|
||||||
|
Loading…
Reference in New Issue
Block a user