From e9d7b36cc5d340233bba0bc9d3baa100d06c11e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Wed, 18 Apr 2018 10:25:17 -0400 Subject: [PATCH] conversationmodel: add the ability to remove one interaction from history Change-Id: Ie2a6a2ca34b04fb0ae6f5b751ee2e11baf3233c2 --- src/api/conversationmodel.h | 19 ++++++++++-- src/authority/databasehelper.cpp | 8 +++++ src/authority/databasehelper.h | 10 ++++++ src/conversationmodel.cpp | 25 +++++++++++++++ test/conversationmodeltester.cpp | 53 ++++++++++++++++++++++++++++++++ test/conversationmodeltester.h | 5 +++ 6 files changed, 117 insertions(+), 3 deletions(-) diff --git a/src/api/conversationmodel.h b/src/api/conversationmodel.h index fb3bfe27..7a96dcf1 100644 --- a/src/api/conversationmodel.h +++ b/src/api/conversationmodel.h @@ -160,7 +160,13 @@ public: /** * clear all history */ - void clearAllHistory(); + void clearAllHistory(); + /** + * Clear one interaction from the history + * @param convId + * @param interactionId + */ + void clearInteractionFromConversation(const std::string& convId, const uint64_t& interactionId); /** * delete obsolete history from the database * @param days, number of days from today. Below this date, interactions will be deleted @@ -191,12 +197,19 @@ Q_SIGNALS: /** * Emitted when an interaction got a new status * @param convUid conversation which owns the interaction - * @param msgId + * @param interactionId * @param msg */ void interactionStatusUpdated(const std::string& convUid, - uint64_t msgId, + uint64_t interactionId, const api::interaction::Info& msg) const; + /** + * Emitted when an interaction got removed from the conversation + * @param convUid conversation which owns the interaction + * @param interactionId + */ + void interactionRemoved(const std::string& convUid, + uint64_t interactionId) const; /** * Emitted when user clear the history of a conversation * @param uid diff --git a/src/authority/databasehelper.cpp b/src/authority/databasehelper.cpp index 48f53a47..7e89ee9d 100644 --- a/src/authority/databasehelper.cpp +++ b/src/authority/databasehelper.cpp @@ -334,6 +334,14 @@ void clearHistory(Database& db, db.deleteFrom("interactions", "conversation_id=:id", {{":id", conversationId}}); } +void clearInteractionFromConversation(Database& db, + const std::string& conversationId, + const uint64_t& interactionId) +{ + db.deleteFrom("interactions", "conversation_id=:conv_id AND id=:int_id", + {{":conv_id", conversationId}, {":int_id", std::to_string(interactionId)}}); +} + void clearAllHistoryFor(Database& db, const std::string& accountUri) { auto accountId = db.select("id", "profiles","uri=:uri", {{":uri", accountUri}}).payloads; diff --git a/src/authority/databasehelper.h b/src/authority/databasehelper.h index 744cb81c..fff6d728 100644 --- a/src/authority/databasehelper.h +++ b/src/authority/databasehelper.h @@ -200,6 +200,16 @@ void updateInteractionStatus(Database& db, unsigned int id, void clearHistory(Database& db, const std::string& conversationId); +/** + * Clear interaction from history + * @param db + * @param conversationId + * @param interactionId + */ +void clearInteractionFromConversation(Database& db, + const std::string& conversationId, + const uint64_t& interactionId); + /** * Clear all history stored in the database for the account uri * @param db diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp index 06ade4e0..f0802aef 100644 --- a/src/conversationmodel.cpp +++ b/src/conversationmodel.cpp @@ -636,6 +636,7 @@ ConversationModel::sendMessage(const std::string& uid, const std::string& body) pimpl_->sortConversations(); // The order has changed, informs the client to redraw the list emit modelSorted(); + } void @@ -716,6 +717,30 @@ ConversationModel::clearHistory(const std::string& uid) emit conversationCleared(uid); } +void +ConversationModel::clearInteractionFromConversation(const std::string& convId, const uint64_t& interactionId) +{ + auto conversationIdx = pimpl_->indexOf(convId); + if (conversationIdx == -1) + return; + + auto erased_keys = 0; + { + std::lock_guard<std::mutex> lk(pimpl_->interactionsLocks[convId]); + try + { + auto& conversation = pimpl_->conversations.at(conversationIdx); + database::clearInteractionFromConversation(pimpl_->db, convId, interactionId); + + erased_keys = conversation.interactions.erase(interactionId); + } catch (const std::out_of_range& e) { + qDebug() << "can't clear interaction from conversation: " << e.what(); + } + } + if (erased_keys > 0) + emit interactionRemoved(convId, interactionId); +} + void ConversationModel::clearAllHistory() { diff --git a/test/conversationmodeltester.cpp b/test/conversationmodeltester.cpp index 10ca9051..a66240ef 100644 --- a/test/conversationmodeltester.cpp +++ b/test/conversationmodeltester.cpp @@ -289,6 +289,59 @@ ConversationModelTester::testSendMessageAndClearHistory() CPPUNIT_ASSERT(conversationExists); } +void +ConversationModelTester::testSendMessagesAndClearInteraction() +{ + accInfo_.conversationModel->setFilter(""); + auto conversations = accInfo_.conversationModel->allFilteredConversations(); + CPPUNIT_ASSERT(conversations.size() != 0); + auto firstConversation = accInfo_.conversationModel->filteredConversation(0); + auto firstConversationUid = firstConversation.uid; + + // HACK reinit the conversation here (without these line, Hello World! will not be in interactions) + // FIXME + accInfo_.conversationModel->clearHistory(firstConversationUid); + firstConversation = accInfo_.conversationModel->filteredConversation(0); + + // Send 3 messages (will be added to conversation.interactions) + int baseInteractionsSize = firstConversation.interactions.size(); + accInfo_.conversationModel->sendMessage(firstConversationUid, "Hello World!"); + accInfo_.conversationModel->sendMessage(firstConversationUid, "It's been a long time"); + accInfo_.conversationModel->sendMessage(firstConversationUid, "How have you been?"); + + conversations = accInfo_.conversationModel->allFilteredConversations(); + auto conversationExists = false; + uint64_t secondInterId = {}; + for (const auto& conversation: conversations) { + if (conversation.uid == firstConversationUid) { + conversationExists = true; + CPPUNIT_ASSERT_EQUAL((int)conversation.interactions.size(), baseInteractionsSize + 3); + auto it = conversation.interactions.begin(); + it++; + secondInterId = it->first; + break; + } + } + CPPUNIT_ASSERT(conversationExists); + + accInfo_.conversationModel->clearInteractionFromConversation(firstConversationUid, secondInterId); + auto unreadMessage = WaitForSignalHelper(*accInfo_.conversationModel, + SIGNAL(interactionRemoved(const std::string& convUid, uint64_t interactionId))).wait(1000); + conversations = accInfo_.conversationModel->allFilteredConversations(); + conversationExists = false; + for (const auto& conversation: conversations) { + if (conversation.uid == firstConversationUid) { + conversationExists = true; + // Second interaction should be removed + CPPUNIT_ASSERT_EQUAL((int)conversation.interactions.size(), baseInteractionsSize + 2); + for (const auto& interaction: conversation.interactions) + CPPUNIT_ASSERT(interaction.first != secondInterId); + break; + } + } + CPPUNIT_ASSERT(conversationExists); +} + void ConversationModelTester::testReceiveMessageAndSetRead() { diff --git a/test/conversationmodeltester.h b/test/conversationmodeltester.h index b88dc6c0..07ff662e 100644 --- a/test/conversationmodeltester.h +++ b/test/conversationmodeltester.h @@ -46,6 +46,7 @@ class ConversationModelTester : public CppUnit::TestFixture { CPPUNIT_TEST(testRmConversation); CPPUNIT_TEST(testFilterAndGetConversations); CPPUNIT_TEST(testSendMessageAndClearHistory); + CPPUNIT_TEST(testSendMessagesAndClearInteraction); CPPUNIT_TEST(testReceiveMessageAndSetRead); CPPUNIT_TEST(testPlaceCall); CPPUNIT_TEST(testCreateConference); @@ -94,6 +95,10 @@ public: * Make sure banned contacts only appear in perfect-match filter searches. */ void testFilterBannedContact(); + /** + * Send multiple messages to the first conversation and clear one interaction + */ + void testSendMessagesAndClearInteraction(); /** * Receives a message from a conversation and set this message READ */ -- GitLab