AmendHub

Download:

jcs

/

subtext

/

amendments

/

308

session_menu: Handle multi-digit input universally here again

Move the board change into this and update all other menus that input
numbers to use it by supplying a prompt addition and short variable
to write to.
 
Update sysop, mail, and file menus to list 20 things at a time.

jcs made amendment 308 about 1 year ago
--- board.c Thu Feb 16 17:23:36 2023 +++ board.c Wed Feb 22 21:31:49 2023 @@ -130,20 +130,20 @@ void board_show(struct session *s, short id) { static const struct session_menu_option opts[] = { - { '#', "#12", "Enter post to read", true }, - { '<', "<", "Previous page of posts" }, - { 'l', "Ll", "List posts" }, - { '>', ">", "Next page of posts" }, - { 'p', "Pp", "Post new thread" }, - { 'q', "QqXx", "Return to main menu" }, - { '?', "?", "List menu options" }, + { '#', "#", "Enter post to read" }, + { '<', "<", "Previous page of posts" }, + { 'l', "Ll", "List posts" }, + { '>', ">", "Next page of posts" }, + { 'p', "Pp", "Post new thread" }, + { 'q', "QqXx", "Return to main menu" }, + { '?', "?", "List menu options" }, }; char prompt[7 + BOARD_NAME_LENGTH]; struct board *board = NULL; size_t n, nall_post_ids, page, pages, npost_ids; unsigned long *post_ids = NULL; short ppp, ret, pn; - char c, cn[2], *pn_field = NULL; + char c; bool done, find_post_ids, show_list, show_help; for (n = 0; n < db->nboards; n++) { @@ -194,7 +194,7 @@ board_show(struct session *s, short id) } c = session_menu(s, board->description, prompt, opts, - nitems(opts), show_help); + nitems(opts), show_help, "Post #", &pn); show_help = false; handle_opt: @@ -227,23 +227,7 @@ handle_opt: find_post_ids = true; show_list = true; break; - case 1: - case 2: - session_printf(s, "\r\n%sPost to View:%s ", - ansi(s, ANSI_BOLD, ANSI_END), ansi(s, ANSI_RESET, ANSI_END)); - session_flush(s); - - cn[0] = c + '0'; - cn[1] = '\0'; - pn_field = session_field_input(s, 3, 2, (char *)&cn, false, 0); - session_printf(s, "\r\n"); - session_flush(s); - if (pn_field == NULL) - break; - - pn = atoi(pn_field); - xfree(&pn_field); - + case '#': check_pn: if (pn < 1 || pn > npost_ids) { session_printf(s, "Invalid post\r\n"); @@ -626,7 +610,7 @@ board_post_read(struct session *s, struct board *board while (!done && !s->ending) { c = session_menu(s, thread.subject, prompt, dopts, - nitems(opts), show_help); + nitems(opts), show_help, NULL, NULL); show_help = false; switch (c) { --- folder.c Thu Feb 16 14:31:23 2023 +++ folder.c Wed Feb 22 22:13:04 2023 @@ -26,7 +26,7 @@ #include "user.h" #include "zmodem.h" -#define FILES_PER_PAGE 10 +#define FILES_PER_PAGE 20 #define FILE_VIEW_RETURN_DONE -1 #define FILE_VIEW_RETURN_LIST -2 @@ -99,10 +99,11 @@ const size_t nfolder_file_object_fields = nitems(folde unsigned long folder_upload(struct session *s, struct folder *folder, char *initial_filename, char *initial_description); void folder_list_files(struct session *s, struct folder *folder, - size_t nfile_ids, unsigned long *file_ids, size_t page, size_t pages); + size_t nfile_ids, unsigned long *file_ids, short files_per_page, + size_t page, size_t pages); void folder_show(struct session *s, struct folder *folder); short folder_file_view(struct session *s, struct folder *folder, - unsigned long id, short idx); + unsigned long id); void folder_delete_file(struct session *s, struct folder *folder, struct folder_file *file); size_t folder_find_file_ids(struct folder *folder, size_t *nfile_ids, @@ -118,12 +119,12 @@ void folder_list(struct session *s) { static const struct session_menu_option opts[] = { - { '#', "#0123456789", "View file folder [#]" }, - { 'l', "Ll", "List folders" }, - { 'q', "QqXx", "Return to main menu" }, - { '?', "?", "List menu options" }, + { '#', "#", "View file folder [#]" }, + { 'l', "Ll", "List folders" }, + { 'q', "QqXx", "Return to main menu" }, + { '?', "?", "List menu options" }, }; - short n; + short n, fn; char c; bool done, show_list, show_help; @@ -134,13 +135,13 @@ folder_list(struct session *s) while (!done && !s->ending) { if (show_list) { session_printf(s, "{{B}}File Folders{{/B}}\r\n"); - session_printf(s, "%s# Name Description%s\r\n", + session_printf(s, "%s# Name Description%s\r\n", ansi(s, ANSI_BOLD, ANSI_END), ansi(s, ANSI_RESET, ANSI_END)); session_flush(s); for (n = 0; n < db->nfolders; n++) { - session_printf(s, "%d %- 13.13s %s\r\n", - n, + session_printf(s, "%2d %- 13.13s %s\r\n", + n + 1, db->folders[n].name, db->folders[n].description); } @@ -150,7 +151,7 @@ folder_list(struct session *s) } c = session_menu(s, "File Folders", "Files", opts, nitems(opts), - show_help); + show_help, "Folder #", &fn); show_help = false; handle_opt: @@ -158,22 +159,14 @@ handle_opt: case 'l': show_list = true; break; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - if (c >= db->nfolders) { + case '#': +check_fn: + if (fn < 1 || fn > db->nfolders) { session_printf(s, "Invalid folder\r\n"); session_flush(s); break; } - folder_show(s, &db->folders[c]); + folder_show(s, &db->folders[fn - 1]); break; case '?': show_help = true; @@ -189,18 +182,18 @@ void folder_show(struct session *s, struct folder *folder) { static const struct session_menu_option opts[] = { - { '#', "#0123456789", "View file [#]" }, - { '<', "<", "Previous page of files" }, - { 'l', "Ll", "List files" }, - { '>', ">", "Next page of files" }, - { 'u', "Uu", "Upload new file" }, - { 'q', "QqXx", "Return to main menu" }, - { '?', "?", "List menu options" }, + { '#', "#", "View file [#]" }, + { '<', "<", "Previous page of files" }, + { 'l', "Ll", "List files" }, + { '>', ">", "Next page of files" }, + { 'u', "Uu", "Upload new file" }, + { 'q', "QqXx", "Return to main menu" }, + { '?', "?", "List menu options" }, }; char prompt[6 + BOARD_NAME_LENGTH + 8]; size_t page, pages, nfile_ids; unsigned long *file_ids = NULL; - short ret; + short ret, fpp, fn; char c; bool done, show_list, show_help, find_files; @@ -215,8 +208,11 @@ folder_show(struct session *s, struct folder *folder) while (!done && !s->ending) { if (find_files) { folder_find_file_ids(folder, &nfile_ids, &file_ids); - /* ceil(nfile_ids / FILES_PER_PAGE) */ - pages = (nfile_ids + FILES_PER_PAGE - 1) / FILES_PER_PAGE; + fpp = FILES_PER_PAGE; + if (s->terminal_lines < fpp + 3) + fpp = BOUND(fpp, 5, s->terminal_lines - 3); + /* ceil(nfile_ids / fpp) */ + pages = (nfile_ids + fpp - 1) / fpp; if (page >= pages) page = pages - 1; @@ -225,13 +221,13 @@ folder_show(struct session *s, struct folder *folder) } if (show_list) { - folder_list_files(s, folder, nfile_ids, file_ids, page + 1, - pages); + folder_list_files(s, folder, nfile_ids, file_ids, fpp, + page + 1, pages); show_list = false; } c = session_menu(s, folder->description, prompt, opts, - nitems(opts), show_help); + nitems(opts), show_help, "File #", &fn); show_help = false; handle_opt: @@ -261,22 +257,13 @@ handle_opt: page--; show_list = true; break; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - if (c >= nfile_ids) { + case '#': + if (fn < 1 || fn > nfile_ids) { session_printf(s, "Invalid file\r\n"); session_flush(s); break; } - c = folder_file_view(s, folder, file_ids[c], c); + c = folder_file_view(s, folder, file_ids[fn - 1]); if (c == FILE_VIEW_RETURN_FIND) find_files = true; break; @@ -295,8 +282,8 @@ handle_opt: void folder_list_files(struct session *s, struct folder *folder, - size_t nfile_ids, unsigned long *file_ids, unsigned long page, - unsigned long pages) + size_t nfile_ids, unsigned long *file_ids, short files_per_page, + unsigned long page, unsigned long pages) { char time[24]; size_t n, off, size; @@ -306,7 +293,7 @@ folder_list_files(struct session *s, struct folder *fo session_printf(s, "{{B}}%s: %s (Page %ld of %ld){{/B}}\r\n", folder->name, folder->description, page, pages); session_printf(s, - "%s# Date File Description%s\r\n", + "%s# Date File Description%s\r\n", ansi(s, ANSI_BOLD, ANSI_END), ansi(s, ANSI_RESET, ANSI_END)); session_flush(s); @@ -316,9 +303,9 @@ folder_list_files(struct session *s, struct folder *fo return; } - off = FILES_PER_PAGE * (page - 1); + off = files_per_page * (page - 1); - for (n = 0; n < FILES_PER_PAGE; n++) { + for (n = 0; n < files_per_page; n++) { if (off + n >= nfile_ids) break; @@ -331,8 +318,8 @@ folder_list_files(struct session *s, struct folder *fo strftime(time, sizeof(time), "%Y-%m-%d", localtime(&file.time)); - session_printf(s, "%ld %s {{#}}%- 17.17s %- 40s\r\n", - n, + session_printf(s, "%2ld %s {{#}}%- 17.17s %- 40s\r\n", + n + 1, time, file.filename, file.description); @@ -648,10 +635,9 @@ file_upload_done: short folder_file_view(struct session *s, struct folder *folder, - unsigned long id, short idx) + unsigned long id) { static const struct session_menu_option opts[] = { - { '#', "#0123456789", "View file [#]" }, { 'd', "Dd", "Download this file" }, { 'r', "Rr", "Remove this file" }, { 'e', "Ee", "Edit this file" }, @@ -719,7 +705,7 @@ folder_file_view(struct session *s, struct folder *fol while (!done && !s->ending) { c = session_menu(s, file.filename, prompt, dopts, nitems(opts), - show_help); + show_help, NULL, NULL); show_help = false; switch (c) { @@ -815,19 +801,6 @@ folder_file_view(struct session *s, struct folder *fol session_printf(s, "\r\nPost not deleted.\r\n"); session_flush(s); } - break; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - ret = c; - done = true; break; case 'q': done = true; --- mail.c Thu Feb 16 14:31:44 2023 +++ mail.c Wed Feb 22 21:51:55 2023 @@ -27,7 +27,7 @@ #include "uthread.h" #include "util.h" -#define MSGS_PER_PAGE 10 +#define MSGS_PER_PAGE 20 #define MAIL_READ_RETURN_DONE -1 #define MAIL_READ_RETURN_LIST -2 @@ -118,7 +118,7 @@ void mail_menu(struct session *s) { static const struct session_menu_option opts[] = { - { '#', "#0123456789", "Read mail message [#]" }, + { '#', "#", "Read mail message [#]" }, { '<', "<", "Previous page of messages" }, { 'l', "Ll", "List mail messages" }, { '>', ">", "Next page of messages" }, @@ -128,7 +128,7 @@ mail_menu(struct session *s) }; size_t nmsgs, nmail_ids; unsigned long *mail_ids = NULL, page, pages; - short ret; + short ret, mpp, mn; char c; bool show_help = false; bool done = false; @@ -148,10 +148,13 @@ mail_menu(struct session *s) if (find_message_ids) { if (mail_ids != NULL) xfree(&mail_ids); + mpp = MSGS_PER_PAGE; + if (s->terminal_lines < mpp + 3) + mpp = BOUND(mpp, 5, s->terminal_lines - 3); nmsgs = mail_find_ids_for_user(s->user, &nmail_ids, &mail_ids, - page * MSGS_PER_PAGE, MSGS_PER_PAGE, false); - /* ceil(nmsgs / MSGS_PER_PAGE) */ - pages = (nmsgs + MSGS_PER_PAGE - 1) / MSGS_PER_PAGE; + page * mpp, mpp, false); + /* ceil(nmsgs / mpp) */ + pages = (nmsgs + mpp - 1) / mpp; if (page >= pages) page = pages - 1; @@ -165,7 +168,7 @@ mail_menu(struct session *s) } c = session_menu(s, "Private Mail", "Mail", opts, nitems(opts), - show_help); + show_help, "Message #", &mn); show_help = false; handle_opt: @@ -195,22 +198,13 @@ handle_opt: find_message_ids = true; show_list = true; break; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - if (c >= nmail_ids) { + case '#': + if (mn < 1 || mn > nmail_ids) { session_printf(s, "Invalid message\r\n"); session_flush(s); break; } - ret = mail_read(s, mail_ids[c], c); + ret = mail_read(s, mail_ids[mn - 1], mn); switch (ret) { case MAIL_READ_RETURN_DONE: break; @@ -417,7 +411,7 @@ mail_list(struct session *s, size_t nmail_ids, unsigne session_printf(s, "{{B}}Private Mail (Page %ld of %ld){{/B}}\r\n", page, pages); - session_printf(s, "%s# Flg Date From Subject%s\r\n", + session_printf(s, "%s# Flg Date From Subject%s\r\n", ansi(s, ANSI_BOLD, ANSI_END), ansi(s, ANSI_RESET, ANSI_END)); session_flush(s); @@ -436,7 +430,7 @@ mail_list(struct session *s, size_t nmail_ids, unsigne session_printf(s, "%s%ld %c %s %- 10s {{#}}%- 40s%s\r\n", msg.read ? "" : ansi(s, ANSI_BOLD, ANSI_END), - n, + n + 1, msg.read ? ' ' : 'N', time, user ? user->username : "(unknown)", @@ -457,7 +451,6 @@ mail_read(struct session *s, unsigned long id, short i { 'd', "Dd", "Delete this message" }, { 'u', "Uu", "Mark this message unread" }, { 'l', "Ll", "Return and list mail messages" }, - { '#', "#0123456789", "Return and read mail message [#]" }, { 'q', "QqXx", "Return to message list" }, { '?', "?", "Show this help menu" }, }; @@ -514,7 +507,7 @@ mail_read(struct session *s, unsigned long id, short i while (!done && !s->ending) { c = session_menu(s, title, prompt, opts, nitems(opts), - show_help); + show_help, NULL, NULL); show_help = false; switch (c) { @@ -562,19 +555,6 @@ mail_read(struct session *s, unsigned long id, short i case 'q': done = true; ret = MAIL_READ_RETURN_DONE; - break; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - ret = c; - done = true; break; case '?': show_help = true; --- session.c Wed Feb 22 20:56:00 2023 +++ session.c Wed Feb 22 22:30:13 2023 @@ -1510,11 +1510,13 @@ session_who(struct session *s) char session_menu(struct session *s, char *title, char *prompt, - const struct session_menu_option *opts, size_t nopts, bool show_opts) + const struct session_menu_option *opts, size_t nopts, bool show_opts, + char *number_prompt, short *ret_number) { size_t n; - short j; + short j, num; unsigned short c; + char cn[2], *num_input = NULL; bool last_invalid = false; if (show_opts) { @@ -1534,6 +1536,7 @@ print_options: } for (;;) { +show_prompt: session_printf(s, "{{B}}%s>{{/B}} ", prompt); session_flush(s); @@ -1549,19 +1552,32 @@ get_menu_option: for (j = 0; ; j++) { if (opts[n].key[j] == '\0') break; - if (opts[n].ret == '#') { - if (opts[n].key[j] == c && c != '#') { - if (!opts[n].supress_output) { - session_printf(s, "%c\r\n", c); - session_flush(s); - } - return c - '0'; /* return actual number */ + if (opts[n].ret == '#' && c >= '0' && c <= '9') { + session_printf(s, "%s:%s>%s ", + ansi(s, ANSI_BACKSPACE, ANSI_BACKSPACE, + ANSI_BOLD, ANSI_END), number_prompt, + ansi(s, ANSI_RESET, ANSI_END)); + session_flush(s); + + cn[0] = c; + cn[1] = '\0'; + num_input = session_field_input(s, 4, 3, (char *)&cn, + false, 0); + session_printf(s, "\r\n"); + session_flush(s); + if (num_input == NULL) + goto show_prompt; + if (num_input[0] == '\0') { + xfree(&num_input); + goto show_prompt; } + num = atoi(num_input); + xfree(&num_input); + *ret_number = num; + return opts[n].ret; } else if (opts[n].key[j] == c) { - if (!opts[n].supress_output) { - session_printf(s, "%c\r\n", c); - session_flush(s); - } + session_printf(s, "%c\r\n", c); + session_flush(s); return opts[n].ret; } } --- session.h Thu Feb 16 17:22:58 2023 +++ session.h Wed Feb 22 21:07:39 2023 @@ -117,7 +117,6 @@ struct session_menu_option { char ret; char key[15]; char title[50]; - bool supress_output; }; struct session * session_create(char *node, char *via, @@ -146,7 +145,8 @@ void session_print_motd(struct session *s, bool force) void session_recents(struct session *s); void session_who(struct session *s); char session_menu(struct session *s, char *title, char *prompt, - const struct session_menu_option *opts, size_t nopts, bool show_opts); + const struct session_menu_option *opts, size_t nopts, bool show_opts, + char *number_prompt, short *ret_number); void session_purge_logs(short days); #endif /* __SESSION_H__ */ --- sysop.c Thu Feb 16 14:32:17 2023 +++ sysop.c Wed Feb 22 21:28:42 2023 @@ -56,7 +56,7 @@ sysop_menu(struct session *s) while (!done && !s->ending) { c = session_menu(s, "Sysop Menu", "Sysop", opts, nitems(opts), - show_help); + show_help, NULL, NULL); show_help = false; switch (c) { @@ -153,7 +153,7 @@ sysop_edit_boards(struct session *s) memcpy(&dopts[db->nboards], opts, sizeof(opts)); c = session_menu(s, "Board Editor", "Sysop:Boards", dopts, - nitems(opts) + db->nboards, show_help); + nitems(opts) + db->nboards, show_help, NULL, NULL); show_help = false; switch (c) { @@ -276,7 +276,7 @@ sysop_edit_folders(struct session *s) memcpy(&dopts[db->nfolders], opts, sizeof(opts)); c = session_menu(s, "Folder Editor", "Sysop:Folders", dopts, - nitems(opts) + db->nfolders, show_help); + nitems(opts) + db->nfolders, show_help, NULL, NULL); show_help = false; switch (c) { @@ -375,7 +375,7 @@ sysop_edit_motd(struct session *s) while (!done && !s->ending) { c = session_menu(s, "MOTD Editor", "Sysop:MOTD", opts, - nitems(opts), show_help); + nitems(opts), show_help, NULL, NULL); show_help = false; switch (c) { @@ -468,16 +468,17 @@ void sysop_edit_users(struct session *s) { static const struct session_menu_option opts[] = { - { '#', "#0123456789", "Edit user [#]" }, - { '<', "<", "Previous page of users" }, - { 'l', "Ll", "List users" }, - { '>', ">", "Next page of users" }, - { 'q', "QqXx", "Return to sysop menu" }, - { '?', "?", "List menu options" }, + { '#', "#", "Edit user [#]" }, + { '<', "<", "Previous page of users" }, + { 'l', "Ll", "List users" }, + { '>', ">", "Next page of users" }, + { 'q', "QqXx", "Return to sysop menu" }, + { '?', "?", "List menu options" }, }; unsigned long *all_user_ids = NULL, *user_ids = NULL; struct user user; size_t pages, page, n, size, nall_user_ids, nuser_ids; + short suser_id; char c; char time[30]; bool show_help = false; @@ -520,7 +521,7 @@ sysop_edit_users(struct session *s) else snprintf(time, sizeof(time), "Never"); session_printf(s, "%ld %-14s %-5ld %c %c %s\r\n", - n, + n + 1, user.username, user.id, user.is_enabled ? 'Y' : ' ', @@ -532,7 +533,7 @@ sysop_edit_users(struct session *s) } c = session_menu(s, "Edit Users", "Sysop:Users", opts, - nitems(opts), show_help); + nitems(opts), show_help, "User #", &suser_id); show_help = false; handle_opt: @@ -559,22 +560,13 @@ handle_opt: find_user_ids = true; show_list = true; break; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - if (c >= nuser_ids) { + case '#': + if (suser_id < 1 || suser_id > nuser_ids) { session_printf(s, "Invalid user\r\n"); session_flush(s); break; } - sysop_edit_user(s, user_ids[c]); + sysop_edit_user(s, user_ids[suser_id - 1]); break; case '?': show_help = true; @@ -645,7 +637,7 @@ sysop_edit_user(struct session *s, unsigned long id) while (!done && !s->ending) { c = session_menu(s, title, prompt, opts, nitems(opts), - show_help); + show_help, NULL, NULL); show_help = false; handle_opt: