From e2750799c5d84fa6bcf3373e53be309f1df61f00 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Wed, 18 Feb 2026 18:39:47 +0200 Subject: [PATCH] ui: alert; anonymous login; registration (not finished) --- TODO.md | 1 + src/draw_modal.c | 4 ++ src/main.h | 5 ++ src/modals/alert.c | 42 +++++++++++++++ src/modals/alert.h | 5 ++ src/modals/login_credentials.c | 2 +- src/modals/login_option.c | 12 +++++ src/modals/register.c | 93 ++++++++++++++++++++++++++++++++++ src/modals/register.h | 8 +++ src/query.c | 1 + src/server.c | 6 +-- src/widget/app.c | 1 + src/widget/app.h | 1 - src/widget/dialogue.c | 10 +++- src/widget/dialogue.h | 4 +- 15 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 src/modals/alert.c create mode 100644 src/modals/alert.h create mode 100644 src/modals/register.c create mode 100644 src/modals/register.h diff --git a/TODO.md b/TODO.md index 228952c..bc2fe67 100644 --- a/TODO.md +++ b/TODO.md @@ -3,6 +3,7 @@ ## Features: - [x] Search files - [x] Correct spacing in the search bar +- [ ] Finish registration - [ ] Privilege settings for files - [ ] Files removal - [ ] Encryption diff --git a/src/draw_modal.c b/src/draw_modal.c index 5cfcb88..2b75ab4 100644 --- a/src/draw_modal.c +++ b/src/draw_modal.c @@ -6,6 +6,7 @@ #include "modals/server_message.h" #include "modals/upload_dialogue.h" #include "modals/upload_props_dialogue.h" +#include "modals/register.h" #include "widget/dialogue.h" #include "main.h" @@ -37,6 +38,9 @@ void app_draw_modal(app_t *app) { case S_UPLOAD_FILE_SELECT: init_upload_dialogue_modal(app); break; + case S_ASK_REGISTER: + init_register_modal(app); + break; case S_UPLOAD_PARAMS: init_upload_props_dialogue_modal(app); break; diff --git a/src/main.h b/src/main.h index af03d2f..3a82932 100644 --- a/src/main.h +++ b/src/main.h @@ -24,10 +24,12 @@ typedef struct params { } params_t; enum state { + /* TUI-based */ S_N_D, S_ASK_SEVER_IP, S_ASK_LOGIN_TYPE, S_ASK_LOGIN_USER, + S_ASK_REGISTER, S_WAIT_SERVER, S_PRINT_SERVER_MESSAGE, S_FILE_LIST, @@ -40,6 +42,8 @@ enum state { S_ASK_USER_BEFORE_LOGIN, S_ERR, S_NEXT_ACTION, + S_WAIT_REGISTER_CONFIRMATION, + /* Legacy */ WAIT_SERVER_INIT, WAIT_SERVER, WAIT_REGISTER, @@ -76,6 +80,7 @@ typedef struct query_args { int32_t buf_used; p_file_t *file; enum state state; + enum state next_state; char *buf; uint32_t from_server : 1; params_t *params; diff --git a/src/modals/alert.c b/src/modals/alert.c new file mode 100644 index 0000000..3fc0c36 --- /dev/null +++ b/src/modals/alert.c @@ -0,0 +1,42 @@ +#include "app.h" +#include "dialogue.h" +#include "widget_core.h" +#include +#include +#include + +void init_alert_cb(callback_args_t *args) { + // +} + +void alert(app_t *app, const char *message) { + if (app == NULL) + return; + + group_el_init_t actions[] = { + {.type = w_button, .label = "OK", .is_default = 1}, {.type = w_end}}; + + dialogue_t *d = malloc(sizeof(dialogue_t)); + + init_dialogue(d, "Alert", message, &(app->coordinates)); + + d->w.callback = init_alert_cb; + d->g_content = NULL; + d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + + dialogue_init_active_id(d); + d->color_scheme = dc_alert; + + draw_dialogue(d); + wrefresh(d->win); + int c = 0; + + while ((c = wgetch(d->win))) { + if (c == '\n') break; + } + + destroy_group(d->g_action); + delwin(d->win); + free(d); + app_refresh(app); +} \ No newline at end of file diff --git a/src/modals/alert.h b/src/modals/alert.h new file mode 100644 index 0000000..80283e4 --- /dev/null +++ b/src/modals/alert.h @@ -0,0 +1,5 @@ +#ifndef ALERT_H +#define ALERT_H +#include "app.h" +void alert(app_t *app, const char *message); +#endif \ No newline at end of file diff --git a/src/modals/login_credentials.c b/src/modals/login_credentials.c index 04046c4..ed2e00f 100644 --- a/src/modals/login_credentials.c +++ b/src/modals/login_credentials.c @@ -59,7 +59,7 @@ dialogue_t *init_login_credentials_modal(app_t *app) { {.type = w_button, .label = "Cancel", .is_default = false}, {.type = w_end}}; - init_dialogue(&(app->modal), "Credentials", "There is information needed", + init_dialogue(&(app->modal), "Login", "Your login credentials", &(app->coordinates)); dialogue_t *d = &(app->modal); diff --git a/src/modals/login_option.c b/src/modals/login_option.c index 8289a68..439b807 100644 --- a/src/modals/login_option.c +++ b/src/modals/login_option.c @@ -1,7 +1,9 @@ #include #include +#include #include +#include #include typedef struct { @@ -22,11 +24,21 @@ void login_modal_option_cb(callback_args_t *args) { if (response > -1) { switch (response) { case 0: + d->needs_destroy = true; + app->params->uname = malloc(sizeof "anonymous"); + strcpy(app->params->uname, "anonymous"); + write(app->params->sd, app->params->uname, sizeof "anonymous"-1); + app->query_args->state = S_WAIT_SERVER; + print_bars(app); break; case 1: d->needs_destroy = true; app->query_args->state = S_ASK_LOGIN_USER; break; + case 2: + d->needs_destroy = true; + app->query_args->state = S_ASK_REGISTER; + break; } } } diff --git a/src/modals/register.c b/src/modals/register.c new file mode 100644 index 0000000..2386b91 --- /dev/null +++ b/src/modals/register.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "alert.h" + +typedef struct { + button_t *element; + enum w_type type; +} group_bt_t; + +void init_register_modal_cb(callback_args_t *args) { + char query[256]; + int32_t qlen = 0; + int32_t response; + callback_args_t d_args; + app_t *app = args->app; + dialogue_t *d = (dialogue_t *)app->active_widget; + memcpy(&d_args, args, sizeof(callback_args_t)); + d_args.app = NULL; + d_args.resp_data = &response; + d_args.element = app->active_widget; + input_t *in_name = d->g_content->elements[0].element; + input_t *in_pass = d->g_content->elements[1].element; + input_t *in_pass_r = d->g_content->elements[2].element; + dialogue_default_callback(&d_args); + if (response > -1) { + switch (response) { + case 0: + if (strcmp(in_pass->value, in_pass_r->value)) { + alert(app, "Your passwords do not match"); + in_pass->value[0] = '\0'; + in_pass->value_len = 0; + in_pass_r->value[0] = '\0'; + in_pass_r->value_len = 0; + return; + } + app->params->uname = malloc(in_name->value_len + 1); + app->params->pass = malloc(in_pass->value_len + 1); + strncpy(app->params->uname, in_name->value, in_name->value_len); + app->params->uname[in_name->value_len] = 0; + strncpy(app->params->pass, in_pass->value, in_pass->value_len); + app->params->pass[in_pass->value_len] = 0; + sprintf(query, "register %s %s\n%n", app->params->uname, app->params->pass, + &qlen); + write(app->params->sd, query, qlen); + app->query_args->state = S_WAIT_REGISTER_CONFIRMATION; + /* d->needs_destroy = true; + print_bars(app); */ + break; + case 1: + destroy_app(app, 0); + } + } +} + +dialogue_t *init_register_modal(app_t *app) { + if (app == NULL) + return NULL; + group_el_init_t content[] = { + {.type = w_input, .label = "Username", .length = 15}, + {.type = w_input, + .label = "Password", + .length = 15, + .is_hidden_value = true}, + {.type = w_input, + .label = "Password (repeat)", + .length = 15, + .is_hidden_value = true}, + {.type = w_end}}; + + group_el_init_t actions[] = { + {.type = w_button, .label = "Register", .is_default = true}, + {.type = w_button, .label = "Cancel", .is_default = false}, + {.type = w_end}}; + + init_dialogue(&(app->modal), "Credentials", "There is information needed", + &(app->coordinates)); + dialogue_t *d = &(app->modal); + + d->w.callback = init_register_modal_cb; + d->g_content = init_group(&(d->win), &(d->w), content, horizontal); + d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + + dialogue_init_active_id(d); + + return NULL; +} \ No newline at end of file diff --git a/src/modals/register.h b/src/modals/register.h new file mode 100644 index 0000000..b0901fe --- /dev/null +++ b/src/modals/register.h @@ -0,0 +1,8 @@ +#ifndef REGISTER_MODAL_H +#define REGISTER_MODAL_H + +#include + +dialogue_t *init_register_modal(app_t *app); + +#endif \ No newline at end of file diff --git a/src/query.c b/src/query.c index a21100b..46f8d22 100644 --- a/src/query.c +++ b/src/query.c @@ -143,6 +143,7 @@ int process_query(query_args_t *query_args, file_args_t *file_args) { case S_NEXT_ACTION: case S_WAIT_SERVER: case WAIT_REGISTER_CONFIRMATION: + case S_WAIT_REGISTER_CONFIRMATION: wait_side(query_args); break; case S_ERR: diff --git a/src/server.c b/src/server.c index 0964d4b..0b8abfe 100644 --- a/src/server.c +++ b/src/server.c @@ -1,5 +1,6 @@ #include "main.h" #include "widget/file_list.h" +#include "modals/alert.h" #include #include #include @@ -69,7 +70,7 @@ int process_server_command(char *line, int l_len, query_args_t *q_args) { } /* REGISTER CONFIRMATION */ - if (q_args->state == WAIT_REGISTER_CONFIRMATION) { + if (q_args->state == S_WAIT_REGISTER_CONFIRMATION) { if (!strcmp(line, "ok")) { sprintf(query, "file list %u %u\n%n", fui->max_lines, fui->current_page, &q_len); @@ -77,8 +78,7 @@ int process_server_command(char *line, int l_len, query_args_t *q_args) { q_args->state = S_FILE_LIST; return 0; } else { - write(STDOUT_FILENO, line, strlen(line)); - q_args->state = WAIT_REGISTER; + PRINT_SRV_MESSAGE(q_args, l_len, line) return 1; } } diff --git a/src/widget/app.c b/src/widget/app.c index 9150ed1..225cac2 100644 --- a/src/widget/app.c +++ b/src/widget/app.c @@ -73,6 +73,7 @@ void init_nc() { init_pair(1, COLOR_RED, COLOR_BLACK); init_pair(2, COLOR_GREEN, COLOR_BLACK); init_pair(modal_color_pair, COLOR_BLUE, COLOR_WHITE); + init_pair(4, COLOR_CYAN, COLOR_WHITE); } } diff --git a/src/widget/app.h b/src/widget/app.h index 701f074..79d84c3 100644 --- a/src/widget/app.h +++ b/src/widget/app.h @@ -28,7 +28,6 @@ typedef struct { coordinates_t coordinates; query_args_t *query_args; file_args_t *file_args; - int32_t read_fd; active_win_t active_win_type; void (*active_callback)(callback_args_t *args); WINDOW *active_win; diff --git a/src/widget/dialogue.c b/src/widget/dialogue.c index 110eb64..5959e2f 100644 --- a/src/widget/dialogue.c +++ b/src/widget/dialogue.c @@ -173,6 +173,7 @@ void init_dialogue(dialogue_t *dialogue, const char title[], const char text[], dialogue->is_initiated = true; dialogue->needs_update = true; dialogue->needs_destroy = false; + dialogue->color_scheme = dc_normal; strcpy(dialogue->w.title, title); strcpy(dialogue->text, text); } @@ -284,7 +285,14 @@ int32_t draw_dialogue(dialogue_t *d) { d->win = newwin(y, x, d->w.m_y, d->w.m_x); } - wattrset(d->win, COLOR_PAIR(0) | A_BOLD | A_REVERSE); + switch (d->color_scheme) { + case dc_normal: + wattrset(d->win, COLOR_PAIR(0) | A_BOLD | A_REVERSE); + break; + case dc_alert: + wattrset(d->win, COLOR_PAIR(4) | A_BOLD | A_REVERSE); + break; + } /* background */ for (int yp = 1; yp < d->w.y - 1; yp++) { diff --git a/src/widget/dialogue.h b/src/widget/dialogue.h index 74e636f..895a120 100644 --- a/src/widget/dialogue.h +++ b/src/widget/dialogue.h @@ -8,6 +8,7 @@ #include enum g_type { g_content, g_action }; +enum d_color_scheme { dc_normal, dc_alert }; typedef struct { widget_t w; @@ -21,8 +22,9 @@ typedef struct { char text[DIALOGUE_TEXT]; uint32_t is_initiated : 1; uint32_t needs_update : 1; - uint32_t needs_destroy: 1; + uint32_t needs_destroy : 1; coordinates_t *p_coordinates; + enum d_color_scheme color_scheme; } dialogue_t; void init_dialogue(dialogue_t *d, const char title[], const char text[],