diff --git a/src/miscellaneous/feedreader.cpp b/src/miscellaneous/feedreader.cpp index 9863c9823..9dca3071b 100755 --- a/src/miscellaneous/feedreader.cpp +++ b/src/miscellaneous/feedreader.cpp @@ -219,8 +219,8 @@ void FeedReader::checkServicesForAsyncOperations() { } void FeedReader::checkServicesForAsyncOperations(bool wait_for_future) { - if (m_cacheSaveFutureWatcher->future().isStarted() || m_cacheSaveFutureWatcher->future().isRunning()) { - qDebug("Previous future is still running or was already started."); + if (m_cacheSaveFutureWatcher->future().isRunning()) { + qDebug("Previous future is still running."); // If we want to wait for future synchronously, we want to make sure that diff --git a/src/services/abstract/serviceroot.h b/src/services/abstract/serviceroot.h index e17fe9ae6..7850d83f4 100755 --- a/src/services/abstract/serviceroot.h +++ b/src/services/abstract/serviceroot.h @@ -84,8 +84,6 @@ class ServiceRoot : public RootItem { virtual void start(bool freshly_activated) = 0; virtual void stop() = 0; - // Is called in short intervals in worker thread. - // Service can save its cached data (if any) here. virtual void saveAllCachedData(); // Account ID corresponds with DB attribute Accounts (id). diff --git a/src/services/owncloud/owncloudserviceroot.cpp b/src/services/owncloud/owncloudserviceroot.cpp index 65836513e..3c1867618 100755 --- a/src/services/owncloud/owncloudserviceroot.cpp +++ b/src/services/owncloud/owncloudserviceroot.cpp @@ -33,7 +33,8 @@ OwnCloudServiceRoot::OwnCloudServiceRoot(RootItem *parent) - : ServiceRoot(parent), m_recycleBin(new OwnCloudRecycleBin(this)), + : ServiceRoot(parent), m_cacheSaveMutex(new Mutex(QMutex::NonRecursive, this)), m_cachedStatesRead(QMap()), + m_cachedStatesImportant(QMap()), m_recycleBin(new OwnCloudRecycleBin(this)), m_actionSyncIn(nullptr), m_serviceMenu(QList()), m_network(new OwnCloudNetworkFactory()) { setIcon(OwnCloudServiceEntryPoint().icon()); } @@ -112,12 +113,61 @@ OwnCloudNetworkFactory *OwnCloudServiceRoot::network() const { return m_network; } +void OwnCloudServiceRoot::saveAllCachedData() { + if (m_cachedStatesRead.isEmpty() && m_cachedStatesImportant.isEmpty()) { + // No cached changes. + return; + } + + m_cacheSaveMutex->lock(); + + // Make copy of changes. + QMap cached_data_read = m_cachedStatesRead; + cached_data_read.detach(); + + QMap cached_data_imp = m_cachedStatesImportant; + cached_data_imp.detach(); + + m_cachedStatesRead.clear(); + m_cachedStatesImportant.clear(); + + m_cacheSaveMutex->unlock(); + + // Save the actual data. + for (int i = 0; i < cached_data_read.size(); i++) { + auto key = cached_data_read.keys().at(i); + QStringList ids = cached_data_read[key]; + + if (!ids.isEmpty()) { + network()->markMessagesRead(key, ids); + } + } +} + bool OwnCloudServiceRoot::onBeforeSetMessagesRead(RootItem *selected_item, const QList &messages, RootItem::ReadStatus read) { Q_UNUSED(selected_item) - QNetworkReply::NetworkError reply = network()->markMessagesRead(read, customIDsOfMessages(messages)); - return reply == QNetworkReply::NoError; + m_cacheSaveMutex->lock(); + + QStringList &list_act = m_cachedStatesRead[read]; + QStringList &list_other = m_cachedStatesRead[read == RootItem::Read ? RootItem::Unread : RootItem::Read]; + + // Store changes, they will be sent to server later. + list_act.append(customIDsOfMessages(messages)); + + QSet set_act = list_act.toSet(); + QSet set_other = list_other.toSet(); + + // Now, we want to remove all IDS from list_other, which are contained in list. + set_other -= set_act; + + list_act.clear(); list_act.append(set_act.toList()); + list_other.clear(); list_other.append(set_other.toList()); + + m_cacheSaveMutex->unlock(); + + return true; } bool OwnCloudServiceRoot::onBeforeSwitchMessageImportance(RootItem *selected_item, @@ -185,8 +235,8 @@ void OwnCloudServiceRoot::saveAccountDataToDatabase() { if (saved) { if (DatabaseQueries::createOwnCloudAccount(database, id_to_assign, m_network->authUsername(), - m_network->authPassword(), m_network->url(), - m_network->forceServerSideUpdate())) { + m_network->authPassword(), m_network->url(), + m_network->forceServerSideUpdate())) { setId(id_to_assign); setAccountId(id_to_assign); updateTitle(); @@ -195,9 +245,6 @@ void OwnCloudServiceRoot::saveAccountDataToDatabase() { } } -void OwnCloudServiceRoot::saveAllCachedData() { -} - void OwnCloudServiceRoot::addNewFeed(const QString &url) { if (!qApp->feedUpdateLock()->tryLock()) { // Lock was not obtained because diff --git a/src/services/owncloud/owncloudserviceroot.h b/src/services/owncloud/owncloudserviceroot.h index 43ff2a91f..56cbed572 100755 --- a/src/services/owncloud/owncloudserviceroot.h +++ b/src/services/owncloud/owncloudserviceroot.h @@ -20,9 +20,12 @@ #include "services/abstract/serviceroot.h" +#include + class OwnCloudNetworkFactory; class OwnCloudRecycleBin; +class Mutex; class OwnCloudServiceRoot : public ServiceRoot { Q_OBJECT @@ -58,6 +61,10 @@ class OwnCloudServiceRoot : public ServiceRoot { void addNewCategory(); private: + Mutex *m_cacheSaveMutex; + QMap m_cachedStatesRead; + QMap m_cachedStatesImportant; + QMap storeCustomFeedsData(); void restoreCustomFeedsData(const QMap &data, const QHash &feeds); RootItem *obtainNewTreeForSyncIn() const;