diff --git a/STRINGS.CHANGES b/STRINGS.CHANGES index 63ba386..15aa514 100644 --- a/STRINGS.CHANGES +++ b/STRINGS.CHANGES @@ -4,6 +4,21 @@ If you are using your own custom strings file, you will need to add / modify the new string on the line specified. Be sure to remove the start and end quotation marks. +Changes from v0.10-alpha -> v0.11-alpha +-------------------------------------------------------------- + +LINE 287 NEW +OLDSTRING: (NONE) +NEWSTRING: "\e[1;30m[\e[1;34;44m%5d\e[1;30;40m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n" + +LINE 288 NEW +OLDSTRING: (NONE) +NEWSTRING: "\e[1;30m[\e[1;34m%5d\e[1;30m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n" + +LINE 111 MODIFIED +OLDSTRING: "\e[1;32mAttribs : \e[1;37m%s\r\n" +NEWSTRING: "\e[1;32mAttribs : \e[1;37m%s \e[1;31m%s\r\n" + Changes from v0.9-alpha -> v0.10-alpha -------------------------------------------------------------- diff --git a/dist/magicka.strings b/dist/magicka.strings index 6c653cf..68f5115 100644 --- a/dist/magicka.strings +++ b/dist/magicka.strings @@ -108,7 +108,7 @@ Quoting Cancelled\r\n \e[1;32mTo : \e[1;37m%-27.27s \e[1;32mConf : \e[1;37m%-27.27s\r\n \e[1;32mSubject : \e[1;37m%-27.27s \e[1;32mArea : \e[1;37m%-27.27s\r\n \e[1;32mDate : \e[1;37m%s \e[1;32mMsgNo : \e[1;37m%4d of %4d\r\n -\e[1;32mAttribs : \e[1;37m%s\r\n +\e[1;32mAttribs : \e[1;37m%s \e[1;31m%s\r\n \e[1;30m-------------------------------------------------------------------------------\e[0m\r\n \r\n\e[1;37mPress \e[1;36mR \e[1;37mto reply, \e[1;36mQ \e[1;37mto quit, \e[1;36mB \e[1;37mto go Back, \e[1;36mSPACE \e[1;37mfor Next Mesage... \r\nSorry, you are not allowed to post in this area\r\n @@ -284,3 +284,5 @@ Read Now ? (Y / N): \e[1;37m%s (by \e[1;36m%s\e[1;37m)\r\n \e[1;35m%d:%02d%s %s, %s %d %d\r\n \r\n\r\n\e[1;37mEnter a title:\e[0m +\e[1;30m[\e[1;34;44m%5d\e[1;30;40m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n +\e[1;30m[\e[1;34m%5d\e[1;30m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n diff --git a/dist/www-bootstrap/static/flag.png b/dist/www-bootstrap/static/flag.png new file mode 100644 index 0000000..84b9d8a Binary files /dev/null and b/dist/www-bootstrap/static/flag.png differ diff --git a/dist/www-bootstrap/static/style.css b/dist/www-bootstrap/static/style.css index 367919b..4cc679a 100644 --- a/dist/www-bootstrap/static/style.css +++ b/dist/www-bootstrap/static/style.css @@ -148,6 +148,15 @@ flex-wrap: wrap; } +.msg-summary-flag { + background-color: #ff9696; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + .msg-summary { background-color: #b2ffb0; display: -webkit-box; diff --git a/dist/www/static/style.css b/dist/www/static/style.css index bf70051..a0d1115 100644 --- a/dist/www/static/style.css +++ b/dist/www/static/style.css @@ -107,6 +107,13 @@ background-color: #eee; } +.msg-summary-flag { + display: table-row; + width: auto; + clear: both; + background-color: #ff9696; +} + .msg-summary { display: table-row; width: auto; diff --git a/src/bbs.h b/src/bbs.h index e11c04c..217e8a1 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -286,6 +286,8 @@ extern struct user_record *check_user_pass(char *loginname, char *password); extern void list_users(struct user_record *user); extern int msgbase_sub_unsub(int conference, int msgbase); extern int msgbase_is_subscribed(int conference, int msgbase); +extern int msgbase_flag_unflag(struct user_record *user, int conference, int msgbase, int msgid); +extern int msgbase_is_flagged(struct user_record *user, int conference, int msgbase, int msgid); extern void active_nodes(); extern void send_node_msg(); diff --git a/src/mail_menu.c b/src/mail_menu.c index fef77a8..c754fee 100644 --- a/src/mail_menu.c +++ b/src/mail_menu.c @@ -1558,7 +1558,7 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno sprintf(buffer, "%s", asctime(&msg_date)); buffer[strlen(buffer) - 1] = '\0'; s_printf(get_string(109), buffer, mailno + 1, msghs->msg_count); - s_printf(get_string(110), (msghs->msgs[mailno]->msg_h->Attribute & JAM_MSG_SENT ? "SENT" : "")); + s_printf(get_string(110), (msghs->msgs[mailno]->msg_h->Attribute & JAM_MSG_SENT ? "SENT" : ""), (msgbase_is_flagged(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[mailno]->msg_h->MsgNum) ? "FLAGGED" : "")); s_printf(get_string(111)); body = (char *)malloc(msghs->msgs[mailno]->msg_h->TxtLen); @@ -1657,6 +1657,8 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno should_break = 1; } else if (tolower(c) == 'j' && newscan == 1) { should_break = 1; + } else if (tolower(c) == 'f') { + should_break = 1; } else if (c == '\e') { c = s_getc(); if (c == 91) { @@ -1957,6 +1959,9 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno mailno--; } free(body); + } else if (tolower(c) == 'f') { + msgbase_flag_unflag(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[mailno]->msg_h->MsgNum); + free(body); } else { free(body); } @@ -2427,7 +2432,13 @@ void list_messages(struct user_record *user) { for (j=start;jmsg_count;j++) { gmtime_r((time_t *)&msghs->msgs[j]->msg_h->DateWritten, &msg_date); if (j == i -1) { - if (msghs->msgs[j]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { + if (msgbase_is_flagged(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[j]->msg_h->MsgNum)) { + if (conf.date_style == 1) { + s_printf(get_string(286), j + 1, msghs->msgs[j]->subject, msghs->msgs[j]->from, msghs->msgs[j]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); + } else { + s_printf(get_string(286), j + 1, msghs->msgs[j]->subject, msghs->msgs[j]->from, msghs->msgs[j]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } else if (msghs->msgs[j]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { if (conf.date_style == 1) { s_printf(get_string(188), j + 1, msghs->msgs[j]->subject, msghs->msgs[j]->from, msghs->msgs[j]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); } else { @@ -2441,7 +2452,13 @@ void list_messages(struct user_record *user) { } } } else { - if (msghs->msgs[j]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { + if (msgbase_is_flagged(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[j]->msg_h->MsgNum)) { + if (conf.date_style == 1) { + s_printf(get_string(287), j + 1, msghs->msgs[j]->subject, msghs->msgs[j]->from, msghs->msgs[j]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); + } else { + s_printf(get_string(287), j + 1, msghs->msgs[j]->subject, msghs->msgs[j]->from, msghs->msgs[j]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } else if (msghs->msgs[j]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { if (conf.date_style == 1) { s_printf(get_string(127), j + 1, msghs->msgs[j]->subject, msghs->msgs[j]->from, msghs->msgs[j]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); } else { @@ -2483,7 +2500,13 @@ void list_messages(struct user_record *user) { } else if (!redraw) { s_printf("\e[%d;1H", i - start); gmtime_r((time_t *)&msghs->msgs[i-2]->msg_h->DateWritten, &msg_date); - if (msghs->msgs[i-2]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { + if (msgbase_is_flagged(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[i-2]->msg_h->MsgNum)) { + if (conf.date_style == 1) { + s_printf(get_string(286), i - 1, msghs->msgs[i-2]->subject, msghs->msgs[i-2]->from, msghs->msgs[i-2]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); + } else { + s_printf(get_string(286), i - 1, msghs->msgs[i-2]->subject, msghs->msgs[i-2]->from, msghs->msgs[i-2]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } else if (msghs->msgs[i-2]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { if (conf.date_style == 1) { s_printf(get_string(127), i - 1, msghs->msgs[i-2]->subject, msghs->msgs[i-2]->from, msghs->msgs[i-2]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); } else { @@ -2498,7 +2521,13 @@ void list_messages(struct user_record *user) { } s_printf("\e[%d;1H", i - start + 1); gmtime_r((time_t *)&msghs->msgs[i-1]->msg_h->DateWritten, &msg_date); - if (msghs->msgs[i-1]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { + if (msgbase_is_flagged(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[i-1]->msg_h->MsgNum)) { + if (conf.date_style == 1) { + s_printf(get_string(286), i, msghs->msgs[i-1]->subject, msghs->msgs[i-1]->from, msghs->msgs[i-1]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); + } else { + s_printf(get_string(286), i, msghs->msgs[i-1]->subject, msghs->msgs[i-1]->from, msghs->msgs[i-1]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } else if (msghs->msgs[i-1]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { if (conf.date_style == 1) { s_printf(get_string(188), i, msghs->msgs[i-1]->subject, msghs->msgs[i-1]->from, msghs->msgs[i-1]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); } else { @@ -2530,7 +2559,13 @@ void list_messages(struct user_record *user) { } else if (!redraw) { s_printf("\e[%d;1H", i - start + 2); gmtime_r((time_t *)&msghs->msgs[i]->msg_h->DateWritten, &msg_date); - if (msghs->msgs[i]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { + if (msgbase_is_flagged(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[i]->msg_h->MsgNum)) { + if (conf.date_style == 1) { + s_printf(get_string(286), i + 1, msghs->msgs[i]->subject, msghs->msgs[i]->from, msghs->msgs[i]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); + } else { + s_printf(get_string(286), i + 1, msghs->msgs[i]->subject, msghs->msgs[i]->from, msghs->msgs[i]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } else if (msghs->msgs[i]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { if (conf.date_style == 1) { s_printf(get_string(127), i + 1, msghs->msgs[i]->subject, msghs->msgs[i]->from, msghs->msgs[i]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); } else { @@ -2545,7 +2580,13 @@ void list_messages(struct user_record *user) { } s_printf("\e[%d;1H", i - start + 1); gmtime_r((time_t *)&msghs->msgs[i-1]->msg_h->DateWritten, &msg_date); - if (msghs->msgs[i-1]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { + if (msgbase_is_flagged(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[i-1]->msg_h->MsgNum)) { + if (conf.date_style == 1) { + s_printf(get_string(286), i, msghs->msgs[i-1]->subject, msghs->msgs[i-1]->from, msghs->msgs[i-1]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); + } else { + s_printf(get_string(286), i, msghs->msgs[i-1]->subject, msghs->msgs[i-1]->from, msghs->msgs[i-1]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } else if (msghs->msgs[i-1]->msg_h->MsgNum > jlr.HighReadMsg || all_unread) { if (conf.date_style == 1) { s_printf(get_string(188), i, msghs->msgs[i-1]->subject, msghs->msgs[i-1]->from, msghs->msgs[i-1]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); } else { @@ -2620,6 +2661,9 @@ void list_messages(struct user_record *user) { JAM_CloseMB(jb); free(jb); } + } else if (tolower(c) == 'f') { + redraw = 1; + msgbase_flag_unflag(user, user->cur_mail_conf, user->cur_mail_area, msghs->msgs[i-1]->msg_h->MsgNum); } } } diff --git a/src/users.c b/src/users.c index a1e0d7a..6937738 100644 --- a/src/users.c +++ b/src/users.c @@ -140,6 +140,102 @@ int save_user(struct user_record *user) { } +int msgbase_flag_unflag(struct user_record *user, int conference, int msgbase, int msgid) { + sqlite3 *db; + sqlite3_stmt *res; + int rc; + char buffer[PATH_MAX]; + char *create_sql = "CREATE TABLE IF NOT EXISTS msg_flags (conference INTEGER, msgbase INTEGER, uid INTEGER, msg INTEGER);"; + char *flag_buf = "INSERT INTO msg_flags (conference, msgbase, uid, msg) VALUES(?, ?, ?, ?)"; + char *unflag_buf = "DELETE FROM msg_flags WHERE conference=? AND msgbase=? AND uid=? AND msg=?"; + char *err_msg = 0; + int flagunflag = 0; + + + flagunflag = msgbase_is_flagged(user, conference, msgbase, msgid); + + snprintf(buffer, PATH_MAX, "%s/users.sq3", conf.bbs_path); + + rc = sqlite3_open(buffer, &db); + + if (rc != SQLITE_OK) { + dolog("Cannot open database: %s", sqlite3_errmsg(db)); + sqlite3_close(db); + + return 0; + } + sqlite3_busy_timeout(db, 5000); + rc = sqlite3_exec(db, create_sql, 0, 0, &err_msg); + if (rc != SQLITE_OK ) { + + dolog("SQL error: %s", err_msg); + + sqlite3_free(err_msg); + sqlite3_close(db); + + return 0; + } + if (flagunflag == 1) { + rc = sqlite3_prepare_v2(db, unflag_buf, -1, &res, 0); + } else { + rc = sqlite3_prepare_v2(db, flag_buf, -1, &res, 0); + } + + sqlite3_bind_int(res, 1, conference); + sqlite3_bind_int(res, 2, msgbase); + sqlite3_bind_int(res, 3, user->id); + sqlite3_bind_int(res, 4, msgid); + + rc = sqlite3_step(res); + + sqlite3_finalize(res); + sqlite3_close(db); + + return 1; +} + +int msgbase_is_flagged(struct user_record *user, int conference, int msgbase, int msgid) { + sqlite3 *db; + sqlite3_stmt *res; + int rc; + char buffer[PATH_MAX]; + + char *sql_buf = "SELECT * FROM msg_flags WHERE conference=? AND msgbase=? AND uid=? AND msg=?"; + + snprintf(buffer, PATH_MAX, "%s/users.sq3", conf.bbs_path); + + rc = sqlite3_open(buffer, &db); + + if (rc != SQLITE_OK) { + dolog("Cannot open database: %s", sqlite3_errmsg(db)); + sqlite3_close(db); + + exit(1); + } + sqlite3_busy_timeout(db, 5000); + + rc = sqlite3_prepare_v2(db, sql_buf, -1, &res, 0); + + if (rc != SQLITE_OK) { + sqlite3_close(db); + return 0; + } + + sqlite3_bind_int(res, 1, conference); + sqlite3_bind_int(res, 2, msgbase); + sqlite3_bind_int(res, 3, user->id); + sqlite3_bind_int(res, 4, msgid); + + if (sqlite3_step(res) != SQLITE_ROW) { + sqlite3_finalize(res); + sqlite3_close(db); + return 0; + } + sqlite3_finalize(res); + sqlite3_close(db); + return 1; +} + int msgbase_sub_unsub(int conference, int msgbase) { sqlite3 *db; sqlite3_stmt *res; diff --git a/src/www_msgs.c b/src/www_msgs.c index e0f26ca..5b305a3 100644 --- a/src/www_msgs.c +++ b/src/www_msgs.c @@ -195,7 +195,13 @@ char *www_msgs_messagelist(struct user_record *user, int conference, int area, i to = www_sanitize(mhrs->msgs[i]->to); from = www_sanitize(mhrs->msgs[i]->from); subject = www_sanitize(mhrs->msgs[i]->subject); - if (mhrs->msgs[i]->msg_h->MsgNum > jlr.HighReadMsg) { + if (msgbase_is_flagged(user, user->cur_mail_conf, user->cur_mail_area, mhrs->msgs[i]->msg_h->MsgNum)) { + if (conf.date_style == 1) { + sprintf(buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); + } else { + sprintf(buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } else if (mhrs->msgs[i]->msg_h->MsgNum > jlr.HighReadMsg) { if (conf.date_style == 1) { sprintf(buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); } else {