зеркало из https://github.com/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 <michael@schuster.ms>
This commit is contained in:
Родитель
b57b8cfb66
Коммит
cb328d6cea
|
@ -20,6 +20,7 @@
|
|||
#include "creds/httpcredentials.h"
|
||||
#include "logger.h"
|
||||
#include "configfile.h"
|
||||
#include "ocsnavigationappsjob.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QTimer>
|
||||
|
@ -27,6 +28,7 @@
|
|||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QNetworkRequest>
|
||||
#include <QBuffer>
|
||||
|
||||
|
@ -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<QSettings> 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
|
||||
|
|
|
@ -29,9 +29,11 @@ namespace OCC {
|
|||
|
||||
class AccountState;
|
||||
class Account;
|
||||
class AccountApp;
|
||||
class RemoteWipe;
|
||||
|
||||
typedef QExplicitlySharedDataPointer<AccountState> AccountStatePtr;
|
||||
typedef QList<AccountApp*> 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 *)
|
||||
|
|
|
@ -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 <QX11Info>
|
||||
#endif
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QQmlComponent>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
@ -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<AccountStatePtr>(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<AccountStatePtr>(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<AccountStatePtr>(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);
|
||||
|
|
|
@ -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<Systray> _tray;
|
||||
QPointer<SettingsDialog> _settingsDialog;
|
||||
|
@ -129,8 +122,6 @@ private:
|
|||
QDBusConnection _bus;
|
||||
#endif
|
||||
|
||||
QMenu *_recentActionsMenu;
|
||||
QVector<QMenu *> _accountMenus;
|
||||
QMap<QString, QPointer<ShareDialog>> _shareDialogs;
|
||||
|
||||
QAction *_actionNewAccountWizard;
|
||||
|
@ -138,9 +129,6 @@ private:
|
|||
QAction *_actionEstimate;
|
||||
|
||||
|
||||
QMenu *_navLinksMenu;
|
||||
QMap<AccountStatePtr, QJsonArray> _navApps;
|
||||
|
||||
QList<QAction *> _recentItemsActions;
|
||||
Application *_app;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче