Implement the causal.agency/consumer capability

weechat-hashes
C. McEnroe 2020-02-29 01:03:46 -05:00
parent 78b4832bfe
commit 8570a62235
4 changed files with 32 additions and 6 deletions

View File

@ -1,4 +1,4 @@
.Dd February 23, 2020 .Dd February 29, 2020
.Dt CATGIRL 1 .Dt CATGIRL 1
.Os .Os
. .
@ -658,6 +658,18 @@ join = #ascii.town
.Re .Re
.El .El
. .
.Ss Extensions
The
.Nm
client can take advantage of the
.Sy causal.agency/consumer
vendor-specific IRCv3 capability
implemented by
.Xr pounce 1 .
The consumer position is stored in the
.Cm save
file.
.
.Sh AUTHORS .Sh AUTHORS
.An June Bug Aq Mt june@causal.agency .An June Bug Aq Mt june@causal.agency
. .

3
chat.h
View File

@ -96,6 +96,7 @@ extern struct Network {
} network; } network;
#define ENUM_CAP \ #define ENUM_CAP \
X("causal.agency/consumer", CapConsumer) \
X("extended-join", CapExtendedJoin) \ X("extended-join", CapExtendedJoin) \
X("invite-notify", CapInviteNotify) \ X("invite-notify", CapInviteNotify) \
X("multi-prefix", CapMultiPrefix) \ X("multi-prefix", CapMultiPrefix) \
@ -112,6 +113,7 @@ enum Cap {
extern struct Self { extern struct Self {
bool debug; bool debug;
bool restricted; bool restricted;
size_t pos;
enum Cap caps; enum Cap caps;
char *plain; char *plain;
char *join; char *join;
@ -128,6 +130,7 @@ static inline void set(char **field, const char *value) {
} }
#define ENUM_TAG \ #define ENUM_TAG \
X("causal.agency/pos", TagPos) \
X("time", TagTime) X("time", TagTime)
enum Tag { enum Tag {

View File

@ -126,6 +126,10 @@ static void handleCap(struct Message *msg) {
enum Cap caps = capParse(msg->params[2]); enum Cap caps = capParse(msg->params[2]);
if (!strcmp(msg->params[1], "LS")) { if (!strcmp(msg->params[1], "LS")) {
caps &= ~CapSASL; caps &= ~CapSASL;
if (caps & CapConsumer && self.pos) {
ircFormat("CAP REQ %s=%zu\r\n", CapNames[CapConsumerBit], self.pos);
caps &= ~CapConsumer;
}
if (caps) { if (caps) {
ircFormat("CAP REQ :%s\r\n", capList(caps)); ircFormat("CAP REQ :%s\r\n", capList(caps));
} else { } else {
@ -1019,9 +1023,10 @@ void handle(struct Message msg) {
); );
if (handler) { if (handler) {
handler->fn(&msg); handler->fn(&msg);
return; } else if (strcmp(msg.cmd, "400") >= 0 && strcmp(msg.cmd, "599") <= 0) {
}
if (strcmp(msg.cmd, "400") >= 0 && strcmp(msg.cmd, "599") <= 0) {
handleErrorGeneric(&msg); handleErrorGeneric(&msg);
} }
if (msg.tags[TagPos]) {
self.pos = strtoull(msg.tags[TagPos], NULL, 10);
}
} }

10
ui.c
View File

@ -960,7 +960,8 @@ void uiRead(void) {
static const time_t Signatures[] = { static const time_t Signatures[] = {
0x6C72696774616301, // no heat, unread, unreadWarm 0x6C72696774616301, // no heat, unread, unreadWarm
0x6C72696774616302, 0x6C72696774616302, // no self.pos
0x6C72696774616303,
}; };
static size_t signatureVersion(time_t signature) { static size_t signatureVersion(time_t signature) {
@ -981,7 +982,8 @@ int uiSave(const char *name) {
FILE *file = dataOpen(name, "w"); FILE *file = dataOpen(name, "w");
if (!file) return -1; if (!file) return -1;
if (writeTime(file, Signatures[1])) return -1; if (writeTime(file, Signatures[2])) return -1;
if (writeTime(file, self.pos)) return -1;
for (uint num = 0; num < windows.len; ++num) { for (uint num = 0; num < windows.len; ++num) {
const struct Window *window = windows.ptrs[num]; const struct Window *window = windows.ptrs[num];
if (writeString(file, idNames[window->id])) return -1; if (writeString(file, idNames[window->id])) return -1;
@ -1032,6 +1034,10 @@ void uiLoad(const char *name) {
} }
size_t version = signatureVersion(signature); size_t version = signatureVersion(signature);
if (version > 1) {
self.pos = readTime(file);
}
char *buf = NULL; char *buf = NULL;
size_t cap = 0; size_t cap = 0;
while (0 < readString(file, &buf, &cap)) { while (0 < readString(file, &buf, &cap)) {