From: Michael Schuster Date: Wed, 15 Jan 2020 15:23:46 +0000 (+0100) Subject: Fetch server Apps in AccountState (moved from ownCloudGui) X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~222^2^2~413^2~36 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=cb328d6cea33186110068eb1d5293d9f7721b261;p=nextcloud-desktop.git Fetch server Apps in AccountState (moved from ownCloudGui) - Add a new class AccountApp to keep them in an AccountAppList and also save properties like ID and Icon URL. - Clear the app list upon re-fetch to avoid endlessly growing lists like in the previous implementation in ownCloudGui. Signed-off-by: Michael Schuster --- diff --git a/src/gui/accountstate.cpp b/src/gui/accountstate.cpp index 9d2fa1830..b9b42eca5 100644 --- a/src/gui/accountstate.cpp +++ b/src/gui/accountstate.cpp @@ -20,6 +20,7 @@ #include "creds/httpcredentials.h" #include "logger.h" #include "configfile.h" +#include "ocsnavigationappsjob.h" #include #include @@ -27,6 +28,7 @@ #include #include +#include #include #include @@ -259,6 +261,9 @@ void AccountState::checkConnectivity() // Use a small authed propfind as a minimal ping when we're // already connected. conValidator->checkAuthentication(); + + // Get the Apps available on the server. + fetchNavigationApps(); } else { // Check the server and then the auth. @@ -316,6 +321,9 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta if (_state != Connected) { setState(Connected); setTalkCapability(); + + // Get the Apps available on the server. + fetchNavigationApps(); } break; case ConnectionValidator::Undefined: @@ -428,4 +436,96 @@ std::unique_ptr AccountState::settings() return s; } +void AccountState::fetchNavigationApps(){ + OcsNavigationAppsJob *job = new OcsNavigationAppsJob(_account); + job->addRawHeader("If-None-Match", navigationAppsEtagResponseHeader()); + connect(job, &OcsNavigationAppsJob::appsJobFinished, this, &AccountState::slotNavigationAppsFetched); + connect(job, &OcsNavigationAppsJob::etagResponseHeaderReceived, this, &AccountState::slotEtagResponseHeaderReceived); + connect(job, &OcsNavigationAppsJob::ocsError, this, &AccountState::slotOcsError); + job->getNavigationApps(); +} + +void AccountState::slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode){ + if(statusCode == 200){ + qCDebug(lcAccountState) << "New navigation apps ETag Response Header received " << value; + setNavigationAppsEtagResponseHeader(value); + } +} + +void AccountState::slotOcsError(int statusCode, const QString &message) +{ + qCDebug(lcAccountState) << "Error " << statusCode << " while fetching new navigation apps: " << message; +} + +void AccountState::slotNavigationAppsFetched(const QJsonDocument &reply, int statusCode) +{ + if(_account){ + if (statusCode == 304) { + qCWarning(lcAccountState) << "Status code " << statusCode << " Not Modified - No new navigation apps."; + } else { + _apps.clear(); + _hasTalk = false; + + if(!reply.isEmpty()){ + printf("%s\n", reply.toJson().toStdString().c_str()); + auto element = reply.object().value("ocs").toObject().value("data"); + auto navLinks = element.toArray(); + + if(navLinks.size() > 0){ + foreach (const QJsonValue &value, navLinks) { + auto navLink = value.toObject(); + + AccountApp *app = new AccountApp(navLink.value("name").toString(), QUrl(navLink.value("href").toString()), + navLink.value("id").toString(), QUrl(navLink.value("icon").toString())); + + _apps << app; + } + } + } + + emit hasFetchedNavigationApps(); + } + } +} + +AccountAppList AccountState::appList() const +{ + return _apps; +} + +/*-------------------------------------------------------------------------------------*/ + +AccountApp::AccountApp(const QString &name, const QUrl &url, + const QString &id, const QUrl &iconUrl, + QObject *parent) + : QObject(parent) + , _name(name) + , _url(url) + , _id(id) + , _iconUrl(iconUrl) +{ +} + +QString AccountApp::name() const +{ + return _name; +} + +QUrl AccountApp::url() const +{ + return _url; +} + +QString AccountApp::id() const +{ + return _id; +} + +QUrl AccountApp::iconUrl() const +{ + return _iconUrl; +} + +/*-------------------------------------------------------------------------------------*/ + } // namespace OCC diff --git a/src/gui/accountstate.h b/src/gui/accountstate.h index 7633bd78d..8bacdcd9c 100644 --- a/src/gui/accountstate.h +++ b/src/gui/accountstate.h @@ -29,9 +29,11 @@ namespace OCC { class AccountState; class Account; +class AccountApp; class RemoteWipe; typedef QExplicitlySharedDataPointer AccountStatePtr; +typedef QList AccountAppList; /** * @brief Extra info about an ownCloud server account. @@ -103,6 +105,8 @@ public: bool hasTalk() const; + AccountAppList appList() const; + /** A user-triggered sign out which disconnects, stops syncs * for the account and forgets the password. */ void signOutByUi(); @@ -164,10 +168,12 @@ public slots: private: void setState(State state); void setTalkCapability(); + void fetchNavigationApps(); signals: void stateChanged(int state); void isConnectedChanged(); + void hasFetchedNavigationApps(); protected Q_SLOTS: void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList &errors); @@ -179,6 +185,10 @@ protected Q_SLOTS: void slotCredentialsFetched(AbstractCredentials *creds); void slotCredentialsAsked(AbstractCredentials *creds); + void slotNavigationAppsFetched(const QJsonDocument &reply, int statusCode); + void slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode); + void slotOcsError(int statusCode, const QString &message); + private: AccountPtr _account; State _state; @@ -209,7 +219,34 @@ private: */ RemoteWipe *_remoteWipe; + /** + * Holds the App names and URLs available on the server + */ + AccountAppList _apps; + }; + +class AccountApp : public QObject +{ + Q_OBJECT +public: + AccountApp(const QString &name, const QUrl &url, + const QString &id, const QUrl &iconUrl, + QObject* parent = 0); + + QString name() const; + QUrl url() const; + QString id() const; + QUrl iconUrl() const; + +private: + QString _name; + QUrl _url; + + QString _id; + QUrl _iconUrl; +}; + } Q_DECLARE_METATYPE(OCC::AccountState *) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index b62122395..f4f37ba1a 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -14,7 +14,6 @@ #include "application.h" #include "owncloudgui.h" -#include "ocsnavigationappsjob.h" #include "theme.h" #include "folderman.h" #include "progressdispatcher.h" @@ -46,10 +45,6 @@ #include #endif -#include -#include -#include - #include #include #include @@ -68,7 +63,6 @@ ownCloudGui::ownCloudGui(Application *parent) #ifdef WITH_LIBCLOUDPROVIDERS , _bus(QDBusConnection::sessionBus()) #endif - , _recentActionsMenu(nullptr) , _app(parent) { _tray = Systray::instance(); @@ -369,7 +363,6 @@ void ownCloudGui::slotShowOptionalTrayMessage(const QString &title, const QStrin slotShowTrayMessage(title, msg); } - /* * open the folder with the given Alias */ @@ -393,93 +386,6 @@ void ownCloudGui::slotFolderOpenAction(const QString &alias) } } -void ownCloudGui::slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode){ - if(statusCode == 200){ - qCDebug(lcApplication) << "New navigation apps ETag Response Header received " << value; - auto account = qvariant_cast(sender()->property(propertyAccountC)); - account->setNavigationAppsEtagResponseHeader(value); - } -} - -void ownCloudGui::fetchNavigationApps(AccountStatePtr account){ - OcsNavigationAppsJob *job = new OcsNavigationAppsJob(account->account()); - job->setProperty(propertyAccountC, QVariant::fromValue(account)); - job->addRawHeader("If-None-Match", account->navigationAppsEtagResponseHeader()); - connect(job, &OcsNavigationAppsJob::appsJobFinished, this, &ownCloudGui::slotNavigationAppsFetched); - connect(job, &OcsNavigationAppsJob::etagResponseHeaderReceived, this, &ownCloudGui::slotEtagResponseHeaderReceived); - connect(job, &OcsNavigationAppsJob::ocsError, this, &ownCloudGui::slotOcsError); - job->getNavigationApps(); -} - -void ownCloudGui::buildNavigationAppsMenu(AccountStatePtr account, QMenu *accountMenu){ - auto navLinks = _navApps.value(account); - - _navLinksMenu->clear(); - _navLinksMenu->setEnabled(navLinks.size() > 0); - - if(navLinks.size() > 0){ - // when there is only one account add the nav links above the settings - QAction *actionBefore = _actionSettings; - - // when there is more than one account add the nav links above pause/unpause folder or logout action - if(AccountManager::instance()->accounts().size() > 1){ - foreach(QAction *action, accountMenu->actions()){ - - // pause/unpause folder and logout actions have propertyAccountC - if(auto actionAccount = qvariant_cast(action->property(propertyAccountC))){ - if(actionAccount == account){ - actionBefore = action; - break; - } - } - } - } - - // Create submenu with links - foreach (const QJsonValue &value, navLinks) { - auto navLink = value.toObject(); - QAction *action = new QAction(navLink.value("name").toString(), this); - QUrl href(navLink.value("href").toString()); - connect(action, &QAction::triggered, this, [href] { QDesktopServices::openUrl(href); }); - _navLinksMenu->addAction(action); - } - } -} - -void ownCloudGui::slotNavigationAppsFetched(const QJsonDocument &reply, int statusCode) -{ - if(auto account = qvariant_cast(sender()->property(propertyAccountC))){ - if (statusCode == 304) { - qCWarning(lcApplication) << "Status code " << statusCode << " Not Modified - No new navigation apps."; - } else { - if(!reply.isEmpty()){ - auto element = reply.object().value("ocs").toObject().value("data"); - auto navLinks = element.toArray(); - _navApps.insert(account, navLinks); - } - } - - // TODO see pull #523 - auto accountList = AccountManager::instance()->accounts(); - if(accountList.size() > 1){ - // the list of apps will be displayed under the account that it belongs to - foreach (QMenu *accountMenu, _accountMenus) { - if(accountMenu->title() == account->account()->displayName()){ - buildNavigationAppsMenu(account, accountMenu); - break; - } - } - } else if(accountList.size() == 1){ - //buildNavigationAppsMenu(account, _contextMenu.data()); - } - } -} - -void ownCloudGui::slotOcsError(int statusCode, const QString &message) -{ - emit serverError(statusCode, message); -} - void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo &progress) { Q_UNUSED(folder); diff --git a/src/gui/owncloudgui.h b/src/gui/owncloudgui.h index 9efd34e8b..928a0fbd0 100644 --- a/src/gui/owncloudgui.h +++ b/src/gui/owncloudgui.h @@ -91,8 +91,6 @@ public slots: void slotOpenPath(const QString &path); void slotAccountStateChanged(); void slotTrayMessageIfServerUnsupported(Account *account); - void slotNavigationAppsFetched(const QJsonDocument &reply, int statusCode); - void slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode); /** @@ -106,9 +104,6 @@ public slots: void slotRemoveDestroyedShareDialogs(); -protected slots: - void slotOcsError(int statusCode, const QString &message); - private slots: void slotLogin(); void slotLogout(); @@ -118,8 +113,6 @@ private slots: private: void setPauseOnAllFoldersHelper(bool pause); - void fetchNavigationApps(AccountStatePtr account); - void buildNavigationAppsMenu(AccountStatePtr account, QMenu *accountMenu); QPointer _tray; QPointer _settingsDialog; @@ -129,8 +122,6 @@ private: QDBusConnection _bus; #endif - QMenu *_recentActionsMenu; - QVector _accountMenus; QMap> _shareDialogs; QAction *_actionNewAccountWizard; @@ -138,9 +129,6 @@ private: QAction *_actionEstimate; - QMenu *_navLinksMenu; - QMap _navApps; - QList _recentItemsActions; Application *_app; };