From 3aabb78d1023d6c0e4745cc10a0a67c620143653 Mon Sep 17 00:00:00 2001 From: sijanec Date: Mon, 22 Mar 2021 18:25:00 +0100 Subject: update 0.0.1 --- src/ui.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 124 insertions(+), 39 deletions(-) (limited to 'src/ui.c') diff --git a/src/ui.c b/src/ui.c index 7bcd070..22aff0e 100644 --- a/src/ui.c +++ b/src/ui.c @@ -12,19 +12,26 @@ #include #define DC_SIMPLEPRINT(w, c, f, ...) do { wattron(w, COLOR_PAIR(c)); wprintw(w, f __VA_OPT__(,) __VA_ARGS__); wrefresh(w); } while (0) /* link with -lncursesw and -lformw */ +void dc_null() { + return; /* a simple null function */ +} int dc_ui_print_message (WINDOW * textwin, struct dc_message * msg2do) { char timestring[64]; struct tm timestruct; localtime_r(&msg2do->time, ×truct); strftime(timestring, 64, DC_I18N_MSGTIMEF, ×truct); /* recimo, da je 23 znakov */ - DC_SIMPLEPRINT(textwin, 3, "%018.18s %08.8s: %s\n", timestring, msg2do->username, msg2do->content); + DC_SIMPLEPRINT(textwin, 1, "#%012.12s ", msg2do->channel->name); + DC_SIMPLEPRINT(textwin, 2, "%018.18s ", timestring); + DC_SIMPLEPRINT(textwin, 4, "%08.8s: ", msg2do->username); + DC_SIMPLEPRINT(textwin, 3, "%s\n", msg2do->content); msg2do->status = 1; return 1; } int dc_ui_processline (struct dc_thread_control * t, char * l, WINDOW * textwin) { struct dc_client * c = t->clients[0]; /* first we trim spaces at the end */ - int i, j, k; + int i = 0, j = 0, k = 0, m = 0, n = 0; + char * jp; for (i = strlen(l)-1; i >= 0; i--) if (l[i] == ' ') l[i] = '\0'; @@ -59,21 +66,37 @@ int dc_ui_processline (struct dc_thread_control * t, char * l, WINDOW * textwin) case 'J': case 'p': case 'P': - DC_CRLE(c, c->guilds_lock); - char * jp; - if (!(jp = strchr(l, ' ')) || (j = atoi(jp+1)) >= c->guilds_sizeof) { - DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_USAGE ": " DC_I18N_UI_JOIN_USAGE "\n", c->guilds_sizeof-1, 999); - DC_CUE(c, c->guilds_lock); - break; - } - if (!strchr(jp+1, ' ') || (k = atoi(strchr(jp+1, ' ')+1)) >= c->guilds[j]->channels_sizeof) { - DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_USAGE ": " DC_I18N_UI_JOIN_USAGE "\n", c->guilds_sizeof-1, c->guilds[j]->channels_sizeof-1); - DC_CUE(c, c->guilds_lock); - break; + DC_CWLE(c, c->guilds_lock); +#define DC_UI_PL_GC() /* get guild and channel. ONLY USE IN THE CONTEXT (switch statement case) OF dc_ui_processline !!! */ \ + if (!(jp = strchr(l, ' ')) || (j = atoi(jp+1)) >= c->guilds_sizeof) { \ + DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_USAGE ": " DC_I18N_UI_GC_USAGE "\n", c->guilds_sizeof-1, 999); \ + DC_CUE(c, c->guilds_lock); \ + break; \ + } \ + if (!strchr(jp+1, ' ') || (k = atoi(strchr(jp+1, ' ')+1)) >= c->guilds[j]->channels_sizeof) { \ + DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_USAGE ": " DC_I18N_UI_GC_USAGE "\n", c->guilds_sizeof-1, c->guilds[j]->channels_sizeof-1); \ + DC_CUE(c, c->guilds_lock); \ + break; \ } + DC_UI_PL_GC(); for (i = c->guilds[j]->channels[k]->messages_sizeof-1; i >= 0; i--) dc_ui_print_message(textwin, c->guilds[j]->channels[k]->messages[i]); - c->joinedchannel = c->guilds[j]->channels[k]; + for (m = 0; m < c->guilds_sizeof; m++) /* we loop over all channels */ + for (n = 0; n < c->guilds[m]->channels_sizeof; n++) + c->guilds[m]->channels[n]->focused = 0; /* remove focus from all channels */ + DC_SIMPLEPRINT(textwin, 3, "/join %d %d", j, k); + c->guilds[j]->channels[k]->focused = 1; + c->guilds[j]->channels[k]->joined = 1; + DC_CUE(c, c->guilds_lock); + break; + case 'l': + case 'L': + case 'z': /* leave */ + case 'Z': + DC_CWLE(c, c->guilds_lock); + DC_UI_PL_GC(); + c->guilds[j]->channels[k]->focused = 0; + c->guilds[j]->channels[k]->joined = 0; DC_CUE(c, c->guilds_lock); break; case 'q': @@ -96,16 +119,22 @@ int dc_ui_processline (struct dc_thread_control * t, char * l, WINDOW * textwin) DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_CNF "\n"); } else { /* send the message, it's not a command */ - if (!c->joinedchannel) { - DC_SIMPLEPRINT(textwin, 1, "!c->joinedchannel - %s\n", DC_I18N_UI_NOT_JOINED); + struct dc_channel * ch = NULL; + for (int m = 0; m < c->guilds_sizeof; m++) /* we loop over all channels */ + for (int n = 0; n < c->guilds[m]->channels_sizeof; n++) + if (c->guilds[m]->channels[n]->focused) + ch = c->guilds[m]->channels[n]; + /* DC_SIMPLEPRINT(textwin, 2, "%s - %s\n", ch->name, ch->guild->name); */ /* debug */ + if (!ch) { + DC_SIMPLEPRINT(textwin, 1, "!ch - %s\n", DC_I18N_UI_NOT_JOINED); return -1; } if (!strlen(l)) { DC_SIMPLEPRINT(textwin, 1, "!strlen(l) - %s\n", DC_I18N_UI_EMPTYMSG); return -2; } - if (time(NULL) - c->last_sent_message <= c->joinedchannel->slowmode) { - DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_SLOWMODE "\n", c->joinedchannel->slowmode, c->joinedchannel->slowmode-(time(NULL)-c->last_sent_message)); + if (time(NULL) - c->last_sent_message <= ch->slowmode) { + DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_SLOWMODE "\n", ch->slowmode, ch->slowmode-(time(NULL)-c->last_sent_message)); return -3; } c->last_sent_message = time(NULL); /* because the other thread may not update counter before the next message is sent */ @@ -116,7 +145,7 @@ int dc_ui_processline (struct dc_thread_control * t, char * l, WINDOW * textwin) DC_UISM = calloc(1, sizeof(struct dc_message)); DC_UISM->content = malloc(strlen(l)+1); strcpy(DC_UISM->content, l); - DC_UISM->channel = c->joinedchannel; + DC_UISM->channel = ch; DC_CUE(c, c->sent_messages_lock); /* DO NOT free it */ } @@ -142,6 +171,7 @@ int dc_ui_thread (struct dc_thread_control * t) { init_pair(3, COLOR_WHITE, COLOR_BLACK); init_pair(4, COLOR_GREEN, COLOR_BLACK); init_pair(5, COLOR_CYAN, COLOR_BLACK); + init_pair(6, COLOR_BLACK, COLOR_CYAN); keypad(stdscr, TRUE); getmaxyx(stdscr, y, x); /* to je macro, zato y in x nista kazalca (;: */ WINDOW * textwin = subwin(stdscr, y-3, x, 0, 0); @@ -154,42 +184,69 @@ int dc_ui_thread (struct dc_thread_control * t) { set_form_win(form, formwin); post_form(form); int i = 0; + int updinforow = 1; wmove(textwin, 0, 0); refresh(); - struct dc_channel * prev_joinedchannel = (void *)&i; /* just so we get something that isn't null without warnings (): */ while (t->power_ui != 2) { if (!(rand() % 10)) { /* roughly every 10 cycles we get errors and messages */ assert(!DC_CRLE(c, c->errors_lock)); for (int i = 0; i < c->errors_sizeof; i++) { if (!c->errors[i]->reported) { - DC_SIMPLEPRINT(textwin, 1, "[" DC_I18N_ERROR "] %s()@%s:%lu: %s", c->errors[i]->function, c->errors[i]->file, c->errors[i]->line, c->errors[i]->message); + DC_SIMPLEPRINT(textwin, 1, "[" DC_I18N_ERROR "] %s()@%s:%lu: %s\n", c->errors[i]->function, c->errors[i]->file, c->errors[i]->line, c->errors[i]->message); c->errors[i]->reported = 1; } } assert(!pthread_rwlock_unlock(c->errors_lock)); /* deadlock if we unlock errors with error reporting, duh */ - if (c->joinedchannel) { + if (c->newmessages || !(rand() % 10)) { /* a race happens */ /* so we add the random every 10*10=100 cycles */ + c->newmessages = 0; /* here inbetween */ DC_CRLE(c, c->guilds_lock); - for (int i = c->joinedchannel->messages_sizeof-1; i >= 0; i--) { - struct dc_message * msg2do = c->joinedchannel->messages[i]; - if (!msg2do->status) - dc_ui_print_message(textwin, msg2do); - } + for (int m = 0; m < c->guilds_sizeof; m++) /* we loop over all channels */ + for (int n = 0; n < c->guilds[m]->channels_sizeof; n++) { + if (!c->guilds[m]->channels[n]->joined) + continue; + for (int i = c->guilds[m]->channels[n]->messages_sizeof-1; i >= 0; i--) { + struct dc_message * msg2do = c->guilds[m]->channels[n]->messages[i]; + if (!msg2do->status) + dc_ui_print_message(textwin, msg2do); + } + } DC_CUE(c, c->guilds_lock); } - if (prev_joinedchannel != c->joinedchannel) { + if (updinforow) { + updinforow = 0; curs_set(0); /* too flashy */ attron(COLOR_PAIR(5)); - if (c->joinedchannel) { - DC_CRLE(c, c->guilds_lock); - mvprintw(y-3, 0, "#%s @ %s%s%s ", c->joinedchannel->name, c->joinedchannel->guild->name, - strlen(c->joinedchannel->topic) ? " - " : "", c->joinedchannel->topic); - DC_CUE(c, c->guilds_lock); - } else { + int drawn = 0; + int k = 0; + move(y-3, 0); clrtoeol(); /* clear line */ + DC_CRLE(c, c->guilds_lock); + for (int m = 0; m < c->guilds_sizeof; m++) /* we loop over all channels */ + for (int n = 0; n < c->guilds[m]->channels_sizeof; n++) { + if (!c->guilds[m]->channels[n]->joined) + continue; + k++; + if (drawn + strlen(c->guilds[m]->channels[n]->name)+2 > x+1) { + attron(COLOR_PAIR(3)); + for (int l = x-3; l <= x; l++) + mvprintw(y-3, l, "."); + break; + } + if (c->guilds[m]->channels[n]->focused) + attron(COLOR_PAIR(6)); + else + attron(COLOR_PAIR(5)); + mvprintw(y-3, drawn, "#%s(%02.2d %02.2d)", c->guilds[m]->channels[n]->name, m, n); + drawn += strlen(c->guilds[m]->channels[n]->name)+9; /* plus 9: 8 are # and (00 00), the other is for the following space between channels */ + } + DC_CUE(c, c->guilds_lock); + if (!k) { attron(COLOR_PAIR(2)); - mvprintw(y-3, 0, DC_I18N_UI_LINE_BEFORE_JOIN); + if (t->power_api == 0) + mvprintw(y-3, 0, DC_I18N_UI_LINE_BEFORE_NETWORK); + else + mvprintw(y-3, 0, DC_I18N_UI_LINE_BEFORE_JOIN); } curs_set(1); - prev_joinedchannel = c->joinedchannel; } pos_form_cursor(form); } @@ -229,6 +286,36 @@ int dc_ui_thread (struct dc_thread_control * t) { case KEY_SDC: form_driver(form, REQ_CLR_FIELD); break; + case 9: /* idk fucken keybd */ + case KEY_STAB: /* switch to next channel for sending */ + dc_null(); + int firstjoined_g = -1; + int firstjoined_c = -1; + int foundfocused = 0; + DC_CWLE(c, c->guilds_lock); + for (int m = 0; m < c->guilds_sizeof; m++) /* we loop over all channels */ + for (int n = 0; n < c->guilds[m]->channels_sizeof; n++) { + if (firstjoined_g == -1 && c->guilds[m]->channels[n]->joined) { + firstjoined_g = m; + firstjoined_c = n; + } + if (!foundfocused && c->guilds[m]->channels[n]->focused) { + c->guilds[m]->channels[n]->focused = 0; + foundfocused = 1; + continue; + } + if (foundfocused && c->guilds[m]->channels[n]->joined) { + c->guilds[m]->channels[n]->focused = 1; + goto found; + break; + } + } + if (firstjoined_g != -1) + c->guilds[firstjoined_g]->channels[firstjoined_c]->focused = 1; + found: + DC_CUE(c, c->guilds_lock); + updinforow++; + break; case KEY_ENTER: case 10: form_driver(form, REQ_NEXT_FIELD); @@ -236,6 +323,7 @@ int dc_ui_thread (struct dc_thread_control * t) { if (dc_ui_processline(t, field_buffer(field[0], 0), textwin) > 0) form_driver(form, REQ_CLR_FIELD); pos_form_cursor(form); + updinforow++; break; default: form_driver_w(form, ret, ch); @@ -243,9 +331,6 @@ int dc_ui_thread (struct dc_thread_control * t) { } wrefresh(formwin); } - /* wnoutrefresh(stdscr); - wnoutrefresh(textwin); - doupdate(); */ i++; usleep(2500); while (t->power_ui == 0) usleep(250000); -- cgit v1.2.3