From 99c2418d1a270c4496b21d6d6c8035b6ef73e8a1 Mon Sep 17 00:00:00 2001 From: Alexander Tkachev Date: Thu, 18 Jul 2019 23:10:49 +0700 Subject: GUI: Rewrite Cloud tab - StorageWizardDialog is removed, along with bmps it was using; - EditTextWidget now accepts custom font in constructor; - ScrollContainer scrollbar now jumps to top when content height changes so it's "overscrolled"; - IndexPageHandler now does not awaits for `code` GET-parameter, as local webserver is no longer used to connect Storages; - CloudManager and all corresponding Storages are updated to support disconnecting and to notify about successful connection. --- backends/cloud/basestorage.cpp | 21 ++++++--- backends/cloud/basestorage.h | 6 +-- backends/cloud/box/boxstorage.cpp | 9 +++- backends/cloud/box/boxstorage.h | 7 ++- backends/cloud/cloudmanager.cpp | 52 ++++++++++++++++++++--- backends/cloud/cloudmanager.h | 10 ++++- backends/cloud/dropbox/dropboxstorage.cpp | 8 +++- backends/cloud/dropbox/dropboxstorage.h | 7 ++- backends/cloud/googledrive/googledrivestorage.cpp | 9 +++- backends/cloud/googledrive/googledrivestorage.h | 7 ++- backends/cloud/onedrive/onedrivestorage.cpp | 9 +++- backends/cloud/onedrive/onedrivestorage.h | 7 ++- 12 files changed, 125 insertions(+), 27 deletions(-) (limited to 'backends/cloud') diff --git a/backends/cloud/basestorage.cpp b/backends/cloud/basestorage.cpp index 805cb472a2..bb198120ff 100644 --- a/backends/cloud/basestorage.cpp +++ b/backends/cloud/basestorage.cpp @@ -37,18 +37,19 @@ BaseStorage::BaseStorage(Common::String token, Common::String refreshToken): BaseStorage::~BaseStorage() {} -void BaseStorage::getAccessToken(Common::String code) { - Networking::JsonCallback callback = new Common::Callback(this, &BaseStorage::codeFlowComplete); - Networking::ErrorCallback errorCallback = new Common::Callback(this, &BaseStorage::codeFlowFailed); +void BaseStorage::getAccessToken(Common::String code, Networking::ErrorCallback callback) { + Networking::JsonCallback innerCallback = new Common::CallbackBridge(this, &BaseStorage::codeFlowComplete, callback); + Networking::ErrorCallback errorCallback = new Common::CallbackBridge(this, &BaseStorage::codeFlowFailed, callback); Common::String url = Common::String::format("https://cloud.scummvm.org/%s/token/%s", cloudProvider().c_str(), code.c_str()); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(callback, errorCallback, url); + Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, url); addRequest(request); } -void BaseStorage::codeFlowComplete(Networking::JsonResponse response) { +void BaseStorage::codeFlowComplete(Networking::ErrorCallback callback, Networking::JsonResponse response) { bool success = true; + Common::String callbackMessage = "OK"; Common::JSONValue *json = (Common::JSONValue *)response.value; if (json == nullptr) { @@ -78,6 +79,7 @@ void BaseStorage::codeFlowComplete(Networking::JsonResponse response) { } warning("BaseStorage: response says error occurred: %s", errorMessage.c_str()); success = false; + callbackMessage = errorMessage; } if (success && !Networking::CurlJsonRequest::jsonContainsObject(result, "oauth", "BaseStorage::codeFlowComplete")) { @@ -110,13 +112,20 @@ void BaseStorage::codeFlowComplete(Networking::JsonResponse response) { if (!success) CloudMan.removeStorage(this); + if (callback) + (*callback)(Networking::ErrorResponse(nullptr, false, !success, callbackMessage, -1)); delete json; + delete callback; } -void BaseStorage::codeFlowFailed(Networking::ErrorResponse error) { +void BaseStorage::codeFlowFailed(Networking::ErrorCallback callback, Networking::ErrorResponse error) { debug(9, "BaseStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode); debug(9, "%s", error.response.c_str()); CloudMan.removeStorage(this); + + if (callback) + (*callback)(error); + delete callback; } void BaseStorage::refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback) { diff --git a/backends/cloud/basestorage.h b/backends/cloud/basestorage.h index 243e7f4bcc..aae1a6ec2f 100644 --- a/backends/cloud/basestorage.h +++ b/backends/cloud/basestorage.h @@ -37,19 +37,19 @@ protected: * Gets token from cloud.scummvm.org using given code. * Base implementation for storages with common auth procedure. */ - virtual void getAccessToken(Common::String code); + virtual void getAccessToken(Common::String code, Networking::ErrorCallback callback); /** * Handles JSON response which should contain access token requested * with getAccessToken(). */ - virtual void codeFlowComplete(Networking::JsonResponse response); + virtual void codeFlowComplete(Networking::ErrorCallback callback, Networking::JsonResponse response); /** * Handles network errors occurred while getting access token requested * with getAccessToken(). */ - virtual void codeFlowFailed(Networking::ErrorResponse error); + virtual void codeFlowFailed(Networking::ErrorCallback callback, Networking::ErrorResponse error); /** * Return cloud provider name, used in cloud.scummvm.org endpoints. diff --git a/backends/cloud/box/boxstorage.cpp b/backends/cloud/box/boxstorage.cpp index f76fa3ac23..13046a08e0 100644 --- a/backends/cloud/box/boxstorage.cpp +++ b/backends/cloud/box/boxstorage.cpp @@ -45,8 +45,8 @@ namespace Box { BoxStorage::BoxStorage(Common::String token, Common::String refreshToken): IdStorage(token, refreshToken) {} -BoxStorage::BoxStorage(Common::String code) { - getAccessToken(code); +BoxStorage::BoxStorage(Common::String code, Networking::ErrorCallback cb) { + getAccessToken(code, cb); } BoxStorage::~BoxStorage() {} @@ -227,6 +227,11 @@ BoxStorage *BoxStorage::loadFromConfig(Common::String keyPrefix) { return new BoxStorage(accessToken, refreshToken); } +void BoxStorage::removeFromConfig(Common::String keyPrefix) { + ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain); + ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain); +} + Common::String BoxStorage::getRootDirectoryId() { return "0"; } diff --git a/backends/cloud/box/boxstorage.h b/backends/cloud/box/boxstorage.h index a8fd32c404..ce77192bfa 100644 --- a/backends/cloud/box/boxstorage.h +++ b/backends/cloud/box/boxstorage.h @@ -55,7 +55,7 @@ protected: public: /** This constructor uses OAuth code flow to get tokens. */ - BoxStorage(Common::String code); + BoxStorage(Common::String code, Networking::ErrorCallback cb); virtual ~BoxStorage(); /** @@ -104,6 +104,11 @@ public: */ static BoxStorage *loadFromConfig(Common::String keyPrefix); + /** + * Remove all BoxStorage-related data from config. + */ + static void removeFromConfig(Common::String keyPrefix); + virtual Common::String getRootDirectoryId(); Common::String accessToken() const { return _token; } diff --git a/backends/cloud/cloudmanager.cpp b/backends/cloud/cloudmanager.cpp index 20c279323c..432a63b040 100644 --- a/backends/cloud/cloudmanager.cpp +++ b/backends/cloud/cloudmanager.cpp @@ -148,6 +148,12 @@ void CloudManager::replaceStorage(Storage *storage, uint32 index) { } _activeStorage = storage; _currentStorageIndex = index; + if (_storages[index].username == "") { + // options' Cloud tab believes Storage is connected once it has non-empty username + _storages[index].username = _(""); + _storages[index].lastSyncDate = _(""); + _storages[index].usedBytes = 0; + } save(); //do what should be done on first Storage connect @@ -250,21 +256,21 @@ void CloudManager::setStorageLastSync(uint32 index, Common::String date) { save(); } -void CloudManager::connectStorage(uint32 index, Common::String code) { +void CloudManager::connectStorage(uint32 index, Common::String code, Networking::ErrorCallback cb) { freeStorages(); switch (index) { case kStorageDropboxId: - new Dropbox::DropboxStorage(code); + new Dropbox::DropboxStorage(code, cb); break; case kStorageOneDriveId: - new OneDrive::OneDriveStorage(code); + new OneDrive::OneDriveStorage(code, cb); break; case kStorageGoogleDriveId: - new GoogleDrive::GoogleDriveStorage(code); + new GoogleDrive::GoogleDriveStorage(code, cb); break; case kStorageBoxId: - new Box::BoxStorage(code); + new Box::BoxStorage(code, cb); break; } // in these constructors Storages request token using the passed code @@ -273,6 +279,42 @@ void CloudManager::connectStorage(uint32 index, Common::String code) { // thus, no memory leak happens } +void CloudManager::disconnectStorage(uint32 index) { + if (index >= kStorageTotal) + error("CloudManager::disconnectStorage: invalid index passed"); + + Common::String name = getStorageConfigName(index); + switch (index) { + case kStorageDropboxId: + Dropbox::DropboxStorage::removeFromConfig(kStoragePrefix + name + "_"); + break; + case kStorageOneDriveId: + OneDrive::OneDriveStorage::removeFromConfig(kStoragePrefix + name + "_"); + break; + case kStorageGoogleDriveId: + GoogleDrive::GoogleDriveStorage::removeFromConfig(kStoragePrefix + name + "_"); + break; + case kStorageBoxId: + Box::BoxStorage::removeFromConfig(kStoragePrefix + name + "_"); + break; + } + + switchStorage(kStorageNoneId); + + ConfMan.removeKey(kStoragePrefix + name + "_username", ConfMan.kCloudDomain); + ConfMan.removeKey(kStoragePrefix + name + "_lastSync", ConfMan.kCloudDomain); + ConfMan.removeKey(kStoragePrefix + name + "_usedBytes", ConfMan.kCloudDomain); + + StorageConfig config; + config.name = _(name); + config.username = ""; + config.lastSyncDate = ""; + config.usedBytes = 0; + + _storages[index] = config; +} + + Networking::Request *CloudManager::listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) { Storage *storage = getCurrentStorage(); if (storage) { diff --git a/backends/cloud/cloudmanager.h b/backends/cloud/cloudmanager.h index eb882a63af..131af9bb8f 100644 --- a/backends/cloud/cloudmanager.h +++ b/backends/cloud/cloudmanager.h @@ -204,8 +204,16 @@ public: * * @param index Storage's index * @param code OAuth2 code received from user + * @param cb callback to notify of success or error */ - void connectStorage(uint32 index, Common::String code); + void connectStorage(uint32 index, Common::String code, Networking::ErrorCallback cb = nullptr); + + /** + * Remove Storage with a given index from config. + * + * @param index Storage's index + */ + void disconnectStorage(uint32 index); /** Returns ListDirectoryResponse with list of files. */ Networking::Request *listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive = false); diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp index c12dec9968..5d8b9e0425 100644 --- a/backends/cloud/dropbox/dropboxstorage.cpp +++ b/backends/cloud/dropbox/dropboxstorage.cpp @@ -42,8 +42,8 @@ namespace Dropbox { DropboxStorage::DropboxStorage(Common::String accessToken, bool unused): BaseStorage(accessToken, "") {} -DropboxStorage::DropboxStorage(Common::String code): BaseStorage() { - getAccessToken(code); +DropboxStorage::DropboxStorage(Common::String code, Networking::ErrorCallback cb): BaseStorage() { + getAccessToken(code, cb); } DropboxStorage::~DropboxStorage() {} @@ -112,5 +112,9 @@ DropboxStorage *DropboxStorage::loadFromConfig(Common::String keyPrefix) { return new DropboxStorage(accessToken, true); } +void DropboxStorage::removeFromConfig(Common::String keyPrefix) { + ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain); +} + } // End of namespace Dropbox } // End of namespace Cloud diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h index bca83d2b5a..0b76bb5c4a 100644 --- a/backends/cloud/dropbox/dropboxstorage.h +++ b/backends/cloud/dropbox/dropboxstorage.h @@ -51,7 +51,7 @@ protected: public: /** This constructor uses OAuth code flow to get tokens. */ - DropboxStorage(Common::String code); + DropboxStorage(Common::String code, Networking::ErrorCallback cb); virtual ~DropboxStorage(); /** @@ -98,6 +98,11 @@ public: * @return pointer to the newly created DropboxStorage or 0 if some problem occured. */ static DropboxStorage *loadFromConfig(Common::String keyPrefix); + + /** + * Remove all DropboxStorage-related data from config. + */ + static void removeFromConfig(Common::String keyPrefix); }; } // End of namespace Dropbox diff --git a/backends/cloud/googledrive/googledrivestorage.cpp b/backends/cloud/googledrive/googledrivestorage.cpp index 67d157748a..a6e17e6ad3 100644 --- a/backends/cloud/googledrive/googledrivestorage.cpp +++ b/backends/cloud/googledrive/googledrivestorage.cpp @@ -46,8 +46,8 @@ namespace GoogleDrive { GoogleDriveStorage::GoogleDriveStorage(Common::String token, Common::String refreshToken): IdStorage(token, refreshToken) {} -GoogleDriveStorage::GoogleDriveStorage(Common::String code) { - getAccessToken(code); +GoogleDriveStorage::GoogleDriveStorage(Common::String code, Networking::ErrorCallback cb) { + getAccessToken(code, cb); } GoogleDriveStorage::~GoogleDriveStorage() {} @@ -231,6 +231,11 @@ GoogleDriveStorage *GoogleDriveStorage::loadFromConfig(Common::String keyPrefix) return new GoogleDriveStorage(accessToken, refreshToken); } +void GoogleDriveStorage::removeFromConfig(Common::String keyPrefix) { + ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain); + ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain); +} + Common::String GoogleDriveStorage::getRootDirectoryId() { return "root"; } diff --git a/backends/cloud/googledrive/googledrivestorage.h b/backends/cloud/googledrive/googledrivestorage.h index 21e027c4a7..db47e7cd3c 100644 --- a/backends/cloud/googledrive/googledrivestorage.h +++ b/backends/cloud/googledrive/googledrivestorage.h @@ -58,7 +58,7 @@ protected: public: /** This constructor uses OAuth code flow to get tokens. */ - GoogleDriveStorage(Common::String code); + GoogleDriveStorage(Common::String code, Networking::ErrorCallback cb); virtual ~GoogleDriveStorage(); /** @@ -106,6 +106,11 @@ public: */ static GoogleDriveStorage *loadFromConfig(Common::String keyPrefix); + /** + * Remove all GoogleDriveStorage-related data from config. + */ + static void removeFromConfig(Common::String keyPrefix); + virtual Common::String getRootDirectoryId(); Common::String accessToken() const { return _token; } diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp index 48c3a10d82..6d05d84c39 100644 --- a/backends/cloud/onedrive/onedrivestorage.cpp +++ b/backends/cloud/onedrive/onedrivestorage.cpp @@ -45,8 +45,8 @@ namespace OneDrive { OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken): BaseStorage(token, refreshToken) {} -OneDriveStorage::OneDriveStorage(Common::String code) { - getAccessToken(code); +OneDriveStorage::OneDriveStorage(Common::String code, Networking::ErrorCallback cb) { + getAccessToken(code, cb); } OneDriveStorage::~OneDriveStorage() {} @@ -209,5 +209,10 @@ OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) { return new OneDriveStorage(accessToken, refreshToken); } +void OneDriveStorage::removeFromConfig(Common::String keyPrefix) { + ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain); + ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain); +} + } // End of namespace OneDrive } // End of namespace Cloud diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h index 4b18929d73..cc46772282 100644 --- a/backends/cloud/onedrive/onedrivestorage.h +++ b/backends/cloud/onedrive/onedrivestorage.h @@ -55,7 +55,7 @@ protected: public: /** This constructor uses OAuth code flow to get tokens. */ - OneDriveStorage(Common::String code); + OneDriveStorage(Common::String code, Networking::ErrorCallback cb); virtual ~OneDriveStorage(); /** @@ -103,6 +103,11 @@ public: */ static OneDriveStorage *loadFromConfig(Common::String keyPrefix); + /** + * Remove all OneDriveStorage-related data from config. + */ + static void removeFromConfig(Common::String keyPrefix); + Common::String accessToken() const { return _token; } }; -- cgit v1.2.3