Commit 54a672e4 authored by Ronan's avatar Ronan

feat(chat): add many functions to deal with unread chat message count (on proxies, global, ...)

parent ea085a42
......@@ -7526,6 +7526,20 @@ void linphone_core_check_for_update(LinphoneCore *lc, const char *current_versio
#endif
}
int linphone_core_get_unread_chat_message_count (const LinphoneCore *lc) {
return L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getUnreadChatMessageCount();
}
int linphone_core_get_unread_chat_message_count_from_local (const LinphoneCore *lc, const LinphoneAddress *address) {
return L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getUnreadChatMessageCount(
LinphonePrivate::IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(address))
);
}
int linphone_core_get_unread_chat_message_count_from_active_locals (const LinphoneCore *lc) {
return L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getUnreadChatMessageCountFromActiveLocals();
}
bool_t linphone_core_has_crappy_opengl(LinphoneCore *lc) {
MSFactory * factory = linphone_core_get_ms_factory(lc);
MSDevicesInfo *devices = ms_factory_get_devices_info(factory);
......
......@@ -28,6 +28,7 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org)
#include "mediastreamer2/mediastream.h"
#include "core/core.h"
#include "enum.h"
#include "private.h"
......@@ -1601,3 +1602,9 @@ bool_t linphone_proxy_config_is_push_notification_allowed(const LinphoneProxyCon
void linphone_proxy_config_set_push_notification_allowed(LinphoneProxyConfig *cfg, bool_t is_allowed) {
cfg->push_notification_allowed = is_allowed;
}
int linphone_proxy_config_get_unread_chat_message_count (const LinphoneProxyConfig *cfg) {
return L_GET_CPP_PTR_FROM_C_OBJECT(cfg->lc)->getUnreadChatMessageCount(
LinphonePrivate::IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(cfg->identity_address))
);
}
......@@ -130,6 +130,31 @@ LINPHONE_PUBLIC LinphoneMagicSearch *linphone_core_create_magic_search(LinphoneC
*/
LINPHONE_PUBLIC void linphone_core_check_for_update(LinphoneCore *lc, const char *current_version);
/**
* Return the global unread chat message count.
* @param[in] lc #LinphoneCore object.
* @return The global unread chat message count.
*/
LINPHONE_PUBLIC int linphone_core_get_unread_chat_message_count (const LinphoneCore *lc);
/**
* Return the unread chat message count for a given local address.
* @param[in] lc #LinphoneCore object.
* @param[in] address #LinphoneAddress object.
* @return The unread chat message count.
*/
LINPHONE_PUBLIC int linphone_core_get_unread_chat_message_count_from_local (
const LinphoneCore *lc,
const LinphoneAddress *address
);
/**
* Return the unread chat message count for all active local address. (Primary contact + proxy configs.)
* @param[in] lc #LinphoneCore object.
* @return The unread chat message count.
*/
LINPHONE_PUBLIC int linphone_core_get_unread_chat_message_count_from_active_locals (const LinphoneCore *lc);
/**
* @}
*/
......
......@@ -632,6 +632,13 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_push_notification_allowed(Linphon
*/
LINPHONE_PUBLIC bool_t linphone_proxy_config_is_push_notification_allowed(const LinphoneProxyConfig *cfg);
/**
* Return the unread chat message count for a given proxy config.
* @param[in] cfg #LinphoneProxyConfig object.
* @return The unread chat message count.
*/
LINPHONE_PUBLIC int linphone_proxy_config_get_unread_chat_message_count (const LinphoneProxyConfig *cfg);
/**
* @}
*/
......
......@@ -38,7 +38,7 @@ public:
IdentityAddress (const IdentityAddress &other);
~IdentityAddress () = default;
IdentityAddress* clone () const override {
IdentityAddress *clone () const override {
return new IdentityAddress(*this);
}
......@@ -78,4 +78,15 @@ inline std::ostream &operator<< (std::ostream &os, const IdentityAddress &identi
LINPHONE_END_NAMESPACE
// Add map key support.
namespace std {
template<>
struct hash<LinphonePrivate::IdentityAddress> {
std::size_t operator() (const LinphonePrivate::IdentityAddress &identityAddress) const {
if (!identityAddress.isValid()) return std::size_t(-1);
return hash<string>()(identityAddress.asString());
}
};
}
#endif // ifndef _L_IDENTITY_ADDRESS_H_
......@@ -34,7 +34,7 @@ public:
ChatRoomId (const IdentityAddress &peerAddress, const IdentityAddress &localAddress);
ChatRoomId (const ChatRoomId &other);
ChatRoomId* clone () const override {
ChatRoomId *clone () const override {
return new ChatRoomId(*this);
}
......@@ -66,6 +66,7 @@ namespace std {
template<>
struct hash<LinphonePrivate::ChatRoomId> {
std::size_t operator() (const LinphonePrivate::ChatRoomId &chatRoomId) const {
if (!chatRoomId.isValid()) return std::size_t(-1);
return hash<string>()(chatRoomId.getPeerAddress().asString()) ^
(hash<string>()(chatRoomId.getLocalAddress().asString()) << 1);
}
......
......@@ -57,9 +57,10 @@ public:
void insert (const Key &key, const Value &value) {
auto it = mKeyToPair.find(key);
if (it != mKeyToPair.end())
if (it != mKeyToPair.end()) {
mKeys.erase(it->second.first);
else if (int(mKeyToPair.size()) == mCapacity) {
mKeyToPair.erase(it);
} else if (int(mKeyToPair.size()) == mCapacity) {
Key lastKey = mKeys.back();
mKeys.pop_back();
mKeyToPair.erase(lastKey);
......@@ -71,9 +72,10 @@ public:
void insert (const Key &key, Value &&value) {
auto it = mKeyToPair.find(key);
if (it != mKeyToPair.end())
if (it != mKeyToPair.end()) {
mKeys.erase(it->second.first);
else if (int(mKeyToPair.size()) == mCapacity) {
mKeyToPair.erase(it);
} else if (int(mKeyToPair.size()) == mCapacity) {
Key lastKey = mKeys.back();
mKeys.pop_back();
mKeyToPair.erase(lastKey);
......
......@@ -20,10 +20,9 @@
#include <mediastreamer2/mscommon.h>
#include <xercesc/util/PlatformUtils.hpp>
//#include "linphone/utils/general.h"
#include "address/address-p.h"
#include "call/call.h"
#include "chat/chat-room/chat-room.h"
#include "conference/handlers/local-conference-list-event-handler.h"
#include "conference/handlers/remote-conference-list-event-handler.h"
#include "core/core-listener.h"
......@@ -177,12 +176,52 @@ LinphoneCore *Core::getCCore () const {
// Paths.
// -----------------------------------------------------------------------------
string Core::getDataPath() const {
string Core::getDataPath () const {
return Paths::getPath(Paths::Data, static_cast<PlatformHelpers *>(L_GET_C_BACK_PTR(this)->platform_helper));
}
string Core::getConfigPath() const {
string Core::getConfigPath () const {
return Paths::getPath(Paths::Config, static_cast<PlatformHelpers *>(L_GET_C_BACK_PTR(this)->platform_helper));
}
// -----------------------------------------------------------------------------
// Misc.
// -----------------------------------------------------------------------------
int Core::getUnreadChatMessageCount () const {
L_D();
return d->mainDb->getUnreadChatMessageCount();
}
int Core::getUnreadChatMessageCount (const IdentityAddress &localAddress) const {
L_D();
int count = 0;
for (const auto &chatRoom : d->chatRooms)
if (chatRoom->getLocalAddress() == localAddress)
count += chatRoom->getUnreadChatMessageCount();
return count;
}
int Core::getUnreadChatMessageCountFromActiveLocals () const {
L_D();
set<IdentityAddress> localAddresses;
{
LinphoneAddress *address = linphone_core_get_primary_contact_parsed(getCCore());
localAddresses.insert(*L_GET_CPP_PTR_FROM_C_OBJECT(address));
linphone_address_unref(address);
}
for (const bctbx_list_t *it = linphone_core_get_proxy_config_list(getCCore()); it; it = bctbx_list_next(it))
localAddresses.insert(*L_GET_CPP_PTR_FROM_C_OBJECT(static_cast<LinphoneProxyConfig *>(it->data)->identity_address));
int count = 0;
for (const auto &chatRoom : d->chatRooms) {
auto it = localAddresses.find(chatRoom->getLocalAddress());
if (it != localAddresses.end())
count += chatRoom->getUnreadChatMessageCount();
}
return count;
}
LINPHONE_END_NAMESPACE
......@@ -131,8 +131,16 @@ public:
// Paths.
// ---------------------------------------------------------------------------
std::string getDataPath() const;
std::string getConfigPath() const;
std::string getDataPath () const;
std::string getConfigPath () const;
// ---------------------------------------------------------------------------
// Misc.
// ---------------------------------------------------------------------------
int getUnreadChatMessageCount () const;
int getUnreadChatMessageCount (const IdentityAddress &localAddress) const;
int getUnreadChatMessageCountFromActiveLocals () const;
private:
Core ();
......
......@@ -764,11 +764,18 @@ long long MainDbPrivate::insertConferenceChatMessageEvent (const shared_ptr<Even
for (const Content *content : chatMessage->getContents())
insertContent(eventId, *content);
for (const auto &participant : chatMessage->getChatRoom()->getParticipants()) {
shared_ptr<AbstractChatRoom> chatRoom(chatMessage->getChatRoom());
for (const auto &participant : chatRoom->getParticipants()) {
const long long &participantSipAddressId = selectSipAddressId(participant->getAddress().asString());
insertChatMessageParticipant(eventId, participantSipAddressId, state, chatMessage->getTime());
}
if (chatMessage->getState() != ChatMessage::State::Displayed) {
int *count = unreadChatMessageCountCache[chatRoom->getChatRoomId()];
if (count)
++*count;
}
return eventId;
}
......@@ -779,6 +786,18 @@ void MainDbPrivate::updateConferenceChatMessageEvent (const shared_ptr<EventLog>
MainDbKeyPrivate *dEventKey = static_cast<MainDbKey &>(dEventLog->dbKey).getPrivate();
const long long &eventId = dEventKey->storageId;
shared_ptr<AbstractChatRoom> chatRoom(chatMessage->getChatRoom());
if (chatMessage->getState() == ChatMessage::State::Displayed) {
int *count = unreadChatMessageCountCache[chatRoom->getChatRoomId()];
if (count) {
int state;
*dbSession.getBackendSession() << "SELECT state FROM conference_chat_message_event WHERE event_id = :eventId",
soci::into(state), soci::use(eventId);
if (state != int(ChatMessage::State::Displayed))
--*count;
}
}
const int &state = int(chatMessage->getState());
const string &imdnMessageId = chatMessage->getImdnMessageId();
*dbSession.getBackendSession() << "UPDATE conference_chat_message_event SET state = :state, imdn_message_id = :imdnMessageId"
......@@ -789,12 +808,12 @@ void MainDbPrivate::updateConferenceChatMessageEvent (const shared_ptr<EventLog>
for (const auto &content : chatMessage->getContents())
insertContent(eventId, *content);
if ((chatMessage->getDirection() == ChatMessage::Direction::Outgoing)
&& ((chatMessage->getState() == ChatMessage::State::Delivered) || (chatMessage->getState() == ChatMessage::State::NotDelivered))
) {
for (const auto &participant : chatMessage->getChatRoom()->getParticipants())
if (
chatMessage->getDirection() == ChatMessage::Direction::Outgoing &&
((chatMessage->getState() == ChatMessage::State::Delivered) || (chatMessage->getState() == ChatMessage::State::NotDelivered))
)
for (const auto &participant : chatRoom->getParticipants())
setChatMessageParticipantState(eventLog, participant->getAddress(), chatMessage->getState(), std::time(nullptr));
}
}
long long MainDbPrivate::insertConferenceNotifiedEvent (const shared_ptr<EventLog> &eventLog, long long *chatRoomId) {
......@@ -939,7 +958,6 @@ void MainDbPrivate::setChatMessageParticipantState (
soci::use(stateInt), soci::use(stateChangeTm), soci::use(eventId), soci::use(participantSipAddressId);
}
// -----------------------------------------------------------------------------
// Cache API.
// -----------------------------------------------------------------------------
......@@ -1782,16 +1800,22 @@ bool MainDb::deleteEvent (const shared_ptr<const EventLog> &eventLog) {
MainDb &mainDb = *core->getPrivate()->mainDb.get();
return L_DB_TRANSACTION_C(&mainDb) {
soci::session *session = mainDb.getPrivate()->dbSession.getBackendSession();
MainDbPrivate *const d = mainDb.getPrivate();
soci::session *session = d->dbSession.getBackendSession();
*session << "DELETE FROM event WHERE id = :id", soci::use(dEventKey->storageId);
tr.commit();
dEventLog->dbKey = MainDbEventKey();
if (eventLog->getType() == EventLog::Type::ConferenceChatMessage)
static_pointer_cast<const ConferenceChatMessageEvent>(
eventLog
)->getChatMessage()->getPrivate()->dbKey = MainDbChatMessageKey();
if (eventLog->getType() == EventLog::Type::ConferenceChatMessage) {
shared_ptr<ChatMessage> chatMessage(static_pointer_cast<const ConferenceChatMessageEvent>(eventLog)->getChatMessage());
if (chatMessage->getState() != ChatMessage::State::Displayed) {
int *count = d->unreadChatMessageCountCache[chatMessage->getChatRoom()->getChatRoomId()];
if (count)
--*count;
}
chatMessage->getPrivate()->dbKey = MainDbChatMessageKey();
}
return true;
};
......@@ -1962,6 +1986,7 @@ void MainDb::markChatMessagesAsRead (const ChatRoomId &chatRoomId) const {
*d->dbSession.getBackendSession() << query, soci::use(dbChatRoomId);
tr.commit();
d->unreadChatMessageCountCache.insert(chatRoomId, 0);
};
}
......@@ -2342,6 +2367,9 @@ void MainDb::cleanHistory (const ChatRoomId &chatRoomId, FilterMask mask) {
*d->dbSession.getBackendSession() << "DELETE FROM event WHERE id IN (" + query + ")", soci::use(dbChatRoomId);
tr.commit();
if (!mask || (mask & ConferenceChatMessageFilter))
d->unreadChatMessageCountCache.insert(chatRoomId, 0);
};
}
......@@ -2512,6 +2540,7 @@ void MainDb::deleteChatRoom (const ChatRoomId &chatRoomId) {
*d->dbSession.getBackendSession() << "DELETE FROM chat_room WHERE id = :chatRoomId", soci::use(dbChatRoomId);
tr.commit();
d->unreadChatMessageCountCache.insert(chatRoomId, 0);
};
}
......
......@@ -99,6 +99,7 @@ public:
int getChatMessageCount (const ChatRoomId &chatRoomId = ChatRoomId()) const;
int getUnreadChatMessageCount (const ChatRoomId &chatRoomId = ChatRoomId()) const;
void markChatMessagesAsRead (const ChatRoomId &chatRoomId) const;
std::list<std::shared_ptr<ChatMessage>> getUnreadChatMessages (const ChatRoomId &chatRoomId) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment