summaryrefslogtreecommitdiffstats
path: root/src/ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui.c')
-rw-r--r--src/ui.c188
1 files changed, 167 insertions, 21 deletions
diff --git a/src/ui.c b/src/ui.c
index 3f8dbaf..2578689 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -1,34 +1,123 @@
-#define _XOPEN_SOURCE 600
-#define _POSIX_C_SOURCE 200809L
+#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
-/* #include <api.c> */
+#include <api.c>
#include <ncursesw/ncurses.h>
#include <ncursesw/form.h>
#include <unistd.h>
#include <locale.h>
+#include <string.h>
+#include <assert.h>
+#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 */
-/* int dc_ui_thread (struct * dc_thread_control t) { */
-int main () {
+int dc_ui_print_message (WINDOW * textwin, struct dc_message * msg2do) {
+ char timestring[64];
+ struct tm timestruct;
+ localtime_r(&msg2do->time, &timestruct);
+ strftime(timestring, 64, DC_I18N_MSGTIMEF, &timestruct); /* recimo, da je 23 znakov */
+ DC_SIMPLEPRINT(textwin, 3, "%023.23s %08.8s: %s\n", timestring, msg2do->username, msg2do->content);
+ 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;
+ for (i = strlen(l)-1; i >= 0; i--)
+ if (l[i] == ' ')
+ l[i] = '\0';
+ else
+ break;
+ if (l[0] == '/')
+ switch (l[1]) {
+ case 'g':
+ case 'G':
+ case 's':
+ case 'S': /* servers */
+ DC_CRLE(c, c->guilds_lock);
+ for (i = 0; i < c->guilds_sizeof; i++)
+ DC_SIMPLEPRINT(textwin, 4, " %02d. %s\n", i, c->guilds[i]->name);
+ DC_CUE(c, c->guilds_lock);
+ break;
+ case 'c':
+ case 'C':
+ case 'k':
+ case 'K':
+ DC_CRLE(c, c->guilds_lock);
+ if (!strchr(l, ' ') || (j = atoi(strchr(l, ' ')+1)) >= c->guilds_sizeof) {
+ DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_USAGE ": " DC_I18N_UI_CHANNELS_USAGE "\n", c->guilds_sizeof-1);
+ DC_CUE(c, c->guilds_lock);
+ break;
+ }
+ for (i = 0; i < c->guilds[j]->channels_sizeof; i++)
+ DC_SIMPLEPRINT(textwin, 4, " %02d. %s - %s\n", i, c->guilds[j]->channels[i]->name, c->guilds[j]->channels[i]->topic);
+ DC_CUE(c, c->guilds_lock);
+ break;
+ case 'j':
+ 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;
+ }
+ for (i = 0; i < c->guilds[j]->channels[k]->messages_sizeof; i++)
+ dc_ui_print_message(textwin, c->guilds[j]->channels[k]->messages[i]);
+ c->joinedchannel = c->guilds[j]->channels[k];
+ DC_CUE(c, c->guilds_lock);
+
+ break;
+ case 'q':
+ case 'Q':
+ case 'i':
+ case 'I':
+ t->power_api = 2; /* 2 for shutdown */
+ t->power_ui = 2;
+ break;
+ case 'N': /* api nit (thread) control */
+ case 'n':
+ if (!strchr(l, ' ')) {
+ DC_SIMPLEPRINT(textwin, 1, "!strchr(l, ' ')\n");
+ break;
+ }
+ t->power_api = atoi(strchr(l, ' ')+1);
+ DC_SIMPLEPRINT(textwin, 4, "t->power_api = %d\n", atoi(strchr(l, ' ')+1));
+ default:
+ DC_SIMPLEPRINT(textwin, 1, DC_I18N_UI_CNF "\n");
+ }
+ wrefresh(textwin);
+ return 1;
+}
+int dc_ui_thread (struct dc_thread_control * t) {
+ while (!t->power_ui) usleep(250000);
FIELD * field[2]; /* field[0] je polje z besedilom */
field[1] = NULL;
FORM * form;
int ret, x, y;
wint_t ch;
+ struct dc_client * c = t->clients[0];
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
setlocale(LC_ALL, "sl_SI.UTF-8");
start_color();
- init_pair(0, COLOR_WHITE, COLOR_BLACK);
+ init_pair(2, COLOR_YELLOW, COLOR_BLACK);
init_pair(1, COLOR_RED, COLOR_BLACK);
- attron(COLOR_PAIR(1));
+ init_pair(3, COLOR_WHITE, COLOR_BLACK);
+ init_pair(4, COLOR_GREEN, COLOR_BLACK);
keypad(stdscr, TRUE);
getmaxyx(stdscr, y, x); /* to je macro, zato y in x nista kazalca (;: */
- WINDOW * textwin = newwin(y-3, x, 0, 0);
- WINDOW * formwin = newwin(2, x, y-2, 0);
+ WINDOW * textwin = subwin(stdscr, y-3, x, 0, 0);
+ WINDOW * formwin = subwin(stdscr, 2, x, y-2, 0);
scrollok(textwin, TRUE);
field[0] = new_field(2, x, y-2, 0, 5 /* offscreen rows */, 0);
set_field_back(field[0], A_UNDERLINE);
@@ -38,15 +127,43 @@ int main () {
post_form(form);
int i = 0;
wmove(textwin, 0, 0);
- time_t last_time = 0;
refresh();
- while (1) {
- if (last_time < time(NULL)) {
- last_time = time(NULL);
- attron(COLOR_PAIR(0));
- wprintw(textwin, "\nvrstica stevilka %d", i);
- attron(COLOR_PAIR(1));
- mvprintw(y-3, 0, "#piš-ti-kurc-2 | discord.c | šijanec 2021");
+ 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() % 100)) { /* roughly every 100 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);
+ c->errors[i]->reported = 1;
+ }
+ }
+ assert(!pthread_rwlock_unlock(c->errors_lock)); /* deadlock if we unlock errors with error reporting, duh */
+ if (c->joinedchannel) {
+ DC_CRLE(c, c->guilds_lock);
+ for (int i = 0; i < c->joinedchannel->messages_sizeof; i++) {
+ struct dc_message * msg2do = c->joinedchannel->messages[i];
+ if (!msg2do->status) {
+ dc_ui_print_message(textwin, msg2do);
+ msg2do->status = 1;
+ }
+ }
+ DC_CUE(c, c->guilds_lock);
+ }
+ if (prev_joinedchannel != c->joinedchannel) {
+ curs_set(0); /* too flashy */
+ attron(COLOR_PAIR(2));
+ if (c->joinedchannel) {
+ DC_CRLE(c, c->guilds_lock);
+ mvprintw(y-3, 0, "#%s @ %s | %s", c->joinedchannel->name, c->joinedchannel->guild->name, c->joinedchannel->topic);
+ DC_CUE(c, c->guilds_lock);
+ }
+ else
+ mvprintw(y-3, 0, DC_I18N_UI_LINE_BEFORE_JOIN);
+ curs_set(1);
+ prev_joinedchannel = c->joinedchannel;
+ }
+ pos_form_cursor(form);
}
ret = get_wch(&ch);
if (ret != ERR) {
@@ -61,20 +178,49 @@ int main () {
form_driver(form, REQ_DEL_PREV);
break;
case KEY_DOWN:
- form_driver(form, REQ_SCR_FLINE);
+ form_driver(form, REQ_NEXT_LINE);
break;
case KEY_UP:
- form_driver(form, REQ_SCR_BLINE);
+ form_driver(form, REQ_PREV_LINE);
+ break;
+ case KEY_DC:
+ form_driver(form, REQ_DEL_CHAR);
+ break;
+ case KEY_END:
+ form_driver(form, REQ_END_LINE);
+ break;
+ case KEY_HOME:
+ form_driver(form, REQ_BEG_LINE);
+ break;
+ case KEY_SLEFT:
+ form_driver(form, REQ_PREV_WORD);
+ break;
+ case KEY_SRIGHT:
+ form_driver(form, REQ_NEXT_WORD);
+ break;
+ case KEY_SDC:
+ form_driver(form, REQ_CLR_FIELD);
+ break;
+ case KEY_ENTER:
+ case 10:
+ form_driver(form, REQ_NEXT_FIELD);
+ form_driver(form, REQ_PREV_FIELD);
+ dc_ui_processline(t, field_buffer(field[0], 0), textwin);
+ form_driver(form, REQ_CLR_FIELD);
+ pos_form_cursor(form);
break;
default:
form_driver_w(form, ret, ch);
break;
}
+ wrefresh(formwin);
}
- wnoutrefresh(stdscr);
+ /* wnoutrefresh(stdscr);
wnoutrefresh(textwin);
- doupdate();
+ doupdate(); */
i++;
+ usleep(2500);
+ while (t->power_ui == 0) usleep(250000);
}
unpost_form(form);
free_form(form);