Commit 11549618 authored by Ronan's avatar Ronan

fix(ChatMessage): do not store file chat message transfer state in database

parent 843d9f4c
......@@ -159,11 +159,11 @@ public:
void storeInDb ();
void updateInDb ();
static bool isValidStateTransition (ChatMessage::State currentState, ChatMessage::State newState);
private:
ChatMessagePrivate(const std::shared_ptr<AbstractChatRoom> &cr, ChatMessage::Direction dir);
static bool validStateTransition (ChatMessage::State currentState, ChatMessage::State newState);
public:
mutable MainDbChatMessageKey dbKey;
......
......@@ -80,7 +80,7 @@ void ChatMessagePrivate::setParticipantState (const IdentityAddress &participant
unique_ptr<MainDb> &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb;
shared_ptr<EventLog> eventLog = mainDb->getEventFromKey(dbKey);
ChatMessage::State currentState = mainDb->getChatMessageParticipantState(eventLog, participantAddress);
if (!validStateTransition(currentState, newState))
if (!isValidStateTransition(currentState, newState))
return;
lInfo() << "Chat message " << this << ": moving participant '" << participantAddress.asString() << "' state to "
......@@ -139,7 +139,7 @@ void ChatMessagePrivate::setState (ChatMessage::State newState, bool force) {
if (force)
state = newState;
if (!validStateTransition(state, newState))
if (!isValidStateTransition(state, newState))
return;
lInfo() << "Chat message " << this << ": moving from " << Utils::toString(state) <<
......@@ -158,14 +158,15 @@ void ChatMessagePrivate::setState (ChatMessage::State newState, bool force) {
if (cbs && linphone_chat_message_cbs_get_msg_state_changed(cbs))
linphone_chat_message_cbs_get_msg_state_changed(cbs)(msg, (LinphoneChatMessageState)state);
if (state == ChatMessage::State::FileTransferDone && !hasFileTransferContent()) {
// We wait until the file has been downloaded to send the displayed IMDN
bool doNotStoreInDb = static_cast<ChatRoomPrivate *>(q->getChatRoom()->getPrivate())->sendDisplayNotification(q->getSharedFromThis());
// Force the state so it is stored directly in DB, but when the IMDN has successfully been delivered
setState(ChatMessage::State::Displayed, doNotStoreInDb);
} else {
if (state == ChatMessage::State::FileTransferDone) {
if (!hasFileTransferContent()) {
// We wait until the file has been downloaded to send the displayed IMDN
bool doNotStoreInDb = static_cast<ChatRoomPrivate *>(q->getChatRoom()->getPrivate())->sendDisplayNotification(q->getSharedFromThis());
// Force the state so it is stored directly in DB, but when the IMDN has successfully been delivered
setState(ChatMessage::State::Displayed, doNotStoreInDb);
}
} else if (state != ChatMessage::State::FileTransferError && state != ChatMessage::State::InProgress)
updateInDb();
}
}
belle_http_request_t *ChatMessagePrivate::getHttpRequest () const {
......@@ -835,20 +836,18 @@ void ChatMessagePrivate::updateInDb () {
// -----------------------------------------------------------------------------
bool ChatMessagePrivate::validStateTransition (ChatMessage::State currentState, ChatMessage::State newState) {
bool ChatMessagePrivate::isValidStateTransition (ChatMessage::State currentState, ChatMessage::State newState) {
if (newState == currentState)
return false;
if (
return !(
(currentState == ChatMessage::State::Displayed || currentState == ChatMessage::State::DeliveredToUser) &&
(
newState == ChatMessage::State::DeliveredToUser ||
newState == ChatMessage::State::Delivered ||
newState == ChatMessage::State::NotDelivered
)
)
return false;
return true;
);
}
// -----------------------------------------------------------------------------
......@@ -857,8 +856,7 @@ ChatMessage::ChatMessage (const shared_ptr<AbstractChatRoom> &chatRoom, ChatMess
Object(*new ChatMessagePrivate(chatRoom, direction)), CoreAccessor(chatRoom->getCore()) {
}
ChatMessage::ChatMessage (ChatMessagePrivate &p) : Object(p), CoreAccessor(p.getPublic()->getChatRoom()->getCore()) {
}
ChatMessage::ChatMessage (ChatMessagePrivate &p) : Object(p), CoreAccessor(p.getPublic()->getChatRoom()->getCore()) {}
ChatMessage::~ChatMessage () {
L_D();
......
......@@ -786,34 +786,50 @@ void MainDbPrivate::updateConferenceChatMessageEvent (const shared_ptr<EventLog>
MainDbKeyPrivate *dEventKey = static_cast<MainDbKey &>(dEventLog->dbKey).getPrivate();
const long long &eventId = dEventKey->storageId;
const bool isOutgoing = chatMessage->getDirection() == ChatMessage::Direction::Outgoing;
// 1. Get current chat message state and database state.
const ChatMessage::State state = chatMessage->getState();
ChatMessage::State dbState;
{
int intState;
*dbSession.getBackendSession() << "SELECT state FROM conference_chat_message_event WHERE event_id = :eventId",
soci::into(intState), soci::use(eventId);
dbState = ChatMessage::State(intState);
}
// 2. Update unread chat message count if necessary.
const bool isOutgoing = chatMessage->getDirection() == ChatMessage::Direction::Outgoing;
shared_ptr<AbstractChatRoom> chatRoom(chatMessage->getChatRoom());
if (!isOutgoing && chatMessage->getState() == ChatMessage::State::Displayed) {
if (!isOutgoing && state == 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)) {
L_ASSERT(*count > 0);
--*count;
}
if (count && dbState != ChatMessage::State::Displayed) {
L_ASSERT(*count > 0);
--*count;
}
}
const string &imdnMessageId = chatMessage->getImdnMessageId();
int stateInt = int(state);
*dbSession.getBackendSession() << "UPDATE conference_chat_message_event SET state = :state, imdn_message_id = :imdnMessageId"
" WHERE event_id = :eventId",
soci::use(stateInt), soci::use(imdnMessageId), soci::use(eventId);
// 3. Update chat message event.
{
const string &imdnMessageId = chatMessage->getImdnMessageId();
// Do not store transfer state.
const int stateInt = int(
state == ChatMessage::State::InProgress ||
state == ChatMessage::State::FileTransferDone ||
state == ChatMessage::State::FileTransferError
? dbState
: state
);
*dbSession.getBackendSession() << "UPDATE conference_chat_message_event SET state = :state, imdn_message_id = :imdnMessageId"
" WHERE event_id = :eventId",
soci::use(stateInt), soci::use(imdnMessageId), soci::use(eventId);
}
// 4. Update contents.
deleteContents(eventId);
for (const auto &content : chatMessage->getContents())
insertContent(eventId, *content);
// 5. Update participants.
if (isOutgoing && (state == ChatMessage::State::Delivered || state == ChatMessage::State::NotDelivered))
for (const auto &participant : chatRoom->getParticipants())
setChatMessageParticipantState(eventLog, participant->getAddress(), state, std::time(nullptr));
......
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