about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-02-02 03:13:50 -0500
committerJune McEnroe <june@causal.agency>2020-02-02 03:13:50 -0500
commitec83332e15d31c1ffbb7112ff6743f2a5c815c71 (patch)
tree13c8812f90e5c3a830063144f47a8b3cb33e2719
parentPreserve copyright year in term.c (diff)
downloadcatgirl-ec83332e15d31c1ffbb7112ff6743f2a5c815c71.tar.gz
catgirl-ec83332e15d31c1ffbb7112ff6743f2a5c815c71.zip
Implement window switching and status line
-rw-r--r--chat.c15
-rw-r--r--chat.h1
-rw-r--r--handle.c22
-rw-r--r--ui.c34
4 files changed, 56 insertions, 16 deletions
diff --git a/chat.c b/chat.c
index ceaf1b5..d4ed31c 100644
--- a/chat.c
+++ b/chat.c
@@ -76,19 +76,8 @@ int main(int argc, char *argv[]) {
 	ircConfig(insecure, cert, priv);
 
 	uiInit();
-	uiFormat(Network, Cold, NULL, C "3Trave" U "ling" U C "0,3.." C "0,4." R);
-	uiFormat(
-		Network, Cold, NULL,
-		"Jackdaws love my big sphinx of quartz. "
-		"The quick brown fox jumps over the lazy dog. "
-		"Jackdaws love my big sphinx of quartz. "
-		"Jackdaws love my big sphinx of quartz. "
-		"Jackdaws love my big sphinx of quartz. "
-		"The quick brown fox jumps over the lazy dog. "
-		"The quick brown fox jumps over the lazy dog. "
-		"Jackdaws love my big sphinx of quartz. "
-		"Jackdaws love my big sphinx of quartz. "
-	);
+	uiShowID(Network);
+	uiFormat(Network, Cold, NULL, "Traveling...");
 	uiDraw();
 	
 	int irc = ircConnect(host, port);
diff --git a/chat.h b/chat.h
index fc5043d..9060f29 100644
--- a/chat.h
+++ b/chat.h
@@ -117,6 +117,7 @@ void handle(struct Message msg);
 enum Heat { Cold, Warm, Hot };
 void uiInit(void);
 void uiDraw(void);
+void uiShowID(size_t id);
 void uiWrite(size_t id, enum Heat heat, const struct tm *time, const char *str);
 void uiFormat(
 	size_t id, enum Heat heat, const struct tm *time, const char *format, ...
diff --git a/handle.c b/handle.c
index 350a636..609867e 100644
--- a/handle.c
+++ b/handle.c
@@ -65,9 +65,11 @@ static void set(char **field, const char *value) {
 	if (!*field) err(EX_OSERR, "strdup");
 }
 
-static void require(const struct Message *msg, bool origin, size_t len) {
-	if (origin && !msg->nick) {
-		errx(EX_PROTOCOL, "%s missing origin", msg->cmd);
+static void require(struct Message *msg, bool origin, size_t len) {
+	if (origin) {
+		if (!msg->nick) errx(EX_PROTOCOL, "%s missing origin", msg->cmd);
+		if (!msg->user) msg->user = msg->nick;
+		if (!msg->host) msg->host = msg->user;
 	}
 	for (size_t i = 0; i < len; ++i) {
 		if (msg->params[i]) continue;
@@ -177,6 +179,19 @@ static void handleReplyMOTD(struct Message *msg) {
 	uiFormat(Network, Cold, tagTime(msg), "%s", line);
 }
 
+static void handleJoin(struct Message *msg) {
+	require(msg, true, 1);
+	size_t id = idFor(msg->params[0]);
+	if (self.nick && !strcmp(msg->nick, self.nick)) {
+		uiShowID(id);
+	}
+	uiFormat(
+		id, Cold, tagTime(msg),
+		C"%02d%s"C" arrives in "C"%02d%s"C,
+		hash(msg->user), msg->nick, hash(idNames[id]), idNames[id]
+	);
+}
+
 static void handlePing(struct Message *msg) {
 	require(msg, false, 1);
 	ircFormat("PONG :%s\r\n", msg->params[0]);
@@ -197,6 +212,7 @@ static const struct Handler {
 	{ "906", handleErrorSASLFail },
 	{ "AUTHENTICATE", handleAuthenticate },
 	{ "CAP", handleCap },
+	{ "JOIN", handleJoin },
 	{ "PING", handlePing },
 };
 
diff --git a/ui.c b/ui.c
index 90ba726..3ae6592 100644
--- a/ui.c
+++ b/ui.c
@@ -262,6 +262,40 @@ static void styleAdd(WINDOW *win, const char *str) {
 	}
 }
 
+static void statusUpdate(void) {
+	wmove(status, 0, 0);
+	int num;
+	const struct Window *window;
+	for (num = 0, window = windows.head; window; ++num, window = window->next) {
+		if (!window->unread && window != windows.active) continue;
+		enum Color color = hash(idNames[window->id]); // FIXME: queries.
+		int unread;
+		char buf[256];
+		snprintf(
+			buf, sizeof(buf), C"%d%s %d %s %n("C"%02d%d"C"%d) ",
+			color, (window == windows.active ? V : ""),
+			num, idNames[window->id],
+			&unread, (window->heat > Warm ? White : color), window->unread,
+			color
+		);
+		if (!window->unread) buf[unread] = '\0';
+		styleAdd(status, buf);
+	}
+	wclrtoeol(status);
+}
+
+void uiShowID(size_t id) {
+	struct Window *window = windowFor(id);
+	window->heat = Cold;
+	window->unread = 0;
+	window->mark = false;
+	if (windows.active) windows.active->mark = true;
+	windows.other = windows.active;
+	windows.active = window;
+	touchwin(window->pad);
+	statusUpdate();
+}
+
 void uiWrite(size_t id, enum Heat heat, const struct tm *time, const char *str) {
 	(void)time;
 	struct Window *window = windowFor(id);