From 27fccbbe4ea21ef4723ded4e01d5ea0df67fb61f Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 22 Apr 2016 05:19:34 -0700 Subject: QML UI: when chosing 'no cloud', switch to dive list Currently we don't remember that we picked 'no cloud' across restarts. Signed-off-by: Dirk Hohndel --- mobile-widgets/qmlmanager.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'mobile-widgets/qmlmanager.h') diff --git a/mobile-widgets/qmlmanager.h b/mobile-widgets/qmlmanager.h index ece2c7b59..860e3c3ad 100644 --- a/mobile-widgets/qmlmanager.h +++ b/mobile-widgets/qmlmanager.h @@ -39,7 +39,8 @@ public: UNKNOWN, INVALID, VALID_EMAIL, - VALID + VALID, + NOCLOUD }; static QMLManager *instance(); -- cgit v1.2.3-70-g09d2 From 4b1edceca0342a403ee549987e156b03ce8767e0 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 22 Apr 2016 07:10:20 -0700 Subject: Add helper function for the consumption of loaded dive data This allows us to call that part of the process from multiple places in the future. Signed-off-by: Dirk Hohndel --- mobile-widgets/qmlmanager.cpp | 7 ++++++- mobile-widgets/qmlmanager.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'mobile-widgets/qmlmanager.h') diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp index 9aae67f33..7780a3ff6 100644 --- a/mobile-widgets/qmlmanager.cpp +++ b/mobile-widgets/qmlmanager.cpp @@ -412,6 +412,12 @@ void QMLManager::loadDivesWithValidCredentials() alreadySaving = false; return; } + consumeFinishedLoad(currentDiveTimestamp); + setLoadFromCloud(true); +} + +void QMLManager::consumeFinishedLoad(timestamp_t currentDiveTimestamp) +{ prefs.unit_system = informational_prefs.unit_system; if (informational_prefs.unit_system == IMPERIAL) informational_prefs.units = IMPERIAL_units; @@ -426,7 +432,6 @@ void QMLManager::loadDivesWithValidCredentials() appendTextToLog(QStringLiteral("%1 dives loaded").arg(dive_table.nr)); if (dive_table.nr == 0) setStartPageText(tr("Cloud storage open successfully. No dives in dive list.")); - setLoadFromCloud(true); alreadySaving = false; } diff --git a/mobile-widgets/qmlmanager.h b/mobile-widgets/qmlmanager.h index 860e3c3ad..2bd2ee240 100644 --- a/mobile-widgets/qmlmanager.h +++ b/mobile-widgets/qmlmanager.h @@ -133,6 +133,7 @@ public slots: QString getCurrentPosition(); QString getVersion() const; void deleteGpsFix(quint64 when); + void consumeFinishedLoad(timestamp_t currentDiveTimestamp); void refreshDiveList(); void screenChanged(QScreen *screen); qreal lastDevicePixelRatio(); -- cgit v1.2.3-70-g09d2 From 4ad73fb80756eb7509efd19962994ebfeb2a219b Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 29 Apr 2016 06:28:09 -0700 Subject: QML UI: when switching from no cloud to cloud usage, don't drop local data This is rather simplistic, it just imports the local data into the remote repository and therefore loses the git history of the local data - but I wasn't able to make the git merge without shared base commit work, so I went this much easier to implement route instead. One thing we need to be careful about is that contacting the remote server could fail. If we don't manage to merge the dives from cloud server and local storage, we need to revery to no cloud status in order not to lose the local data. Signed-off-by: Dirk Hohndel --- mobile-widgets/qmlmanager.cpp | 79 ++++++++++++++++++++++++++++++++++++------- mobile-widgets/qmlmanager.h | 2 ++ 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'mobile-widgets/qmlmanager.h') diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp index 427b184f3..416130d98 100644 --- a/mobile-widgets/qmlmanager.cpp +++ b/mobile-widgets/qmlmanager.cpp @@ -20,6 +20,7 @@ #include "core/git-access.h" #include "core/cloudstorage.h" #include "core/subsurface-qt/SettingsObjectWrapper.h" +#include "core/membuffer.h" QMLManager *QMLManager::m_instance = NULL; @@ -154,6 +155,11 @@ void QMLManager::openLocalThenRemote(QString url) DiveListModel::instance()->addAllDives(); appendTextToLog(QStringLiteral("%1 dives loaded from cache").arg(dive_table.nr)); } + if (oldStatus() == NOCLOUD) { + // if we switch to credentials from NOCLOUD, we take things online temporarily + prefs.git_local_only = false; + appendTextToLog(QStringLiteral("taking things online to be able to switch to cloud account")); + } set_filename(fileNamePrt.data(), true); if (prefs.git_local_only) { appendTextToLog(QStringLiteral("have cloud credentials, but user asked not to connect to network")); @@ -164,6 +170,13 @@ void QMLManager::openLocalThenRemote(QString url) } } +void QMLManager::mergeLocalRepo() +{ + char *filename = format_string("%s/cloudstorage/localrepo[master]", system_default_directory()); + parse_file(filename); + process_dives(true, false); +} + void QMLManager::finishSetup() { // Initialize cloud credentials. @@ -346,8 +359,7 @@ void QMLManager::retrieveUserid() if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 302) { appendTextToLog(QStringLiteral("Cloud storage connection not working correctly: %1").arg(QString(reply->readAll()))); setStartPageText(RED_FONT + tr("Cannot connect to cloud storage") + END_FONT); - setAccessingCloud(-1); - alreadySaving = false; + revertToNoCloudIfNeeded(); return; } setCredentialStatus(VALID); @@ -355,8 +367,7 @@ void QMLManager::retrieveUserid() if (userid.isEmpty()) { if (same_string(prefs.cloud_storage_email, "") || same_string(prefs.cloud_storage_password, "")) { appendTextToLog("cloud user name or password are empty, can't retrieve web user id"); - setAccessingCloud(-1); - alreadySaving = false; + revertToNoCloudIfNeeded(); return; } appendTextToLog(QStringLiteral("calling getUserid with user %1").arg(prefs.cloud_storage_email)); @@ -385,12 +396,12 @@ void QMLManager::loadDiveProgress(int percent) void QMLManager::loadDivesWithValidCredentials() { QString url; + timestamp_t currentDiveTimestamp = selectedDiveTimestamp(); if (getCloudURL(url)) { QString errorString(get_error_string()); appendTextToLog(errorString); setStartPageText(RED_FONT + tr("Cloud storage error: %1").arg(errorString) + END_FONT); - setAccessingCloud(-1); - alreadySaving = false; + revertToNoCloudIfNeeded(); return; } QByteArray fileNamePrt = QFile::encodeName(url); @@ -400,13 +411,9 @@ void QMLManager::loadDivesWithValidCredentials() if (check_git_sha(fileNamePrt.data(), &git, &branch) == 0) { qDebug() << "local cache was current, no need to modify dive list"; appendTextToLog("Cloud sync shows local cache was current"); - setLoadFromCloud(true); - setAccessingCloud(-1); - alreadySaving = false; - return; + goto successful_exit; } appendTextToLog("Cloud sync brought newer data, reloading the dive list"); - timestamp_t currentDiveTimestamp = selectedDiveTimestamp(); clear_dive_file_data(); if (git != dummy_git_repository) { @@ -426,12 +433,56 @@ void QMLManager::loadDivesWithValidCredentials() report_error("failed to open file %s", fileNamePrt.data()); QString errorString(get_error_string()); appendTextToLog(errorString); - setStartPageText(RED_FONT + tr("Cloud storage error: %1").arg(errorString) + END_FONT); - alreadySaving = false; + revertToNoCloudIfNeeded(); return; } consumeFinishedLoad(currentDiveTimestamp); + +successful_exit: + alreadySaving = false; setLoadFromCloud(true); + // if we came from local storage mode, let's merge the local data into the local cache + // for the remote data - which then later gets merged with the remote data if necessary + if (oldStatus() == NOCLOUD) { + git_storage_update_progress(false, "import dives from nocloud local storage"); + dive_table.preexisting = dive_table.nr; + mergeLocalRepo(); + DiveListModel::instance()->clear(); + DiveListModel::instance()->addAllDives(); + appendTextToLog(QStringLiteral("%1 dives loaded after importing nocloud local storage").arg(dive_table.nr)); + saveChangesLocal(); + if (syncToCloud() == false) { + appendTextToLog(QStringLiteral("taking things back offline now that storage is synced")); + prefs.git_local_only = syncToCloud(); + } + } + setAccessingCloud(-1); + return; +} + +void QMLManager::revertToNoCloudIfNeeded() +{ + if (oldStatus() == NOCLOUD) { + // we tried to switch to a cloud account and had previously used local data, + // but connecting to the cloud account (and subsequently merging the local + // and cloud data) failed - so let's delete the cloud credentials and go + // back to NOCLOUD mode in order to prevent us from losing the locally stored + // dives + if (syncToCloud() == false) { + appendTextToLog(QStringLiteral("taking things back offline since sync with cloud failed")); + prefs.git_local_only = syncToCloud(); + } + free(prefs.cloud_storage_email); + prefs.cloud_storage_email = NULL; + free(prefs.cloud_storage_password); + prefs.cloud_storage_password = NULL; + setCloudUserName(""); + setCloudPassword(""); + setCredentialStatus(INCOMPLETE); + setStartPageText(RED_FONT + tr("Failed to connect to cloud server, reverting to no cloud status") + END_FONT); + } + setAccessingCloud(-1); + alreadySaving = false; } void QMLManager::consumeFinishedLoad(timestamp_t currentDiveTimestamp) @@ -1156,6 +1207,8 @@ QMLManager::credentialStatus_t QMLManager::credentialStatus() const void QMLManager::setCredentialStatus(const credentialStatus_t value) { if (m_credentialStatus != value) { + if (value == NOCLOUD) + appendTextToLog("Switching to no cloud mode"); m_credentialStatus = value; emit credentialStatusChanged(); } diff --git a/mobile-widgets/qmlmanager.h b/mobile-widgets/qmlmanager.h index 2bd2ee240..965a68d40 100644 --- a/mobile-widgets/qmlmanager.h +++ b/mobile-widgets/qmlmanager.h @@ -128,11 +128,13 @@ public slots: void clearGpsData(); void finishSetup(); void openLocalThenRemote(QString url); + void mergeLocalRepo(); QString getNumber(const QString& diveId); QString getDate(const QString& diveId); QString getCurrentPosition(); QString getVersion() const; void deleteGpsFix(quint64 when); + void revertToNoCloudIfNeeded(); void consumeFinishedLoad(timestamp_t currentDiveTimestamp); void refreshDiveList(); void screenChanged(QScreen *screen); -- cgit v1.2.3-70-g09d2 From ba9288fab6d7aa8527f7a75a717cdc88a68facd9 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sat, 30 Apr 2016 11:08:33 -0700 Subject: QML UI: when first entering cloud credentials, force cloud connection With offline the default now, we need to force a connection at least once so that the repos are in sync. And then of course we need to return to the correct state, regardless on whether this connection succeeded or failed. Signed-off-by: Dirk Hohndel --- mobile-widgets/qmlmanager.cpp | 14 ++++++++++++++ mobile-widgets/qmlmanager.h | 1 + 2 files changed, 15 insertions(+) (limited to 'mobile-widgets/qmlmanager.h') diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp index a0ed9873c..82ea319bb 100644 --- a/mobile-widgets/qmlmanager.cpp +++ b/mobile-widgets/qmlmanager.cpp @@ -286,6 +286,10 @@ void QMLManager::saveCloudCredentials() // we therefore know that no one else is already accessing THIS git repo; // let's make sure we stay the only ones doing so alreadySaving = true; + // since we changed credentials, we need to try to connect to the cloud, regardless + // of whether we're in offline mode or not, to make sure the repository is synced + currentGitLocalOnly = prefs.git_local_only; + prefs.git_local_only = false; openLocalThenRemote(url); } } @@ -461,11 +465,21 @@ successful_exit: } } setAccessingCloud(-1); + // if we got here just for an initial connection to the cloud, reset to offline + if (currentGitLocalOnly) { + currentGitLocalOnly = false; + prefs.git_local_only = true; + } return; } void QMLManager::revertToNoCloudIfNeeded() { + if (currentGitLocalOnly) { + // we tried to connect to the cloud for the first time and that failed + currentGitLocalOnly = false; + prefs.git_local_only = true; + } if (oldStatus() == NOCLOUD) { // we tried to switch to a cloud account and had previously used local data, // but connecting to the cloud account (and subsequently merging the local diff --git a/mobile-widgets/qmlmanager.h b/mobile-widgets/qmlmanager.h index 965a68d40..906e7b0b2 100644 --- a/mobile-widgets/qmlmanager.h +++ b/mobile-widgets/qmlmanager.h @@ -174,6 +174,7 @@ private: bool checkLocation(DiveObjectHelper *myDive, struct dive *d, QString location, QString gps); bool checkDuration(DiveObjectHelper *myDive, struct dive *d, QString duration); bool checkDepth(DiveObjectHelper *myDive, struct dive *d, QString depth); + bool currentGitLocalOnly; signals: void cloudUserNameChanged(); -- cgit v1.2.3-70-g09d2