diff --git a/coreapi/chat.c b/coreapi/chat.c index abbbbf745..0140bdbe1 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -400,6 +400,7 @@ static LinphoneChatRoom * _linphone_core_create_chat_room(LinphoneCore *lc, Linp cr->lc = lc; cr->peer = linphone_address_as_string(addr); cr->peer_url = addr; + cr->unread_count = -1; lc->chatrooms = ms_list_append(lc->chatrooms, (void *)cr); return cr; } @@ -619,6 +620,8 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM msg->dir=LinphoneChatMessageOutgoing; msg->from=linphone_address_new(identity); msg->storage_id=linphone_chat_message_store(msg); + + if(cr->unread_count >= 0 && !msg->is_read) cr->unread_count++; // add to transient list cr->transient_messages = ms_list_append(cr->transient_messages, linphone_chat_message_ref(msg)); @@ -772,6 +775,10 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag linphone_address_destroy(addr); msg->storage_id=linphone_chat_message_store(msg); + + if(cr->unread_count < 0) cr->unread_count = 1; + else cr->unread_count++; + linphone_chat_room_message_received(cr,lc,msg); linphone_chat_message_unref(msg); } diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 22da7b8d0..a5985f4d3 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_PATH_SIZE 1024 #include "sqlite3.h" +#include static ORTP_INLINE LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, unsigned int storage_id){ MSList* transients = cr->transient_messages; @@ -286,6 +287,9 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){ char *buf; if (lc->db==NULL) return ; + + // optimization: do not modify the database if no message is marked as unread + if(linphone_chat_room_get_unread_messages_count(cr) == 0) return; peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); buf=sqlite3_mprintf("UPDATE history SET read=%i WHERE remoteContact = %Q;", @@ -293,6 +297,8 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){ linphone_sql_request(lc->db,buf); sqlite3_free(buf); ms_free(peer); + + cr->unread_count = 0; } void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { @@ -315,6 +321,9 @@ static int linphone_chat_room_get_messages_count(LinphoneChatRoom *cr, bool_t un int returnValue; if (lc->db==NULL) return 0; + + // optimization: do not read database if the count is already available in memory + if(unread_only && cr->unread_count >= 0) return cr->unread_count; peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); buf=sqlite3_mprintf("SELECT count(*) FROM history WHERE remoteContact = %Q %s;",peer,unread_only?"AND read = 0":""); @@ -327,6 +336,11 @@ static int linphone_chat_room_get_messages_count(LinphoneChatRoom *cr, bool_t un sqlite3_finalize(selectStatement); sqlite3_free(buf); ms_free(peer); + + /* no need to test the sign of cr->unread_count here + * because it has been tested above */ + if(unread_only) cr->unread_count = numrows; + return numrows; } @@ -347,6 +361,11 @@ void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage buf=sqlite3_mprintf("DELETE FROM history WHERE id = %i;", msg->storage_id); linphone_sql_request(lc->db,buf); sqlite3_free(buf); + + if(cr->unread_count >= 0 && !msg->is_read) { + assert(cr->unread_count > 0); + cr->unread_count--; + } } void linphone_chat_room_delete_history(LinphoneChatRoom *cr){ @@ -361,6 +380,8 @@ void linphone_chat_room_delete_history(LinphoneChatRoom *cr){ linphone_sql_request(lc->db,buf); sqlite3_free(buf); ms_free(peer); + + if(cr->unread_count > 0) cr->unread_count = 0; } MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, int endm){ diff --git a/coreapi/private.h b/coreapi/private.h index 5366b9699..b48111c67 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -556,6 +556,7 @@ struct _LinphoneChatRoom{ LinphoneAddress *peer_url; MSList *messages_hist; MSList *transient_messages; + int unread_count; LinphoneIsComposingState remote_is_composing; LinphoneIsComposingState is_composing; belle_sip_source_t *remote_composing_refresh_timer;