diff --git a/src/gui/accountmanager.cpp b/src/gui/accountmanager.cpp
index 76c94eb2a8..e78d760960 100644
--- a/src/gui/accountmanager.cpp
+++ b/src/gui/accountmanager.cpp
@@ -287,6 +287,7 @@ bool AccountManager::restoreFromLegacySettings()
configFile.setPromptDeleteFiles(settings->value(ConfigFile::promptDeleteC, configFile.promptDeleteFiles()).toBool());
configFile.setShowCallNotifications(settings->value(ConfigFile::showCallNotificationsC, configFile.showCallNotifications()).toBool());
configFile.setShowChatNotifications(settings->value(ConfigFile::showChatNotificationsC, configFile.showChatNotifications()).toBool());
+ configFile.setShowQuotaWarningNotifications(settings->value(ConfigFile::showQuotaWarningNotificationsC, configFile.showQuotaWarningNotifications()).toBool());
configFile.setShowInExplorerNavigationPane(settings->value(ConfigFile::showInExplorerNavigationPaneC, configFile.showInExplorerNavigationPane()).toBool());
ClientProxy().saveProxyConfigurationFromSettings(*settings);
configFile.setUseUploadLimit(settings->value(ConfigFile::useUploadLimitC, configFile.useUploadLimit()).toInt());
diff --git a/src/gui/generalsettings.cpp b/src/gui/generalsettings.cpp
index 10271ecc1e..a9b3c6c818 100644
--- a/src/gui/generalsettings.cpp
+++ b/src/gui/generalsettings.cpp
@@ -195,6 +195,9 @@ GeneralSettings::GeneralSettings(QWidget *parent)
this, &GeneralSettings::slotToggleCallNotifications);
_ui->callNotificationsCheckBox->setToolTip(tr("Show call notification dialogs."));
+ connect(_ui->quotaWarningNotificationsCheckBox, &QAbstractButton::toggled, this, &GeneralSettings::slotToggleQuotaWarningNotifications);
+ _ui->quotaWarningNotificationsCheckBox->setToolTip(tr("Show notification when quota usage exceeds 80%."));
+
connect(_ui->showInExplorerNavigationPaneCheckBox, &QAbstractButton::toggled, this, &GeneralSettings::slotShowInExplorerNavigationPane);
// Rename 'Explorer' appropriately on non-Windows
@@ -298,6 +301,8 @@ void GeneralSettings::loadMiscSettings()
_ui->chatNotificationsCheckBox->setChecked(cfgFile.showChatNotifications());
_ui->callNotificationsCheckBox->setEnabled(cfgFile.optionalServerNotifications());
_ui->callNotificationsCheckBox->setChecked(cfgFile.showCallNotifications());
+ _ui->quotaWarningNotificationsCheckBox->setEnabled(cfgFile.optionalServerNotifications());
+ _ui->quotaWarningNotificationsCheckBox->setChecked(cfgFile.showQuotaWarningNotifications());
_ui->showInExplorerNavigationPaneCheckBox->setChecked(cfgFile.showInExplorerNavigationPane());
_ui->newExternalStorage->setChecked(cfgFile.confirmExternalStorage());
_ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons());
@@ -594,6 +599,12 @@ void GeneralSettings::slotToggleCallNotifications(bool enable)
cfgFile.setShowCallNotifications(enable);
}
+void GeneralSettings::slotToggleQuotaWarningNotifications(bool enable)
+{
+ ConfigFile cfgFile;
+ cfgFile.setShowQuotaWarningNotifications(enable);
+}
+
void GeneralSettings::slotShowInExplorerNavigationPane(bool checked)
{
ConfigFile cfgFile;
diff --git a/src/gui/generalsettings.h b/src/gui/generalsettings.h
index 2c52ff0080..b62a7b3c07 100644
--- a/src/gui/generalsettings.h
+++ b/src/gui/generalsettings.h
@@ -49,6 +49,7 @@ private slots:
void slotToggleOptionalServerNotifications(bool);
void slotToggleChatNotifications(bool);
void slotToggleCallNotifications(bool);
+ void slotToggleQuotaWarningNotifications(bool);
void slotShowInExplorerNavigationPane(bool);
void slotIgnoreFilesEditor();
void slotCreateDebugArchive();
diff --git a/src/gui/generalsettings.ui b/src/gui/generalsettings.ui
index 0a20f0b68c..b26f433ed2 100644
--- a/src/gui/generalsettings.ui
+++ b/src/gui/generalsettings.ui
@@ -58,6 +58,13 @@
+ -
+
+
+ Show &Quota Warning Notifications
+
+
+
diff --git a/src/gui/tray/usermodel.cpp b/src/gui/tray/usermodel.cpp
index a2929b5339..f5a7946071 100644
--- a/src/gui/tray/usermodel.cpp
+++ b/src/gui/tray/usermodel.cpp
@@ -24,12 +24,14 @@
#include "tray/talkreply.h"
#include "userstatusconnector.h"
+#include
#include
#include
#include
#include
#include
#include
+#include
// time span in milliseconds which has to be between two
// refreshes of the notifications
@@ -83,6 +85,7 @@ User::User(AccountStatePtr &account, const bool &isCurrent, QObject *parent)
connect(_account.data(), &AccountState::hasFetchedNavigationApps,
this, &User::slotRebuildNavigationAppList);
connect(_account->account().data(), &Account::accountChangedDisplayName, this, &User::nameChanged);
+ connect(_account->account().data(), &Account::rootFolderQuotaChanged, this, &User::slotQuotaChanged);
connect(FolderMan::instance(), &FolderMan::folderListChanged, this, &User::hasLocalFolderChanged);
@@ -1192,6 +1195,44 @@ void User::slotFetchGroupFolders()
connect(groupFolderListJob, &SimpleNetworkJob::finishedSignal, this, &User::slotGroupFoldersFetched);
}
+void User::slotQuotaChanged(const int64_t &usedBytes, const int64_t &availableBytes)
+{
+ int64_t total = usedBytes + availableBytes;
+ if (total <= 0 || !ConfigFile().showQuotaWarningNotifications()) {
+ return;
+ }
+
+ const auto percent = (double)usedBytes / (double)total * 100.0;
+ const auto percentInt = qMin(qRound(percent), 100);
+ qCDebug(lcActivity) << tr("Quota is updated; %1 percent of the total space is used.").arg(QString::number(percentInt));
+
+ int thresholdPassed = 0;
+ if (_lastQuotaPercent < 80 && percentInt >= 80) {
+ thresholdPassed = 80;
+ }
+
+ if (_lastQuotaPercent < 90 && percentInt >= 90) {
+ thresholdPassed = 90;
+ }
+
+ if (_lastQuotaPercent < 95 && percentInt >= 95) {
+ thresholdPassed = 95;
+ }
+
+ if (thresholdPassed > 0) {
+ _activityModel->removeActivityFromActivityList(_lastQuotaActivity);
+
+ _lastQuotaActivity._type = Activity::OpenSettingsNotificationType;
+ _lastQuotaActivity._dateTime = QDateTime::fromString(QDateTime::currentDateTime().toString(), Qt::ISODate);
+ _lastQuotaActivity._subject = tr("Quota Warning - %1 percent or more storage in use").arg(QString::number(thresholdPassed));
+ _lastQuotaActivity._accName = account()->displayName();
+ _lastQuotaActivity._id = qHash(QDateTime::currentMSecsSinceEpoch());
+ showDesktopNotification(_lastQuotaActivity);
+ _activityModel->addNotificationToActivityList(_lastQuotaActivity);
+ }
+ _lastQuotaPercent = percentInt;
+}
+
void User::slotGroupFoldersFetched(QNetworkReply *reply)
{
Q_ASSERT(reply);
diff --git a/src/gui/tray/usermodel.h b/src/gui/tray/usermodel.h
index e8ca2a153b..0f7fd54834 100644
--- a/src/gui/tray/usermodel.h
+++ b/src/gui/tray/usermodel.h
@@ -18,6 +18,7 @@
#include "activitydata.h"
#include "activitylistmodel.h"
#include "folderman.h"
+#include "userinfo.h"
#include "userstatusconnector.h"
#include "userstatusselectormodel.h"
#include
@@ -161,6 +162,7 @@ private slots:
void slotReceivedPushActivity(OCC::Account *account);
void slotCheckExpiredActivities();
void slotGroupFoldersFetched(QNetworkReply *reply);
+ void slotQuotaChanged(const int64_t &usedBytes, const int64_t &availableBytes);
void checkNotifiedNotifications();
void showDesktopNotification(const QString &title, const QString &message, const long notificationId);
void showDesktopNotification(const OCC::Activity &activity);
@@ -206,6 +208,10 @@ private:
int _lastTalkNotificationsReceivedCount = 0;
bool _isNotificationFetchRunning = false;
+
+ // used for quota warnings
+ int _lastQuotaPercent = 0;
+ Activity _lastQuotaActivity;
};
class UserModel : public QAbstractListModel
diff --git a/src/libsync/account.h b/src/libsync/account.h
index 5434904ec5..bbb198762d 100644
--- a/src/libsync/account.h
+++ b/src/libsync/account.h
@@ -470,6 +470,7 @@ signals:
void encryptionCertificateFingerprintChanged();
void userCertificateNeedsMigrationChanged();
+ void rootFolderQuotaChanged(const int64_t &usedBytes, const int64_t &availableBytes);
protected Q_SLOTS:
void slotCredentialsFetched();
void slotCredentialsAsked();
diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp
index d512fba3af..71ac126d46 100644
--- a/src/libsync/configfile.cpp
+++ b/src/libsync/configfile.cpp
@@ -216,6 +216,19 @@ void ConfigFile::setShowCallNotifications(bool show)
settings.sync();
}
+bool ConfigFile::showQuotaWarningNotifications() const
+{
+ const QSettings settings(configFile(), QSettings::IniFormat);
+ return settings.value(showQuotaWarningNotificationsC, true).toBool() && optionalServerNotifications();
+}
+
+void ConfigFile::setShowQuotaWarningNotifications(bool show)
+{
+ QSettings settings(configFile(), QSettings::IniFormat);
+ settings.setValue(showQuotaWarningNotificationsC, show);
+ settings.sync();
+}
+
bool ConfigFile::showInExplorerNavigationPane() const
{
const bool defaultValue =
diff --git a/src/libsync/configfile.h b/src/libsync/configfile.h
index c2b22f0c6e..92f960a5c5 100644
--- a/src/libsync/configfile.h
+++ b/src/libsync/configfile.h
@@ -165,6 +165,9 @@ public:
[[nodiscard]] bool showCallNotifications() const;
void setShowCallNotifications(bool show);
+ [[nodiscard]] bool showQuotaWarningNotifications() const;
+ void setShowQuotaWarningNotifications(bool show);
+
[[nodiscard]] bool showInExplorerNavigationPane() const;
void setShowInExplorerNavigationPane(bool show);
@@ -257,6 +260,7 @@ public:
static constexpr char optionalServerNotificationsC[] = "optionalServerNotifications";
static constexpr char promptDeleteC[] = "promptDeleteAllFiles";
static constexpr char showCallNotificationsC[] = "showCallNotifications";
+ static constexpr char showQuotaWarningNotificationsC[] = "showQuotaWarningNotifications";
static constexpr char showChatNotificationsC[] = "showChatNotifications";
static constexpr char showInExplorerNavigationPaneC[] = "showInExplorerNavigationPane";
diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp
index 1b314040d6..a5e53ce32b 100644
--- a/src/libsync/discovery.cpp
+++ b/src/libsync/discovery.cpp
@@ -2299,6 +2299,10 @@ void ProcessDirectoryJob::setFolderQuota(const FolderQuota &folderQuota)
{
_folderQuota.bytesUsed = folderQuota.bytesUsed;
_folderQuota.bytesAvailable = folderQuota.bytesAvailable;
+
+ if (_currentFolder._original.isEmpty()) {
+ emit updatedRootFolderQuota(_folderQuota.bytesUsed, _folderQuota.bytesAvailable);
+ }
}
void ProcessDirectoryJob::startAsyncLocalQuery()
diff --git a/src/libsync/discovery.h b/src/libsync/discovery.h
index 164de5662c..1dc2de2350 100644
--- a/src/libsync/discovery.h
+++ b/src/libsync/discovery.h
@@ -305,6 +305,7 @@ signals:
void finished();
// The root etag of this directory was fetched
void etag(const QByteArray &, const QDateTime &time);
+ void updatedRootFolderQuota(const int64_t &bytesUsed, const int64_t &bytesAvailable);
private slots:
void setFolderQuota(const FolderQuota &folderQuota);
diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp
index 7b4b69f4f9..a9ca164038 100644
--- a/src/libsync/syncengine.cpp
+++ b/src/libsync/syncengine.cpp
@@ -760,6 +760,7 @@ void SyncEngine::startSync()
_discoveryPhase->startJob(discoveryJob);
connect(discoveryJob, &ProcessDirectoryJob::etag, this, &SyncEngine::slotRootEtagReceived);
+ connect(discoveryJob, &ProcessDirectoryJob::updatedRootFolderQuota, account().data(), &Account::rootFolderQuotaChanged);
connect(_discoveryPhase.get(), &DiscoveryPhase::addErrorToGui, this, &SyncEngine::addErrorToGui);
}