Add /query, /part and /close

Closing a channel before parting it is a bit weird, but if I send a PART
on /close, it would get reopened again to show the part message.
master
Curtis McEnroe 2018-08-13 13:49:03 -04:00
parent 1232ce451d
commit 2ae5b6b9ab
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
4 changed files with 88 additions and 23 deletions

1
chat.h
View File

@ -93,6 +93,7 @@ void uiDraw(void);
void uiRead(void); void uiRead(void);
void uiViewTag(struct Tag tag); void uiViewTag(struct Tag tag);
void uiViewNum(int num); void uiViewNum(int num);
void uiCloseTag(struct Tag tag);
void uiTopic(struct Tag tag, const char *topic); void uiTopic(struct Tag tag, const char *topic);
void uiLog(struct Tag tag, const wchar_t *line); void uiLog(struct Tag tag, const wchar_t *line);
void uiFmt(struct Tag tag, const wchar_t *format, ...); void uiFmt(struct Tag tag, const wchar_t *format, ...);

View File

@ -122,12 +122,15 @@ static void handleJoin(char *prefix, char *params) {
char *nick, *user, *chan; char *nick, *user, *chan;
shift(prefix, &nick, &user, NULL, params, 1, 0, &chan); shift(prefix, &nick, &user, NULL, params, 1, 0, &chan);
struct Tag tag = tagFor(chan); struct Tag tag = tagFor(chan);
if (isSelf(nick, user)) {
tabTouch(TAG_NONE, chan);
uiViewTag(tag);
}
tabTouch(tag, nick); tabTouch(tag, nick);
uiFmt( uiFmt(
tag, "\3%d%s\3 arrives in \3%d%s\3", tag, "\3%d%s\3 arrives in \3%d%s\3",
color(user), nick, color(chan), chan color(user), nick, color(chan), chan
); );
if (isSelf(nick, user)) uiViewTag(tag);
} }
static void handlePart(char *prefix, char *params) { static void handlePart(char *prefix, char *params) {

24
input.c
View File

@ -64,6 +64,21 @@ static void inputJoin(struct Tag tag, char *params) {
ircFmt("JOIN %s\r\n", chan); ircFmt("JOIN %s\r\n", chan);
} }
static void inputPart(struct Tag tag, char *params) {
if (params) {
ircFmt("PART %s :%s\r\n", tag.name, params);
} else {
ircFmt("PART %s :Goodbye\r\n", tag.name);
}
}
static void inputQuery(struct Tag tag, char *params) {
(void)tag;
char *nick = param("/query", &params, "name");
tabTouch(TAG_NONE, nick);
uiViewTag(tagFor(nick));
}
static void inputWho(struct Tag tag, char *params) { static void inputWho(struct Tag tag, char *params) {
(void)params; (void)params;
ircFmt("WHO %s\r\n", tag.name); ircFmt("WHO %s\r\n", tag.name);
@ -113,15 +128,24 @@ static void inputView(struct Tag tag, char *params) {
} }
} }
static void inputClose(struct Tag tag, char *params) {
(void)params;
uiCloseTag(tag);
tabRemove(TAG_NONE, tag.name);
}
static const struct { static const struct {
const char *command; const char *command;
Handler handler; Handler handler;
} COMMANDS[] = { } COMMANDS[] = {
{ "/close", inputClose },
{ "/join", inputJoin }, { "/join", inputJoin },
{ "/me", inputMe }, { "/me", inputMe },
{ "/names", inputWho }, { "/names", inputWho },
{ "/nick", inputNick }, { "/nick", inputNick },
{ "/open", inputOpen }, { "/open", inputOpen },
{ "/part", inputPart },
{ "/query", inputQuery },
{ "/quit", inputQuit }, { "/quit", inputQuit },
{ "/topic", inputTopic }, { "/topic", inputTopic },
{ "/url", inputUrl }, { "/url", inputUrl },

81
ui.c
View File

@ -70,11 +70,7 @@ static short pair8(short pair) {
return (pair & 0x70) >> 1 | (pair & 0x07); return (pair & 0x70) >> 1 | (pair & 0x07);
} }
static const int LOG_LINES = 256; struct View {
static const int TOPIC_COLS = 512;
static const int INPUT_COLS = 512;
static struct View {
struct Tag tag; struct Tag tag;
WINDOW *topic; WINDOW *topic;
WINDOW *log; WINDOW *log;
@ -82,16 +78,35 @@ static struct View {
bool mark; bool mark;
struct View *prev; struct View *prev;
struct View *next; struct View *next;
} *viewHead, *viewTail; };
static struct {
struct View *head;
struct View *tail;
struct View *tags[TAGS_LEN];
} views;
static void viewAppend(struct View *view) { static void viewAppend(struct View *view) {
if (viewTail) viewTail->next = view; if (views.tail) views.tail->next = view;
view->prev = viewTail; view->prev = views.tail;
view->next = NULL; view->next = NULL;
viewTail = view; if (!views.head) views.head = view;
if (!viewHead) viewHead = view; views.tail = view;
views.tags[view->tag.id] = view;
} }
static void viewRemove(struct View *view) {
if (view->prev) view->prev->next = view->next;
if (view->next) view->next->prev = view->prev;
if (views.head == view) views.head = view->next;
if (views.tail == view) views.tail = view->prev;
views.tags[view->tag.id] = NULL;
}
static const int LOG_LINES = 256;
static const int TOPIC_COLS = 512;
static const int INPUT_COLS = 512;
static int logHeight(const struct View *view) { static int logHeight(const struct View *view) {
return LINES - (view->topic ? 2 : 0) - 2; return LINES - (view->topic ? 2 : 0) - 2;
} }
@ -105,15 +120,8 @@ static int lastCol(void) {
return COLS - 1; return COLS - 1;
} }
static struct {
bool hide;
WINDOW *input;
struct View *view;
struct View *tags[TAGS_LEN];
} ui;
static struct View *viewTag(struct Tag tag) { static struct View *viewTag(struct Tag tag) {
struct View *view = ui.tags[tag.id]; struct View *view = views.tags[tag.id];
if (view) return view; if (view) return view;
view = calloc(1, sizeof(*view)); view = calloc(1, sizeof(*view));
@ -127,10 +135,22 @@ static struct View *viewTag(struct Tag tag) {
view->scroll = LOG_LINES; view->scroll = LOG_LINES;
viewAppend(view); viewAppend(view);
ui.tags[tag.id] = view;
return view; return view;
} }
static void viewClose(struct View *view) {
viewRemove(view);
if (view->topic) delwin(view->topic);
delwin(view->log);
free(view);
}
static struct {
bool hide;
struct View *view;
WINDOW *input;
} ui;
void uiHide(void) { void uiHide(void) {
ui.hide = true; ui.hide = true;
termMode(TERM_FOCUS, false); termMode(TERM_FOCUS, false);
@ -170,7 +190,7 @@ void uiExit(void) {
} }
static void uiResize(void) { static void uiResize(void) {
for (struct View *view = viewHead; view; view = view->next) { for (struct View *view = views.head; view; view = view->next) {
wresize(view->log, LOG_LINES, COLS); wresize(view->log, LOG_LINES, COLS);
wmove(view->log, lastLogLine(), lastCol()); wmove(view->log, lastLogLine(), lastCol());
} }
@ -215,19 +235,36 @@ static void uiView(struct View *view) {
ui.view = view; ui.view = view;
} }
static void uiClose(struct View *view) {
if (ui.view == view) {
if (view->next) {
uiView(view->next);
} else if (view->prev) {
uiView(view->prev);
} else {
return;
}
}
viewClose(view);
}
void uiViewTag(struct Tag tag) { void uiViewTag(struct Tag tag) {
uiView(viewTag(tag)); uiView(viewTag(tag));
} }
void uiCloseTag(struct Tag tag) {
uiClose(viewTag(tag));
}
void uiViewNum(int num) { void uiViewNum(int num) {
if (num < 0) { if (num < 0) {
for (struct View *view = viewTail; view; view = view->prev) { for (struct View *view = views.tail; view; view = view->prev) {
if (++num) continue; if (++num) continue;
uiView(view); uiView(view);
break; break;
} }
} else { } else {
for (struct View *view = viewHead; view; view = view->next) { for (struct View *view = views.head; view; view = view->next) {
if (num--) continue; if (num--) continue;
uiView(view); uiView(view);
break; break;