jcs
/subtext
/amendments
/98
mail: Make menu work like others where just a letter does something
For menu options that require a message id, use a field input for that
jcs made amendment 98 over 2 years ago
--- mail.c Tue Apr 26 20:55:15 2022
+++ mail.c Thu Apr 28 17:05:12 2022
@@ -58,6 +58,8 @@ void mail_delete(struct session *s, unsigned long idx)
void mail_mark_unread(struct session *s, unsigned long idx);
void mail_list(struct session *s, bool sent, unsigned long **mail_ids,
size_t *nmsgs);
+short mail_get_message_id(struct session *s, size_t nmsgs, char *prompt,
+ short initial);
void
mail_free_message_strings(struct private_message *msg)
@@ -72,6 +74,38 @@ mail_free_message_strings(struct private_message *msg)
}
}
+short
+mail_get_message_id(struct session *s, size_t nmsgs, char *prompt,
+ short initial)
+{
+ char *tmp;
+ char start_s[10] = { 0 };
+ short ret;
+
+ if (initial > -1)
+ snprintf(start_s, sizeof(start_s), "%d", initial);
+
+get_id:
+ if (prompt)
+ session_printf(s, "{{B}}%s:{{/}} ", prompt);
+
+ tmp = session_field_input(s, 5, 5, start_s, 0);
+ if (tmp == NULL)
+ return -1;
+ session_output(s, "\r\n", 2);
+ session_flush(s);
+
+ if (sscanf(tmp, "%d", &ret) != 1 || ret < 1 || ret > nmsgs) {
+ session_printf(s, "{{B}}Invalid message ID{{/}} (^C to cancel)\r\n");
+ session_flush(s);
+ free(tmp);
+ goto get_id;
+ }
+
+ free(tmp);
+ return ret;
+}
+
void
mail_menu(struct session *s)
{
@@ -80,6 +114,7 @@ mail_menu(struct session *s)
bool done = false;
char *field;
unsigned long *mail_ids = NULL;
+ unsigned short c;
short ret;
if (!s->user) {
@@ -100,44 +135,69 @@ mail_menu(struct session *s)
session_output_template(s, "{{B}}Mail>{{/}} ");
session_flush(s);
- field = session_field_input(s, 30, 30, NULL, 0);
- if (field == NULL)
+get_menu_option:
+ c = session_input_char(s);
+ if (s->ending)
return;
- session_output(s, "\r\n", 2);
+ if (c == '\r' || c == 0 || c > 255)
+ goto get_menu_option;
+
+ session_printf(s, "%c\r\n", c);
session_flush(s);
-
- if (sscanf(field, "%[Cc] %s", &l, &arg) == 2)
+
+ switch (c) {
+ case 'c':
+ case 'C':
mail_compose(s, arg, NULL, NULL);
- else if (sscanf(field, "%[Cc]", &l) == 1 && field[1] == '\0')
- mail_compose(s, NULL, NULL, NULL);
- else if (sscanf(field, "%[Dd] %ld%n", &l, &id, &count) == 2 &&
- field[count] == '\0')
- mail_delete(s, id);
- else if (sscanf(field, "%[Uu] %ld%n", &l, &id, &count) == 2 &&
- field[count] == '\0')
- mail_mark_unread(s, id);
- else if (sscanf(field, "%ld%n", &id, &count) == 1 &&
- field[count] == '\0') {
- if (id < 1 || id > nmsgs) {
- session_output_string(s, "Invalid message id\r\n");
- session_flush(s);
- continue;
- }
- mail_read(s, mail_ids[id - 1]);
- }
- else if (sscanf(field, "%[Ll]", &l) == 1 && field[1] == '\0')
+ break;
+ case 'd':
+ case 'D':
+ id = mail_get_message_id(s, nmsgs, "Message # to delete", -1);
+ if (id != -1)
+ mail_delete(s, id);
+ break;
+ case 'h':
+ case 'H':
+ case '?':
+ mail_help(s);
+ break;
+ case 'l':
+ case 'L':
mail_list(s, false, &mail_ids, &nmsgs);
- else if (sscanf(field, "%[QqXx]", &l) == 1 && field[1] == '\0')
+ break;
+ case 'q':
+ case 'Q':
+ case 'x':
+ case 'X':
done = true;
- else if (sscanf(field, "%[?Hh]", &l) == 1 && field[1] == '\0')
- mail_help(s);
- else if (field[0] != '\0') {
+ break;
+ case 'u':
+ case 'U':
+ id = mail_get_message_id(s, nmsgs, "Message # to mark unread",
+ -1);
+ if (id != -1)
+ mail_mark_unread(s, id);
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ id = mail_get_message_id(s, nmsgs, "Message # to read",
+ c - '0');
+ if (id != -1)
+ mail_read(s, mail_ids[id - 1]);
+ break;
+ default:
session_output_template(s,
"Invalid option ({{B}}?{{/}} for help)\r\n");
session_flush(s);
}
-
- free(field);
}
}