From 9db6f437cbbced6d7e241cb888fc22304270ab54 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Fri, 15 Jul 2022 13:56:13 -0400 Subject: [PATCH] Add a web API command for the server STAT command. This will allow us to implement a new-messages check that does not require loading the entire room again. --- webcit-ng/api.txt | 1 + webcit-ng/room_functions.c | 40 ++++++++++++++++++++++++++++++-- webcit-ng/static/js/defs.js | 1 + webcit-ng/static/js/main.js | 2 ++ webcit-ng/static/js/view_mail.js | 9 +++++-- webcit-ng/webcit.h | 2 ++ 6 files changed, 51 insertions(+), 4 deletions(-) diff --git a/webcit-ng/api.txt b/webcit-ng/api.txt index e46e631be..972b5efd5 100644 --- a/webcit-ng/api.txt +++ b/webcit-ng/api.txt @@ -11,6 +11,7 @@ GET /ctdl/r/ROOMNAME/info.txt Returns the room info banner for this room GET /ctdl/r/ROOMNAME/msgs.all JSON array of message list in room GET /ctdl/r/ROOMNAME/msgs.new JSON array of message list in room (new messages) GET /ctdl/r/ROOMNAME/mailbox JSON dictionary of a mailbox summary in this room +GET /ctdl/r/ROOMNAME/stat JSON dictionary of the server STAT command (room name and modification time) GET /ctdl/r/ROOMNAME/MSGNUM Retrieve the content of an individual message GET /ctdl/r/ROOMNAME/MSGNUM/json Retrieve an individual message in a room, encapsulated in JSON DELETE /ctdl/r/ROOMNAME/MSGNUM Deletes a message from a room diff --git a/webcit-ng/room_functions.c b/webcit-ng/room_functions.c index bafb7c9dd..d2e75f55b 100644 --- a/webcit-ng/room_functions.c +++ b/webcit-ng/room_functions.c @@ -73,6 +73,35 @@ int match_etags(char *taglist, long msgnum) { } +// Client is requesting a STAT (name and modification time) of the current room +void json_stat(struct http_transaction *h, struct ctdlsession *c) { + char buf[1024]; + char field[1024]; + + ctdl_printf(c, "STAT"); + ctdl_readline(c, buf, sizeof(buf)); + syslog(LOG_DEBUG, "%s", buf); + if (buf[0] == '2') { + JsonValue *j = NewJsonObject(HKEY("stat")); + extract_token(field, &buf[4], 0, '|', sizeof field); + JsonObjectAppend(j, NewJsonPlainString(HKEY("name"), field, -1)); + JsonObjectAppend(j, NewJsonNumber(HKEY("room_mtime"), extract_long(&buf[4], 1))); + + StrBuf *sj = NewStrBuf(); + SerializeJson(sj, j, 1); // '1' == free the source array + add_response_header(h, strdup("Content-type"), strdup("application/json")); + h->response_code = 200; + h->response_string = strdup("OK"); + h->response_body_length = StrLength(sj); + h->response_body = SmashStrBuf(&sj); + } + else { + do_404(h); + } + return; +} + + // Client is requesting a mailbox summary of the current room void json_mailbox(struct http_transaction *h, struct ctdlsession *c) { char buf[1024]; @@ -188,6 +217,11 @@ void object_in_room(struct http_transaction *h, struct ctdlsession *c) { return; } + if (!strcasecmp(buf, "stat")) { // Client is requesting a stat command (name and modification time) + json_stat(h, c); + return; + } + if (!strncasecmp(buf, "msgs.", 5)) { // Client is requesting a list of message numbers unescape_input(&buf[5]); json_msglist(h, c, &buf[5]); @@ -474,6 +508,8 @@ void get_the_room_itself(struct http_transaction *h, struct ctdlsession *c) { JsonObjectAppend(j, NewJsonNumber(HKEY("new_messages"), c->new_messages)); JsonObjectAppend(j, NewJsonNumber(HKEY("total_messages"), c->total_messages)); JsonObjectAppend(j, NewJsonNumber(HKEY("last_seen"), c->last_seen)); + JsonObjectAppend(j, NewJsonNumber(HKEY("room_mtime"), c->room_mtime)); + JsonObjectAppend(j, NewJsonNumber(HKEY("new_mail"), c->new_mail)); StrBuf *sj = NewStrBuf(); SerializeJson(sj, j, 1); // '1' == free the source array @@ -597,13 +633,13 @@ void ctdl_r(struct http_transaction *h, struct ctdlsession *c) { c->last_seen = extract_long(&buf[4], 6); // The highest message number the user has read in this room // 7 (int)rmailflag Boolean flag: 1 if this is a Mail> room, 0 otherwise. c->is_room_aide = extract_int(&buf[4], 8); - // 9 (int)newmailcount The number of new Mail messages the user has + c->new_mail = extract_int(&buf[4], 9); // the number of new messages in the user's INBOX // 10 (int)CC->room.QRfloor The floor number this room resides on c->room_current_view = extract_int(&buf[4], 11); c->room_default_view = extract_int(&buf[4], 12); // 13 (int)is_trash Boolean flag: 1 if this is the user's Trash folder, 0 otherwise. room_flags2 = extract_long(&buf[4], 14); // More flags associated with this room. - // 15 (long)CC->room.QRmtime Timestamp of the last write activity in this room + c->room_mtime = extract_long(&buf[4], 15); // Timestamp of the last write activity in this room // If any of these three conditions are met, let the client know it has permission to delete messages. if ((c->is_room_aide) || (room_flags & QR_MAILBOX) || (room_flags2 & QR2_COLLABDEL)) { diff --git a/webcit-ng/static/js/defs.js b/webcit-ng/static/js/defs.js index 5a7397e99..737218a32 100644 --- a/webcit-ng/static/js/defs.js +++ b/webcit-ng/static/js/defs.js @@ -19,6 +19,7 @@ var current_user = _("Not logged in."); var serv_info; var last_seen = 0; var is_room_aide = 0; +var room_mtime = 0; var can_delete_messages = 0; var messages_per_page = 20; var march_list = [] ; diff --git a/webcit-ng/static/js/main.js b/webcit-ng/static/js/main.js index 20b629a3d..ec9ff04ff 100644 --- a/webcit-ng/static/js/main.js +++ b/webcit-ng/static/js/main.js @@ -73,7 +73,9 @@ function gotoroom(roomname) { default_view = data.default_view; last_seen = data.last_seen; is_room_aide = data.is_room_aide; + room_mtime = data.room_mtime; can_delete_messages = data.can_delete_messages; + console.log("new mail: " + data.new_mail); update_banner(); render_room_view(0, 9999999999); } diff --git a/webcit-ng/static/js/view_mail.js b/webcit-ng/static/js/view_mail.js index 1d218fb9e..b53cb7adc 100644 --- a/webcit-ng/static/js/view_mail.js +++ b/webcit-ng/static/js/view_mail.js @@ -8,6 +8,7 @@ var selected_message = 0; // Remember the last message that was selected var RefreshMailboxInterval; // We store our refresh timer here +var last_mtime; // Watch this mailbox using the room's mtime // Render a message into the mailbox view @@ -139,6 +140,7 @@ function mail_display() { = "
" ; + last_mtime = 0; // Keep track of room's mod time so we know when to refresh refresh_mail_display(); try { // if this was already set up, clear it so there aren't multiple clearInterval(RefreshMailboxInterval); @@ -152,8 +154,6 @@ function mail_display() { // Display or refresh the mailbox function refresh_mail_display() { - console.log("refresh_mail_display()"); - // If the "ctdl-mailbox-pane" no longer exists, the user has navigated to a different part of the site, // so cancel the refresh. try { @@ -166,6 +166,11 @@ function refresh_mail_display() { return; } + if (last_mtime == 0) { + last_mtime = room_mtime; + } + console.log("refresh_mail_display() last_mtime is " + last_mtime + " FIXME"); + // Now go to the server. url = "/ctdl/r/" + escapeHTMLURI(current_room) + "/mailbox"; fetch_mailbox = async() => { diff --git a/webcit-ng/webcit.h b/webcit-ng/webcit.h index eeeac89b2..9e6d069ba 100644 --- a/webcit-ng/webcit.h +++ b/webcit-ng/webcit.h @@ -90,6 +90,8 @@ struct ctdlsession { int total_messages; time_t last_access; // Timestamp of last request that used this session time_t num_requests_handled; + time_t room_mtime; // Timestampt of the most recent write activity in this room + int new_mail; // number of new messages in the user's INBOX }; extern char *ssl_cipher_list; -- 2.39.2