Use push notifications to notify file provider of changes
authorClaudio Cambra <claudio.cambra@nextcloud.com>
Sat, 11 Mar 2023 00:25:05 +0000 (01:25 +0100)
committerClaudio Cambra <claudio.cambra@nextcloud.com>
Fri, 12 May 2023 05:21:26 +0000 (13:21 +0800)
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
src/gui/macOS/fileproviderdomainmanager.h
src/gui/macOS/fileproviderdomainmanager_mac.mm

index 7e4fff181bf20a6e6513e0b54526b1b085f00a47..7f2ddd46065364c0cc8ea50bea3a9fad9739a288 100644 (file)
@@ -18,6 +18,7 @@
 
 namespace OCC {
 
+class Account;
 class AccountState;
 
 namespace Mac {
@@ -36,6 +37,10 @@ private slots:
     void addFileProviderDomainForAccount(OCC::AccountState *accountState);
     void removeFileProviderDomainForAccount(OCC::AccountState *accountState);
 
+    void trySetupPushNotificationsForAccount(Account *account);
+    void setupPushNotificationsForAccount(OCC::Account *account);
+    void signalEnumeratorChanged(OCC::Account *account);
+
 private:
     explicit FileProviderDomainManager(QObject *parent = nullptr);
     static FileProviderDomainManager *_instance;
index 6993c0186538e0f005b466339bdb8d4a5fd9c649..f87f466af663b848bcecbbe0843e757e178c9f4b 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include "fileproviderdomainmanager.h"
+#include "pushnotifications.h"
 
 #import <FileProvider/FileProvider.h>
 
@@ -218,12 +219,74 @@ void FileProviderDomainManager::setupFileProviderDomains()
 
 void FileProviderDomainManager::addFileProviderDomainForAccount(AccountState *accountState)
 {
+    Q_ASSERT(accountState);
+    const auto account = accountState->account();
+    Q_ASSERT(account);
+
     d->addFileProviderDomain(accountState);
+
+    const auto accountCapabilities = account->capabilities().isValid();
+    if (!accountCapabilities) {
+        connect(account.get(), &Account::capabilitiesChanged, this, [this, account] {
+            trySetupPushNotificationsForAccount(account.get());
+        });
+        return;
+    }
+
+    trySetupPushNotificationsForAccount(account.get());
+}
+
+void FileProviderDomainManager::trySetupPushNotificationsForAccount(Account *account)
+{
+    Q_ASSERT(account);
+
+    const auto pushNotifications = account->pushNotifications();
+    const auto pushNotificationsCapability = account->capabilities().availablePushNotifications() & PushNotificationType::Files;
+
+    if (pushNotificationsCapability && pushNotifications && pushNotifications->isReady()) {
+        qCDebug(lcMacFileProviderDomainManager) << "Push notifications already ready, connecting them to enumerator signalling."
+                                                << account->displayName();
+        setupPushNotificationsForAccount(account);
+    } else if (pushNotificationsCapability) {
+        qCDebug(lcMacFileProviderDomainManager) << "Push notifications not yet ready, will connect to signalling when ready."
+                                                << account->displayName();
+        connect(account, &Account::pushNotificationsReady, this, &FileProviderDomainManager::setupPushNotificationsForAccount);
+    }
+}
+
+void FileProviderDomainManager::setupPushNotificationsForAccount(Account *account)
+{
+    Q_ASSERT(account);
+
+    qCDebug(lcMacFileProviderDomainManager) << "Setting up push notifications for file provider domain for account:"
+                                            << account->displayName();
+
+    connect(account->pushNotifications(), &PushNotifications::filesChanged, this, &FileProviderDomainManager::signalEnumeratorChanged);
+    disconnect(account, &Account::pushNotificationsReady, this, &FileProviderDomainManager::setupPushNotificationsForAccount);
+}
+
+void FileProviderDomainManager::signalEnumeratorChanged(Account *account)
+{
+    Q_ASSERT(account);
+    d->signalEnumeratorChanged(account);
 }
 
 void FileProviderDomainManager::removeFileProviderDomainForAccount(AccountState* accountState)
 {
+    Q_ASSERT(accountState);
+    const auto account = accountState->account();
+    Q_ASSERT(account);
+
     d->removeFileProviderDomain(accountState);
+
+    const auto pushNotifications = account->pushNotifications();
+    const auto pushNotificationsCapability = account->capabilities().availablePushNotifications() & PushNotificationType::Files;
+
+    if (pushNotificationsCapability && pushNotifications && pushNotifications->isReady()) {
+        disconnect(pushNotifications, &PushNotifications::filesChanged, this, &FileProviderDomainManager::signalEnumeratorChanged);
+    } else if (pushNotificationsCapability) {
+        disconnect(account.get(), &Account::pushNotificationsReady, this, &FileProviderDomainManager::setupPushNotificationsForAccount);
+    }
 }
 
 } // namespace Mac