ui: notification when a file is downloaded
This commit is contained in:
@@ -8,7 +8,10 @@ TODO:
|
|||||||
- [ ] Simpler refresh on typing / entering in input
|
- [ ] Simpler refresh on typing / entering in input
|
||||||
- [ ] Group elements as lists
|
- [ ] Group elements as lists
|
||||||
- [x] Process arrows
|
- [x] Process arrows
|
||||||
- [ ] Optimize modals re-drawings
|
- [x] Optimize modals re-drawings
|
||||||
|
- [ ] Bug with file list on downloading files
|
||||||
|
- [ ] Remember page numbers
|
||||||
|
- [ ] "Server message" to notification
|
||||||
|
|
||||||
INPUT:
|
INPUT:
|
||||||
- [ ] hidden text for passwords
|
- [ ] hidden text for passwords
|
||||||
|
|||||||
+12
-3
@@ -34,6 +34,7 @@ void file_list(file_args_t *f_args, query_args_t *q_args) {
|
|||||||
static char qbuf[INBUFSIZE * 2];
|
static char qbuf[INBUFSIZE * 2];
|
||||||
static uint32_t qbuf_used = 0;
|
static uint32_t qbuf_used = 0;
|
||||||
ui_file_list_t *fui = (ui_file_list_t *)q_args->file_list_ui;
|
ui_file_list_t *fui = (ui_file_list_t *)q_args->file_list_ui;
|
||||||
|
dialogue_t *d = (dialogue_t *)q_args->active_dialogue;
|
||||||
fui->start = &(f_args->l_start);
|
fui->start = &(f_args->l_start);
|
||||||
fui->current = &(f_args->l_current);
|
fui->current = &(f_args->l_current);
|
||||||
|
|
||||||
@@ -45,6 +46,9 @@ void file_list(file_args_t *f_args, query_args_t *q_args) {
|
|||||||
if (!strcmp("list_end\n", query)) {
|
if (!strcmp("list_end\n", query)) {
|
||||||
q_args->state = S_FILE_SELECT;
|
q_args->state = S_FILE_SELECT;
|
||||||
draw_file_list(fui);
|
draw_file_list(fui);
|
||||||
|
if (d != NULL && d->is_initiated) {
|
||||||
|
d->needs_update = true;
|
||||||
|
}
|
||||||
idx = 1;
|
idx = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -159,7 +163,7 @@ int32_t ui_file_select(file_args_t *f_args, query_args_t *q_args, int32_t idx) {
|
|||||||
f_selected->name = NULL;
|
f_selected->name = NULL;
|
||||||
sprintf(file_path, "%s/%s", DOWNLOADS_DIR, l_selected->name);
|
sprintf(file_path, "%s/%s", DOWNLOADS_DIR, l_selected->name);
|
||||||
f_selected->name = strdup(l_selected->name);
|
f_selected->name = strdup(l_selected->name);
|
||||||
/* fl_clear(&f_args->l_start, &f_args->l_current); */
|
fl_clear(&f_args->l_start, &f_args->l_current);
|
||||||
f_args->file_d = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
f_args->file_d = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||||
if (f_args->file_d == -1) {
|
if (f_args->file_d == -1) {
|
||||||
qlen = sprintf(send_buf, "error: %s\n", f_selected->name);
|
qlen = sprintf(send_buf, "error: %s\n", f_selected->name);
|
||||||
@@ -186,6 +190,7 @@ void file_download(file_args_t *f_args, query_args_t *q_args) {
|
|||||||
if (it_interval == 0)
|
if (it_interval == 0)
|
||||||
it_interval = 1;
|
it_interval = 1;
|
||||||
}
|
}
|
||||||
|
char answer[256];
|
||||||
|
|
||||||
static size_t size_rest = 0;
|
static size_t size_rest = 0;
|
||||||
uint32_t progress = (f_selected->size - size_rest) * 100 / f_selected->size;
|
uint32_t progress = (f_selected->size - size_rest) * 100 / f_selected->size;
|
||||||
@@ -213,9 +218,13 @@ void file_download(file_args_t *f_args, query_args_t *q_args) {
|
|||||||
it_interval = 0;
|
it_interval = 0;
|
||||||
f_selected->size = 0;
|
f_selected->size = 0;
|
||||||
close(f_args->file_d);
|
close(f_args->file_d);
|
||||||
free(f_selected->name);
|
|
||||||
d->needs_destroy = true;
|
d->needs_destroy = true;
|
||||||
q_args->state = WAIT_CLIENT;
|
sprintf(answer, "File %s is downloaded from the server!", f_selected->name);
|
||||||
|
q_args->notification = malloc(strlen(answer)+1);
|
||||||
|
strcpy(q_args->notification, answer);
|
||||||
|
free(f_selected->name);
|
||||||
|
write(q_args->sd, "file list\n", sizeof("file list\n")-1);
|
||||||
|
q_args->state = S_FILE_LIST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ typedef struct query_args {
|
|||||||
void *file_list_ui; /* TODO: find solution to insert actual type without recursion */
|
void *file_list_ui; /* TODO: find solution to insert actual type without recursion */
|
||||||
void *progress_bar;
|
void *progress_bar;
|
||||||
void *active_dialogue;
|
void *active_dialogue;
|
||||||
|
char *notification;
|
||||||
} query_args_t;
|
} query_args_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -263,6 +263,7 @@ void init_query_args(query_args_t *q_args, params_t *params) {
|
|||||||
q_args->next_server_command = NULL;
|
q_args->next_server_command = NULL;
|
||||||
q_args->progress_bar = NULL;
|
q_args->progress_bar = NULL;
|
||||||
q_args->active_dialogue = NULL;
|
q_args->active_dialogue = NULL;
|
||||||
|
q_args->notification = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void user_request_description(query_args_t *q_args) {
|
void user_request_description(query_args_t *q_args) {
|
||||||
|
|||||||
+1
-1
@@ -87,7 +87,7 @@ int process_server_command(char *line, int l_len, query_args_t *q_args) {
|
|||||||
|
|
||||||
/* WELCOME MES */
|
/* WELCOME MES */
|
||||||
if (!strncmp(line, "Welcome, ", ws_pos)) {
|
if (!strncmp(line, "Welcome, ", ws_pos)) {
|
||||||
write(q_args->sd, "file list", sizeof("file list"));
|
write(q_args->sd, "file list\n", sizeof("file list\n")-1);
|
||||||
q_args->state = S_FILE_LIST;
|
q_args->state = S_FILE_LIST;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-4
@@ -3,6 +3,7 @@
|
|||||||
#include "modals/download_pr.h"
|
#include "modals/download_pr.h"
|
||||||
#include "modals/login_credentials.h"
|
#include "modals/login_credentials.h"
|
||||||
#include "modals/login_option.h"
|
#include "modals/login_option.h"
|
||||||
|
#include "modals/notification.h"
|
||||||
#include "modals/server_message.h"
|
#include "modals/server_message.h"
|
||||||
#include "widget/dialogue.h"
|
#include "widget/dialogue.h"
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
@@ -139,6 +140,10 @@ void app_refresh(app_t *app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void app_draw_modal(app_t *app) {
|
void app_draw_modal(app_t *app) {
|
||||||
|
if (app->modal.needs_destroy) {
|
||||||
|
destroy_dialogue(&(app->modal), app);
|
||||||
|
app_refresh(app);
|
||||||
|
}
|
||||||
if (!app->modal.is_initiated) {
|
if (!app->modal.is_initiated) {
|
||||||
switch (app->query_args->state) {
|
switch (app->query_args->state) {
|
||||||
case S_ASK_SEVER_IP:
|
case S_ASK_SEVER_IP:
|
||||||
@@ -172,18 +177,18 @@ void app_draw_modal(app_t *app) {
|
|||||||
case S_WAIT_SERVER:
|
case S_WAIT_SERVER:
|
||||||
case S_N_D:
|
case S_N_D:
|
||||||
case S_NEXT_ACTION:
|
case S_NEXT_ACTION:
|
||||||
|
if (app->query_args->notification != NULL) {
|
||||||
|
init_notification_modal(app);
|
||||||
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
app->active_callback = app->modal.w.callback;
|
app->active_callback = app->modal.w.callback;
|
||||||
app->active_win = app->modal.win;
|
app->active_win = app->modal.win;
|
||||||
app->active_win_type = aw_modal;
|
app->active_win_type = aw_modal;
|
||||||
app->active_widget = &(app->modal);
|
app->active_widget = &(app->modal);
|
||||||
}
|
}
|
||||||
if (app->modal.needs_destroy) {
|
|
||||||
destroy_dialogue(&(app->modal), app);
|
|
||||||
} else {
|
|
||||||
draw_dialogue(&(app->modal));
|
draw_dialogue(&(app->modal));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_app(app_t *app) {
|
void destroy_app(app_t *app) {
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#include <ncurses.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../app.h"
|
||||||
|
#include "../widget/dialogue.h"
|
||||||
|
#include "../widget/group.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
button_t *element;
|
||||||
|
enum w_type type;
|
||||||
|
} group_bt_t;
|
||||||
|
|
||||||
|
void init_notification_modal_cb(callback_args_t *args) {
|
||||||
|
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.widget = app->active_widget;
|
||||||
|
dialogue_default_callback(&d_args);
|
||||||
|
|
||||||
|
app->query_args->state = WAIT_CLIENT;
|
||||||
|
destroy_dialogue(d, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue_t *init_notification_modal(app_t *app) {
|
||||||
|
if (app == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
group_el_init_t actions[] = {
|
||||||
|
{.type = w_button, .label = "OK", .is_default = 1}, {.type = w_end}};
|
||||||
|
|
||||||
|
init_dialogue(&(app->modal), "Notification", app->query_args->notification,
|
||||||
|
&(app->coordinates));
|
||||||
|
free(app->query_args->notification);
|
||||||
|
app->query_args->notification = NULL;
|
||||||
|
dialogue_t *d = &(app->modal);
|
||||||
|
app->query_args->active_dialogue = d;
|
||||||
|
|
||||||
|
d->w.callback = init_notification_modal_cb;
|
||||||
|
d->g_content = NULL;
|
||||||
|
d->g_action = init_group(&(d->win), &(d->w), actions, horizontal);
|
||||||
|
|
||||||
|
dialogue_init_active_id(d);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef NOTIFICATION_H
|
||||||
|
#define NOTIFICATION_H
|
||||||
|
|
||||||
|
#include "../app.h"
|
||||||
|
#include "../widget/dialogue.h"
|
||||||
|
|
||||||
|
dialogue_t *init_notification_modal(app_t *app);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user