From 03e8aabf1754f5061f207d2c9c082ba6199db0e5 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 2 Mar 2018 12:00:54 +0100 Subject: Visualize that a folder has new mails. We listen for new mail notifications, and highlight the folder accordingly. --- framework/src/domain/folderlistmodel.cpp | 41 ++++++++++++++++++++++++++++++++ framework/src/domain/folderlistmodel.h | 8 ++++++- framework/src/sinkfabric.cpp | 5 ++++ 3 files changed, 53 insertions(+), 1 deletion(-) (limited to 'framework/src') diff --git a/framework/src/domain/folderlistmodel.cpp b/framework/src/domain/folderlistmodel.cpp index f929b01e..6555abbf 100644 --- a/framework/src/domain/folderlistmodel.cpp +++ b/framework/src/domain/folderlistmodel.cpp @@ -21,6 +21,8 @@ #include "folderlistmodel.h" #include #include +#include +#include #include using namespace Sink; @@ -59,6 +61,7 @@ QHash< int, QByteArray > FolderListModel::roleNames() const roles[DomainObject] = "domainObject"; roles[Status] = "status"; roles[Trash] = "trash"; + roles[HasNewData] = "hasNewData"; return roles; } @@ -92,14 +95,46 @@ QVariant FolderListModel::data(const QModelIndex &idx, int role) const return folder->getSpecialPurpose().contains(Sink::ApplicationDomain::SpecialPurpose::Mail::trash); } return false; + case HasNewData: + return mHasNewData.contains(folder->identifier()); } return QSortFilterProxyModel::data(idx, role); } +static QModelIndex findRecursive(QAbstractItemModel *model, const QModelIndex &parent, int role, const QVariant &value) +{ + for (auto row = 0; row < model->rowCount(parent); row++) { + const auto idx = model->index(row, 0, parent); + if (model->data(idx, role) == value) { + return idx; + } + auto result = findRecursive(model, idx, role, value); + if (result.isValid()) { + return result; + } + } + return {}; +} + void FolderListModel::runQuery(const Query &query) { mModel = Store::loadModel(query); setSourceModel(mModel.data()); + + Sink::Query resourceQuery; + resourceQuery.setFilter(query.getResourceFilter()); + mNotifier.reset(new Sink::Notifier{resourceQuery}); + mNotifier->registerHandler([&](const Sink::Notification ¬ification) { + if (notification.type == Sink::Notification::Info && notification.code == ApplicationDomain::NewContentAvailable) { + if (!notification.entities.isEmpty()) { + mHasNewData.insert(notification.entities.first()); + auto idx = findRecursive(this, {}, Id, QVariant::fromValue(notification.entities.first())); + if (idx.isValid()) { + emit dataChanged(idx, idx); + } + } + } + }); } void FolderListModel::setAccountId(const QVariant &accountId) @@ -164,6 +199,12 @@ bool FolderListModel::acceptRow(int sourceRow, const QModelIndex &sourceParent) return enabled; } +void FolderListModel::fetchMore(const QModelIndex &parent) +{ + mHasNewData.remove(parent.data(Id).toByteArray()); + QAbstractItemModel::fetchMore(parent); +} + void FolderListModel::setFolderId(const QVariant &folderId) { const auto folder = folderId.toString().toUtf8(); diff --git a/framework/src/domain/folderlistmodel.h b/framework/src/domain/folderlistmodel.h index 738cf4a0..d3bef397 100644 --- a/framework/src/domain/folderlistmodel.h +++ b/framework/src/domain/folderlistmodel.h @@ -22,6 +22,8 @@ #include #include +#include +#include namespace Sink { class Query; @@ -54,7 +56,8 @@ public: Id, DomainObject, Status, - Trash + Trash, + HasNewData }; Q_ENUMS(Roles) @@ -68,8 +71,11 @@ public: protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const Q_DECL_OVERRIDE; bool acceptRow(int sourceRow, const QModelIndex &sourceParent) const Q_DECL_OVERRIDE; + void fetchMore(const QModelIndex &left) Q_DECL_OVERRIDE; private: void runQuery(const Sink::Query &query); QSharedPointer mModel; + QSet mHasNewData; + QScopedPointer mNotifier; }; diff --git a/framework/src/sinkfabric.cpp b/framework/src/sinkfabric.cpp index 8492f272..916cc8fa 100644 --- a/framework/src/sinkfabric.cpp +++ b/framework/src/sinkfabric.cpp @@ -203,6 +203,11 @@ public: if (notification.code == Sink::ApplicationDomain::TransmissionSuccess) { message["type"] = "info"; message["message"] = QObject::tr("A message has been sent."); + } else if (notification.code == Sink::ApplicationDomain::NewContentAvailable) { + message["type"] = "info"; + if (!notification.entities.isEmpty()) { + message["folderId"] = notification.entities.first(); + } } else { return; } -- cgit v1.2.3