diff --git a/src/mrchatlist.c b/src/mrchatlist.c index 23ac4b7d..e30314b7 100644 --- a/src/mrchatlist.c +++ b/src/mrchatlist.c @@ -319,7 +319,7 @@ int mrchatlist_load_from_db__(mrchatlist_t* ths, int listflags, const char* quer /* select example with left join and minimum: http://stackoverflow.com/questions/7588142/mysql-left-join-min */ #define QUR1 "SELECT c.id, m.id FROM chats c " \ - " LEFT JOIN msgs m ON (c.id=m.chat_id AND m.timestamp=(SELECT MAX(timestamp) FROM msgs WHERE chat_id=c.id)) " \ + " LEFT JOIN msgs m ON (c.id=m.chat_id AND m.timestamp=(SELECT MAX(timestamp) FROM msgs WHERE chat_id=c.id AND hidden=0)) " \ " WHERE c.id>" MR_STRINGIFY(MR_CHAT_ID_LAST_SPECIAL) " AND c.blocked=0" #define QUR2 " GROUP BY c.id " /* GROUP BY is needed as there may be several messages with the same timestamp */ \ " ORDER BY MAX(c.draft_timestamp, IFNULL(m.timestamp,0)) DESC,m.id DESC;" /* the list starts with the newest chats */ diff --git a/src/mrcontact.h b/src/mrcontact.h index 728d9c3d..82b03ddf 100644 --- a/src/mrcontact.h +++ b/src/mrcontact.h @@ -37,6 +37,7 @@ extern "C" { typedef struct _mrcontact mrcontact_t; #define MR_CONTACT_ID_SELF 1 +#define MR_CONTACT_ID_SYSTEM 2 #define MR_CONTACT_ID_LAST_SPECIAL 9 diff --git a/src/mrmailbox.c b/src/mrmailbox.c index 8d5bad89..a74b9154 100644 --- a/src/mrmailbox.c +++ b/src/mrmailbox.c @@ -1403,6 +1403,7 @@ mrarray_t* mrmailbox_get_chat_msgs(mrmailbox_t* mailbox, uint32_t chat_id, uint3 " LEFT JOIN chats ON m.chat_id=chats.id" " LEFT JOIN contacts ON m.from_id=contacts.id" " WHERE m.from_id!=" MR_STRINGIFY(MR_CONTACT_ID_SELF) + " AND m.hidden=0 " " AND chats.blocked=2 " " AND contacts.blocked=0" " ORDER BY m.timestamp,m.id;"); /* the list starts with the oldest message*/ @@ -1413,7 +1414,9 @@ mrarray_t* mrmailbox_get_chat_msgs(mrmailbox_t* mailbox, uint32_t chat_id, uint3 "SELECT m.id, m.timestamp" " FROM msgs m" " LEFT JOIN contacts ct ON m.from_id=ct.id" - " WHERE m.starred=1 AND ct.blocked=0" + " WHERE m.starred=1 " + " AND m.hidden=0 " + " AND ct.blocked=0" " ORDER BY m.timestamp,m.id;"); /* the list starts with the oldest message*/ } else @@ -1422,7 +1425,9 @@ mrarray_t* mrmailbox_get_chat_msgs(mrmailbox_t* mailbox, uint32_t chat_id, uint3 "SELECT m.id, m.timestamp" " FROM msgs m" " LEFT JOIN contacts ct ON m.from_id=ct.id" - " WHERE m.chat_id=? AND ct.blocked=0" + " WHERE m.chat_id=? " + " AND m.hidden=0 " + " AND ct.blocked=0" " ORDER BY m.timestamp,m.id;"); /* the list starts with the oldest message*/ sqlite3_bind_int(stmt, 1, chat_id); } @@ -1529,6 +1534,7 @@ mrarray_t* mrmailbox_search_msgs(mrmailbox_t* mailbox, uint32_t chat_id, const c "SELECT m.id, m.timestamp FROM msgs m" " LEFT JOIN contacts ct ON m.from_id=ct.id" " WHERE m.chat_id=? " + " AND m.hidden=0 " " AND ct.blocked=0 AND (txt LIKE ? OR ct.name LIKE ?)" " ORDER BY m.timestamp,m.id;"); /* chats starts with the oldest message*/ sqlite3_bind_int (stmt, 1, chat_id); @@ -1542,6 +1548,7 @@ mrarray_t* mrmailbox_search_msgs(mrmailbox_t* mailbox, uint32_t chat_id, const c " LEFT JOIN contacts ct ON m.from_id=ct.id" " LEFT JOIN chats c ON m.chat_id=c.id" " WHERE m.chat_id>" MR_STRINGIFY(MR_CHAT_ID_LAST_SPECIAL) + " AND m.hidden=0 " " AND (c.blocked=0 OR c.blocked=?)" " AND ct.blocked=0 AND (m.txt LIKE ? OR ct.name LIKE ?)" " ORDER BY m.timestamp DESC,m.id DESC;"); /* chat overview starts with the newest message*/ @@ -1667,7 +1674,10 @@ int mrmailbox_get_fresh_msg_count__(mrmailbox_t* mailbox, uint32_t chat_id) sqlite3_stmt* stmt = NULL; stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_COUNT_FROM_msgs_WHERE_state_AND_chat_id, - "SELECT COUNT(*) FROM msgs WHERE state=" MR_STRINGIFY(MR_STATE_IN_FRESH) " AND chat_id=?;"); /* we have an index over the state-column, this should be sufficient as there are typically only few fresh messages */ + "SELECT COUNT(*) FROM msgs " + " WHERE state=" MR_STRINGIFY(MR_STATE_IN_FRESH) + " AND hidden=0 " + " AND chat_id=?;"); /* we have an index over the state-column, this should be sufficient as there are typically only few fresh messages */ sqlite3_bind_int(stmt, 1, chat_id); if( sqlite3_step(stmt) != SQLITE_ROW ) { @@ -1687,7 +1697,8 @@ uint32_t mrmailbox_get_last_deaddrop_fresh_msg__(mrmailbox_t* mailbox) " FROM msgs m " " LEFT JOIN chats c ON c.id=m.chat_id " " WHERE m.state=" MR_STRINGIFY(MR_STATE_IN_FRESH) - " AND c.blocked=" MR_STRINGIFY(MR_CHAT_DEADDROP_BLOCKED) + " AND m.hidden=0 " + " AND c.blocked=" MR_STRINGIFY(MR_CHAT_DEADDROP_BLOCKED) " ORDER BY m.timestamp DESC, m.id DESC;"); /* we have an index over the state-column, this should be sufficient as there are typically only few fresh messages */ if( sqlite3_step(stmt) != SQLITE_ROW ) { @@ -2307,7 +2318,7 @@ static uint32_t mrmailbox_send_msg_i__(mrmailbox_t* mailbox, mrchat_t* chat, con /* add message to the database */ stmt = mrsqlite3_predefine__(mailbox->m_sql, INSERT_INTO_msgs_mcftttstpb, - "INSERT INTO msgs (rfc724_mid,chat_id,from_id,to_id, timestamp,type,state, txt,param) VALUES (?,?,?,?, ?,?,?, ?,?);"); + "INSERT INTO msgs (rfc724_mid,chat_id,from_id,to_id, timestamp,type,state, txt,param,hidden) VALUES (?,?,?,?, ?,?,?, ?,?,?);"); sqlite3_bind_text (stmt, 1, rfc724_mid, -1, SQLITE_STATIC); sqlite3_bind_int (stmt, 2, MR_CHAT_ID_MSGS_IN_CREATION); sqlite3_bind_int (stmt, 3, MR_CONTACT_ID_SELF); @@ -2317,6 +2328,7 @@ static uint32_t mrmailbox_send_msg_i__(mrmailbox_t* mailbox, mrchat_t* chat, con sqlite3_bind_int (stmt, 7, MR_STATE_OUT_PENDING); sqlite3_bind_text (stmt, 8, msg->m_text? msg->m_text : "", -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 9, msg->m_param->m_packed, -1, SQLITE_STATIC); + sqlite3_bind_int (stmt, 10, msg->m_hidden); if( sqlite3_step(stmt) != SQLITE_DONE ) { mrmailbox_log_error(mailbox, 0, "Cannot send message, cannot insert to database.", chat->m_id); goto cleanup; diff --git a/src/mrmailbox_oob.c b/src/mrmailbox_oob.c index ac3023f4..2947723f 100644 --- a/src/mrmailbox_oob.c +++ b/src/mrmailbox_oob.c @@ -426,6 +426,7 @@ static void send_handshake_msg(mrmailbox_t* mailbox, uint32_t chat_id, const cha msg->m_type = MR_MSG_TEXT; msg->m_text = mr_mprintf("Secure-Join: %s", step); + msg->m_hidden = 1; mrparam_set_int(msg->m_param, MRP_SYSTEM_CMD, MR_SYSTEM_OOB_VERIFY_MESSAGE); mrparam_set (msg->m_param, MRP_SYSTEM_CMD_PARAM, step); diff --git a/src/mrmailbox_receive_imf.c b/src/mrmailbox_receive_imf.c index d0b771a0..429ce006 100644 --- a/src/mrmailbox_receive_imf.c +++ b/src/mrmailbox_receive_imf.c @@ -848,6 +848,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina uint32_t chat_id = 0; int chat_id_blocked = 0; int state = MR_STATE_UNDEFINED; + int hidden = 0; sqlite3_stmt* stmt; size_t i, icnt; @@ -1112,6 +1113,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina /* check of the message is a special handshake message; if so, mark it as "seen" here and handle it when done */ is_handshake_message = mrmailbox_oob_is_handshake_message__(mailbox, mime_parser); if( is_handshake_message ) { + hidden = 1; if( state==MR_STATE_IN_FRESH || state==MR_STATE_IN_NOTICED ) { state = MR_STATE_IN_SEEN; } @@ -1205,7 +1207,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina stmt = mrsqlite3_predefine__(mailbox->m_sql, INSERT_INTO_msgs_msscftttsmttpb, "INSERT INTO msgs (rfc724_mid,server_folder,server_uid,chat_id,from_id, to_id,timestamp,timestamp_sent,timestamp_rcvd,type, state,msgrmsg,txt,txt_raw,param,bytes)" - " VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?,?,?,?);"); + " VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?,?,?,?,?);"); sqlite3_bind_text (stmt, 1, rfc724_mid, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 2, server_folder, -1, SQLITE_STATIC); sqlite3_bind_int (stmt, 3, server_uid); @@ -1222,6 +1224,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina sqlite3_bind_text (stmt, 14, txt_raw? txt_raw : "", -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 15, part->m_param->m_packed, -1, SQLITE_STATIC); sqlite3_bind_int (stmt, 16, part->m_bytes); + sqlite3_bind_int (stmt, 17, hidden); if( sqlite3_step(stmt) != SQLITE_DONE ) { mrmailbox_log_info(mailbox, 0, "Cannot write DB."); goto cleanup; /* i/o error - there is nothing more we can do - in other cases, we try to write at least an empty record */ diff --git a/src/mrmsg-private.h b/src/mrmsg-private.h index e6a63ee5..4f83fdf9 100644 --- a/src/mrmsg-private.h +++ b/src/mrmsg-private.h @@ -75,6 +75,8 @@ struct _mrmsg int m_state; /**< Message state. It is recommended to use mrmsg_get_state() to access this field. */ + int m_hidden; /**< Used eg. for handshaking messages. */ + time_t m_timestamp; /**< Unix time for sorting. 0 if unset. */ time_t m_timestamp_sent; /**< Unix time the message was sent. 0 if unset. */ time_t m_timestamp_rcvd; /**< Unix time the message was recveived. 0 if unset. */ diff --git a/src/mrmsg.c b/src/mrmsg.c index fa1617d1..287dcd00 100644 --- a/src/mrmsg.c +++ b/src/mrmsg.c @@ -106,6 +106,8 @@ void mrmsg_empty(mrmsg_t* msg) mrparam_set_packed(msg->m_param, NULL); msg->m_mailbox = NULL; + + msg->m_hidden = 0; } @@ -853,7 +855,7 @@ cleanup: #define MR_MSG_FIELDS " m.id,rfc724_mid,m.server_folder,m.server_uid,m.chat_id, " \ " m.from_id,m.to_id,m.timestamp,m.timestamp_sent,m.timestamp_rcvd, m.type,m.state,m.msgrmsg,m.txt, " \ - " m.param,m.starred,c.blocked " + " m.param,m.starred,m.hidden,c.blocked " static int mrmsg_set_from_stmt__(mrmsg_t* ths, sqlite3_stmt* row, int row_offset) /* field order must be MR_MSG_FIELDS */ @@ -879,6 +881,7 @@ static int mrmsg_set_from_stmt__(mrmsg_t* ths, sqlite3_stmt* row, int row_offset mrparam_set_packed( ths->m_param, (char*)sqlite3_column_text (row, row_offset++)); ths->m_starred = sqlite3_column_int (row, row_offset++); + ths->m_hidden = sqlite3_column_int (row, row_offset++); ths->m_chat_blocked = sqlite3_column_int (row, row_offset++); if( ths->m_chat_blocked == 2 ) { diff --git a/src/mrsqlite3.c b/src/mrsqlite3.c index 9d8d2c45..3f66cab8 100644 --- a/src/mrsqlite3.c +++ b/src/mrsqlite3.c @@ -371,6 +371,16 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags) mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); } #undef NEW_DB_VERSION + + #define NEW_DB_VERSION 28 + if( dbversion < NEW_DB_VERSION ) + { + mrsqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN hidden INTEGER DEFAULT 0;"); + + dbversion = NEW_DB_VERSION; + mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); + } + #undef NEW_DB_VERSION } mrmailbox_log_info(ths->m_mailbox, 0, "Opened \"%s\" successfully.", dbfile);