commit 2025ea4e39a7ac782c6d0543b7fbdc0c6a249a04
parent 5c0cf35e0b54bce9d7e1862165a0a7359b9afdab
Author: hhvn <dev@hhvn.uk>
Date: Sun, 24 Oct 2021 17:49:56 +0100
handle.c hirc.h main.c nick.c ui.c: rudimentary nicklist
Diffstat:
M | handle.c | | | 36 | +++++++++++++++++++++++++++++------- |
M | hirc.h | | | 1 | + |
M | main.c | | | 15 | +++++++++++---- |
M | nick.c | | | 1 | + |
M | ui.c | | | 42 | +++++++++++++++++++++++++++++------------- |
5 files changed, 71 insertions(+), 24 deletions(-)
diff --git a/handle.c b/handle.c
@@ -14,6 +14,7 @@ struct Handler handlers[] = {
{ "NOTICE", handle_PRIVMSG },
{ "005", handle_ISUPPORT },
{ "353", handle_NAMREPLY },
+ { "366", NULL /* end of names */ },
{ "433", handle_NICKNAMEINUSE },
{ NULL, NULL },
};
@@ -49,10 +50,15 @@ handle_JOIN(char *msg, char **params, struct Server *server, time_t timestamp) {
hist_add(server, server->history, nick, msg, params, Activity_status, timestamp, HIST_LOG);
hist_add(server, chan->history, nick, msg, params, Activity_status, timestamp, HIST_SHOW);
- nick_free(nick);
- selected_server = server;
- selected_channel = chan;
+ if (nick_isself(nick)) {
+ selected_server = server;
+ selected_channel = chan;
+ } else if (selected_channel == chan) {
+ ui_draw_nicklist();
+ }
+
+ nick_free(nick);
}
void
@@ -72,8 +78,12 @@ handle_PART(char *msg, char **params, struct Server *server, time_t timestamp) {
if (nick_isself(nick)) {
chan_setold(chan, 1);
nick_free_list(&chan->nicks);
+ if (chan == selected_channel)
+ selected_channel = NULL;
} else {
nick_remove(&chan->nicks, nick->nick);
+ if (chan == selected_channel)
+ ui_draw_nicklist();
}
hist_add(server, server->history, nick, msg, params, Activity_status, timestamp, HIST_LOG);
@@ -100,6 +110,8 @@ handle_QUIT(char *msg, char **params, struct Server *server, time_t timestamp) {
if (nick_get(&chan->nicks, nick->nick) != NULL) {
nick_remove(&chan->nicks, nick->nick);
hist_add(server, chan->history, nick, msg, params, Activity_status, timestamp, HIST_SHOW);
+ if (chan == selected_channel)
+ ui_draw_nicklist();
}
}
@@ -181,6 +193,7 @@ handle_ISUPPORT(char *msg, char **params, struct Server *server, time_t timestam
void
handle_NAMREPLY(char *msg, char **params, struct Server *server, time_t timestamp) {
struct Channel *chan;
+ struct Nick *oldnick;
char *nick, priv, *target;
char **nicks, **nicksref;
char *supportedprivs;
@@ -198,7 +211,11 @@ handle_NAMREPLY(char *msg, char **params, struct Server *server, time_t timestam
chan = chan_add(server, &server->channels, target);
params++;
- supportedprivs = struntil(support_get(server, "PREFIX"), ')') + 1;
+ supportedprivs = strchr(support_get(server, "PREFIX"), ')');
+ if (supportedprivs == NULL || supportedprivs[0] == '\0')
+ supportedprivs = "";
+ else
+ supportedprivs++;
nicksref = nicks = param_create(*params);
for (; *nicks && **nicks; nicks++) {
@@ -209,11 +226,14 @@ handle_NAMREPLY(char *msg, char **params, struct Server *server, time_t timestam
while (chrcmp(*nick, supportedprivs))
nick++;
}
- if (nick_get(&chan->nicks, nick) != NULL)
- nick_remove(&chan->nicks, nick);
- nick_add(&chan->nicks, nick, priv, server);
+ if ((oldnick = nick_get(&chan->nicks, nick)) == NULL)
+ nick_add(&chan->nicks, nick, priv, server);
+ else
+ oldnick->priv = priv;
}
+ if (selected_channel == chan)
+ ui_draw_nicklist();
param_free(nicksref);
}
@@ -255,6 +275,8 @@ handle_NICK(char *msg, char **params, struct Server *server, time_t timestamp) {
if ((chnick = nick_get(&chan->nicks, nick->nick)) != NULL) {
nick_add(&chan->nicks, newnick, chnick->priv, server);
nick_remove(&chan->nicks, nick->nick);
+ if (selected_channel == chan)
+ ui_draw_nicklist();
}
}
}
diff --git a/hirc.h b/hirc.h
@@ -93,6 +93,7 @@ void ui_init(void);
void ui_read(void);
void ui_redraw(void);
void ui_draw_input(void);
+void ui_draw_nicklist(void);
void ui_error_(char *file, int line, char *format, ...);
#define ui_error(format, ...) ui_error_(__FILE__, __LINE__, format, __VA_ARGS__);
void ui_perror_(char *file, int line, char *str);
diff --git a/main.c b/main.c
@@ -176,6 +176,8 @@ sighandler(int signal) {
int
main(int argc, char **argv) {
+ struct Channel *old_selected_channel;
+ struct Server *old_selected_server;
struct Server *sp;
FILE *file;
struct pollfd fds[] = {
@@ -226,13 +228,18 @@ main(int argc, char **argv) {
}
}
- ui_read();
- wrefresh(nicklist.window);
+ if (old_selected_channel != selected_channel || old_selected_server != selected_server) {
+ ui_draw_nicklist();
+ wrefresh(nicklist.window);
+ }
+
wrefresh(winlist.window);
wrefresh(mainwindow.window);
- /* always refresh input last */
- wrefresh(inputwindow.window);
+ ui_read();
+
+ old_selected_channel = selected_channel;
+ old_selected_server = selected_server;
}
return 0;
diff --git a/nick.c b/nick.c
@@ -177,6 +177,7 @@ nick_remove(struct Nick **head, char *nick) {
if (p->next != NULL)
p->next->prev = p->prev;
nick_free(p);
+
return 1;
}
diff --git a/ui.c b/ui.c
@@ -98,7 +98,6 @@ ui_init(void) {
ui_redraw();
- wprintw(nicklist.window, "nicklist");
wprintw(winlist.window, "winlist");
}
@@ -116,37 +115,32 @@ ui_read(void) {
int key;
switch (key = wgetch(stdscr)) {
+ case ERR:
+ /* this happens due to nodelay */
+ return;
case KEY_RESIZE:
ui_redraw();
- break;
+ return;
case KEY_BACKSPACE:
if (input.counter) {
memmove(&input.string[input.counter - 1],
&input.string[input.counter],
strlen(&input.string[input.counter]) + 1);
input.counter--;
- ui_draw_input();
}
break;
case KEY_LEFT:
- if (input.counter) {
+ if (input.counter)
input.counter--;
- ui_draw_input();
- }
break;
case KEY_RIGHT:
- if (input.string[input.counter]) {
+ if (input.string[input.counter])
input.counter++;
- ui_draw_input();
- }
break;
case '\n':
- exit(0);
- }
command_eval(input.string);
memset(input.string, '\0', sizeof(input.string));
input.counter = 0;
- ui_draw_input();
break;
default:
if (isprint(key) || iscntrl(key)) {
@@ -154,9 +148,10 @@ ui_read(void) {
&input.string[input.counter],
strlen(&input.string[input.counter]));
input.string[input.counter++] = key;
- ui_draw_input();
}
}
+
+ ui_draw_input();
}
void
@@ -212,6 +207,7 @@ ui_redraw(void) {
mvhline(LINES - 2, x, '-', COLS - x - rx);
+ ui_draw_nicklist();
ui_draw_input();
}
@@ -235,4 +231,24 @@ ui_draw_input(void) {
} else waddnstr(inputwindow.window, p, 1);
}
wmove(inputwindow.window, 0, input.counter - offset);
+ wrefresh(inputwindow.window);
+}
+
+void
+ui_draw_nicklist(void) {
+ struct Nick *p;
+
+ wclear(nicklist.window);
+ if (!selected_channel || !nicklist.location)
+ return;
+
+ wmove(nicklist.window, 0, 0);
+
+ /* TODO: sort nicks here
+ * TODO: more nicks than screen height? */
+ for (p = selected_channel->nicks; p; p = p->next) {
+ /* TODO: colourize nicks */
+ wprintw(nicklist.window, "%c%s\n", p->priv, p->nick);
+ }
+ wrefresh(nicklist.window);
}