From 26431f41e23324092eba3de8328e0643f0a7d75f Mon Sep 17 00:00:00 2001 From: Alek Rudnik <54846206+alekrudnik@users.noreply.github.com> Date: Mon, 13 Jul 2020 14:39:36 +0200 Subject: [PATCH] [EGD-2810] Added sms option to mark conversation as read/unread (#522) * [EGD-2810] SMS - Added option to mark conversation as read/unread * [EGD-2810] PR fixes --- changelog.md | 7 ++++ .../ApplicationMessages.cpp | 18 ++++++++++ .../ApplicationMessages.hpp | 2 ++ .../windows/OptionsWindow.cpp | 36 ++++++++++++------- .../windows/ThreadViewWindow.cpp | 5 +-- module-db/CMakeLists.txt | 1 + module-db/Interface/ThreadRecord.cpp | 28 +++++++++------ module-db/Interface/ThreadRecord.hpp | 26 +++++--------- .../queries/sms/QuerySmsThreadMarkAsRead.cpp | 25 +++++++++++++ .../queries/sms/QuerySmsThreadMarkAsRead.hpp | 34 ++++++++++++++++++ module-db/tests/ThreadRecord_tests.cpp | 29 +++++++++++++++ 11 files changed, 169 insertions(+), 42 deletions(-) create mode 100644 module-db/queries/sms/QuerySmsThreadMarkAsRead.cpp create mode 100644 module-db/queries/sms/QuerySmsThreadMarkAsRead.hpp diff --git a/changelog.md b/changelog.md index c3b446fd6..f5cd877f7 100644 --- a/changelog.md +++ b/changelog.md @@ -2,9 +2,16 @@ ## Current version +### Added +* `[sms]` Added option to mark conversation as read/unread + +### Changed + ### Fixed * `[phonebook]` Fix wrong text label for back action. +### Other + ## [0.28.1] - 2020-07-10 ### Added diff --git a/module-apps/application-messages/ApplicationMessages.cpp b/module-apps/application-messages/ApplicationMessages.cpp index faa53c1d8..6d01bd24e 100644 --- a/module-apps/application-messages/ApplicationMessages.cpp +++ b/module-apps/application-messages/ApplicationMessages.cpp @@ -119,6 +119,24 @@ namespace app void ApplicationMessages::destroyUserInterface() {} + bool ApplicationMessages::markSmsThreadAsRead(const uint32_t id) + { + using namespace db::query::smsthread; + LOG_DEBUG("markSmsThreadAsRead"); + DBServiceAPI::GetQuery( + this, db::Interface::Name::SMSThread, std::make_unique(id, MarkAsRead::Read::True)); + return true; + } + + bool ApplicationMessages::markSmsThreadAsUnread(const uint32_t id) + { + using namespace db::query::smsthread; + LOG_DEBUG("markSmsThreadAsRead"); + DBServiceAPI::GetQuery( + this, db::Interface::Name::SMSThread, std::make_unique(id, MarkAsRead::Read::False)); + return true; + } + bool ApplicationMessages::removeSMS_thread(const ThreadRecord *record) { if (record == nullptr) { diff --git a/module-apps/application-messages/ApplicationMessages.hpp b/module-apps/application-messages/ApplicationMessages.hpp index ae40d8919..773115ce6 100644 --- a/module-apps/application-messages/ApplicationMessages.hpp +++ b/module-apps/application-messages/ApplicationMessages.hpp @@ -54,6 +54,8 @@ namespace app bool removeSMS(const SMSRecord &record); bool removeSMS_thread(const ThreadRecord *record); + bool markSmsThreadAsRead(const uint32_t id); + bool markSmsThreadAsUnread(const uint32_t id); /// show dialog with big search icon and text which was used for query bool searchEmpty(const std::string &query = ""); bool showSearchResults(const UTF8 &title, const UTF8 &search_text); diff --git a/module-apps/application-messages/windows/OptionsWindow.cpp b/module-apps/application-messages/windows/OptionsWindow.cpp index b3685ca68..7f0138eeb 100644 --- a/module-apps/application-messages/windows/OptionsWindow.cpp +++ b/module-apps/application-messages/windows/OptionsWindow.cpp @@ -7,24 +7,34 @@ std::list threadWindowOptions(app::ApplicationMessages *app, const ThreadRecord *record) { - + assert(record != nullptr); ContactRecord contact = record ? DBServiceAPI::ContactGetByID(app, record->contactID)->front() : ContactRecord(); std::list options; - options.push_back(gui::options::call(app, app::CallOperation::ExecuteCall, contact)); + options.emplace_back(gui::options::call(app, app::CallOperation::ExecuteCall, contact)); auto contactOperation = contact.contactType == ContactType::TEMPORARY ? app::ContactOperation::Add : app::ContactOperation::Details; - options.push_back(gui::options::contact(app, contactOperation, contact)); - // TODO - // last sms, all sms? what author had in mind? - options.push_back(gui::Option{"" + utils::localize.get("sms_mark_unread"), [=](gui::Item &item) { - LOG_ERROR("TODO: need implementation"); - return true; - }}); - options.push_back(gui::Option{utils::localize.get("sms_delete_conversation"), [=](gui::Item &item) { - LOG_INFO("Removing sms thread!"); - return app->removeSMS_thread(record); - }}); + options.emplace_back(gui::options::contact(app, contactOperation, contact)); + + if (record->isUnread()) { + options.emplace_back(gui::Option{utils::localize.get("sms_mark_read"), [=](gui::Item &item) { + app->markSmsThreadAsRead(record->ID); + app->returnToPreviousWindow(); + return true; + }}); + } + else { + options.emplace_back(gui::Option{utils::localize.get("sms_mark_unread"), [=](gui::Item &item) { + app->markSmsThreadAsUnread(record->ID); + app->returnToPreviousWindow(); + return true; + }}); + } + + options.emplace_back(gui::Option{utils::localize.get("sms_delete_conversation"), [=](gui::Item &item) { + LOG_INFO("Removing sms thread!"); + return app->removeSMS_thread(record); + }}); // TODO // shouldn't this be in show contact details actually? it would be much easier too diff --git a/module-apps/application-messages/windows/ThreadViewWindow.cpp b/module-apps/application-messages/windows/ThreadViewWindow.cpp index 87498f624..0f979f4ac 100644 --- a/module-apps/application-messages/windows/ThreadViewWindow.cpp +++ b/module-apps/application-messages/windows/ThreadViewWindow.cpp @@ -148,8 +148,9 @@ namespace gui SMS.dbsize = threadDetails->msgCount; if (threadDetails != nullptr && threadDetails->isUnread()) { - threadDetails->unreadMsgCount = 0; - DBServiceAPI::ThreadUpdate(application, *threadDetails); + auto app = dynamic_cast(application); + assert(app != nullptr); + app->markSmsThreadAsRead(threadDetails->ID); } LOG_DEBUG("start: %d end: %d db: %d", SMS.start, SMS.end, SMS.dbsize); diff --git a/module-db/CMakeLists.txt b/module-db/CMakeLists.txt index fd275f803..7d2498542 100644 --- a/module-db/CMakeLists.txt +++ b/module-db/CMakeLists.txt @@ -48,6 +48,7 @@ set(SOURCES queries/RecordQuery.cpp queries/sms/QuerySMSSearch.cpp + queries/sms/QuerySmsThreadMarkAsRead.cpp queries/calllog/QueryCalllogSetAllRead.cpp queries/notifications/QueryNotificationsGet.cpp queries/notifications/QueryNotificationsIncrement.cpp diff --git a/module-db/Interface/ThreadRecord.cpp b/module-db/Interface/ThreadRecord.cpp index 1303feda8..b8abcbace 100644 --- a/module-db/Interface/ThreadRecord.cpp +++ b/module-db/Interface/ThreadRecord.cpp @@ -1,13 +1,3 @@ - -/* - * @file ThreadRecord.cpp - * @author Mateusz Piesta (mateusz.piesta@mudita.com) - * @date 29.05.19 - * @brief - * @copyright Copyright (C) 2019 mudita.com - * @details - */ - #include "ThreadRecord.hpp" #include "SMSRecord.hpp" #include "queries/sms/QuerySMSSearch.hpp" @@ -138,6 +128,9 @@ std::unique_ptr ThreadRecordInterface::runQuery(const db::Query if (const auto local_query = dynamic_cast(query)) { return runQueryImpl(local_query); } + if (const auto local_query = dynamic_cast(query)) { + return runQueryImpl(local_query); + } return nullptr; } @@ -146,3 +139,18 @@ std::unique_ptr ThreadRecordInterface::runQueryImpl( auto db_result = smsDB->threads.getBySMSQuery(query->text, query->starting_postion, query->depth); return std::make_unique(db_result.first, db_result.second); } + +std::unique_ptr ThreadRecordInterface::runQueryImpl( + const db::query::smsthread::MarkAsRead *query) +{ + using namespace db::query::smsthread; + auto ret = false; + + auto record = GetByID(query->id); + if (record.isValid()) { + LOG_FATAL("query-read %d", static_cast(query->read)); + record.unreadMsgCount = query->read == MarkAsRead::Read::True ? 0 : 1; + ret = Update(record); + } + return std::make_unique(ret); +} diff --git a/module-db/Interface/ThreadRecord.hpp b/module-db/Interface/ThreadRecord.hpp index 5de3a9cdc..ad31dff97 100644 --- a/module-db/Interface/ThreadRecord.hpp +++ b/module-db/Interface/ThreadRecord.hpp @@ -1,22 +1,15 @@ - -/* - * @file ThreadRecord.hpp - * @author Mateusz Piesta (mateusz.piesta@mudita.com) - * @date 29.05.19 - * @brief - * @copyright Copyright (C) 2019 mudita.com - * @details - */ #pragma once #include "Record.hpp" -#include -#include "utf8/UTF8.hpp" -#include "../Databases/SmsDB.hpp" -#include "../Databases/ContactsDB.hpp" -#include "../Common/Common.hpp" -#include "../queries/sms/QuerySMSSearch.hpp" +#include "module-db/Databases/SmsDB.hpp" +#include "module-db/Databases/ContactsDB.hpp" +#include "module-db/Common/Common.hpp" +#include "module-db/queries/sms/QuerySMSSearch.hpp" +#include "module-db/queries/sms/QuerySmsThreadMarkAsRead.hpp" +#include + +#include struct ThreadRecord : Record { uint32_t date = 0; @@ -64,8 +57,6 @@ class ThreadRecordInterface : public RecordInterface> GetLimitOffset(uint32_t offset, uint32_t limit) override final; std::unique_ptr> GetLimitOffsetByField(uint32_t offset, @@ -83,4 +74,5 @@ class ThreadRecordInterface : public RecordInterface runQueryImpl(const db::query::SMSSearch *query); + std::unique_ptr runQueryImpl(const db::query::smsthread::MarkAsRead *query); }; diff --git a/module-db/queries/sms/QuerySmsThreadMarkAsRead.cpp b/module-db/queries/sms/QuerySmsThreadMarkAsRead.cpp new file mode 100644 index 000000000..029271c1f --- /dev/null +++ b/module-db/queries/sms/QuerySmsThreadMarkAsRead.cpp @@ -0,0 +1,25 @@ +#include "QuerySmsThreadMarkAsRead.hpp" + +namespace db::query::smsthread +{ + MarkAsRead::MarkAsRead(uint32_t id, Read read) : Query(Query::Type::Update), read(read), id(id) + {} + + auto MarkAsRead::debugInfo() const -> std::string + { + return "MarkAsRead"; + } + + MarkAsReadResult::MarkAsReadResult(bool ret) : ret(ret) + {} + + auto MarkAsReadResult::getResult() const -> bool + { + return ret; + } + + auto MarkAsReadResult::debugInfo() const -> std::string + { + return "MarkAsReadResult"; + } +} // namespace db::query::smsthread diff --git a/module-db/queries/sms/QuerySmsThreadMarkAsRead.hpp b/module-db/queries/sms/QuerySmsThreadMarkAsRead.hpp new file mode 100644 index 000000000..30cfb737b --- /dev/null +++ b/module-db/queries/sms/QuerySmsThreadMarkAsRead.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +namespace db::query::smsthread +{ + class MarkAsRead : public Query + { + public: + enum class Read : bool + { + True, + False + }; + const Read read; + const uint32_t id; + MarkAsRead(uint32_t id, Read read = Read::True); + + [[nodiscard]] auto debugInfo() const -> std::string override; + }; + + class MarkAsReadResult : public QueryResult + { + bool ret; + + public: + MarkAsReadResult(bool ret); + [[nodiscard]] auto getResult() const -> bool; + + [[nodiscard]] auto debugInfo() const -> std::string override; + }; + +} // namespace db::query::smsthread diff --git a/module-db/tests/ThreadRecord_tests.cpp b/module-db/tests/ThreadRecord_tests.cpp index 86017d4a0..4c50f05b9 100644 --- a/module-db/tests/ThreadRecord_tests.cpp +++ b/module-db/tests/ThreadRecord_tests.cpp @@ -16,6 +16,7 @@ #include "Interface/ContactRecord.hpp" #include "Interface/SMSRecord.hpp" #include "Interface/ThreadRecord.hpp" +#include "queries/sms/QuerySmsThreadMarkAsRead.hpp" #include "vfs.hpp" #include @@ -119,5 +120,33 @@ TEST_CASE("Thread Record tests") REQUIRE(record.snippet == snippetTest2); } + SECTION("Mark as read / unread") + { + recordIN.unreadMsgCount = 10; + REQUIRE(threadRecordInterface1.Add(recordIN)); + auto rec = threadRecordInterface1.GetByID(3); + REQUIRE(rec.isUnread()); + + { + db::query::smsthread::MarkAsRead query{3, db::query::smsthread::MarkAsRead::Read::True}; + auto ret = threadRecordInterface1.runQuery(&query); + auto result = dynamic_cast(ret.get()); + REQUIRE(result != nullptr); + REQUIRE(result->getResult()); + rec = threadRecordInterface1.GetByID(3); + REQUIRE_FALSE(rec.isUnread()); + } + + { + db::query::smsthread::MarkAsRead query{3, db::query::smsthread::MarkAsRead::Read::False}; + auto ret = threadRecordInterface1.runQuery(&query); + auto result = dynamic_cast(ret.get()); + REQUIRE(result != nullptr); + REQUIRE(result->getResult()); + rec = threadRecordInterface1.GetByID(3); + REQUIRE(rec.isUnread()); + } + } + Database::Deinitialize(); }