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: