From 6ff59f19714cfe7b95e8179eeb41948670c6f116 Mon Sep 17 00:00:00 2001 From: scharel Date: Mon, 21 Jun 2021 00:17:10 +0200 Subject: [PATCH] Fixed basic API calls (not visible in UI yet) --- qml/harbour-nextcloudnotes.qml | 26 +++--- qml/pages/NotesPage.qml | 9 +- qml/pages/SettingsPage.qml | 16 ++-- src/apps/abstractnextcloudapp.h | 4 +- src/apps/notes/notesapp.cpp | 54 +++++++++-- src/nextcloudapi.cpp | 33 +++---- translations/harbour-nextcloudnotes.ts | 120 ++++++++++++------------- 7 files changed, 151 insertions(+), 111 deletions(-) diff --git a/qml/harbour-nextcloudnotes.qml b/qml/harbour-nextcloudnotes.qml index 4cb55f6..8c95674 100644 --- a/qml/harbour-nextcloudnotes.qml +++ b/qml/harbour-nextcloudnotes.qml @@ -24,7 +24,7 @@ ApplicationWindow path: "/apps/harbour-nextcloudnotes" property bool initialized: false - property var accounts: value("accounts", [], Array) + property var accountList: value("accountList", [], Array) property string currentAccount: value("currentAccount", "", String) property int autoSyncInterval: value("autoSyncInterval", 0, Number) property int previewLineCount: value("previewLineCount", 4, Number) @@ -34,10 +34,6 @@ ApplicationWindow property bool useMonoFont: value("useMonoFont", false, Boolean) property bool useCapitalX: value("useCapitalX", false, Boolean) - onCurrentAccountChanged: { - console.log("Current account: " + currentAccount) - } - onSortByChanged: { if (sortBy == "none") Notes.model.invalidate() } @@ -47,9 +43,9 @@ ApplicationWindow function createAccount(username, password, url, name) { var hash = accountHash.hash(username, url) - var tmpaccounts = accounts + var tmpaccounts = accountList tmpaccounts.push(hash) - accounts = tmpaccounts + accountList = tmpaccounts tmpAccount.path = appSettings.path + "/accounts/" + hash tmpAccount.url = url @@ -64,13 +60,18 @@ ApplicationWindow Nextcloud.deleteAppPassword(appSettings.value("accounts/" + hash + "/password"), appSettings.value("accounts/" + hash + "/username"), appSettings.value("accounts/" + hash + "/url")) - var tmpaccounts = accounts + var tmpaccounts = accountList tmpaccounts.pop(hash) - accounts = tmpaccounts + accountList = tmpaccounts tmpAccount.path = appSettings.path + "/accounts/" + hash tmpAccount.clear() - currentAccount = accounts[-1] + if (accountList[-1]) { + currentAccount = accountList[-1] + } + else { + currentAccount = "" + } } } @@ -78,7 +79,10 @@ ApplicationWindow id: account Connections { target: appSettings - onCurrentAccountChanged: account.path = appSettings.path + "/accounts/" + appSettings.currentAccount + onCurrentAccountChanged: { + account.path = appSettings.path + "/accounts/" + appSettings.currentAccount + console.log("Current account: " + account.username + "@" + account.url) + } } property url url: value("url", "", String) diff --git a/qml/pages/NotesPage.qml b/qml/pages/NotesPage.qml index 1e464b7..1768032 100644 --- a/qml/pages/NotesPage.qml +++ b/qml/pages/NotesPage.qml @@ -1,13 +1,14 @@ import QtQuick 2.2 import Sailfish.Silica 1.0 import harbour.nextcloudapi 1.0 +import harbour.nextcloudapi.notes 1.0 Page { id: page onStatusChanged: { if (status === PageStatus.Activating) { - if (appSettings.accounts.length <= 0) { + if (appSettings.accountList.length <= 0) { addAccountHint.restart() } else { @@ -35,13 +36,13 @@ Page { text: qsTr("Add note") visible: appSettings.currentAccount !== "" enabled: Nextcloud.networkAccessible - onClicked: Nextcloud.createNote( { 'content': "", 'modified': new Date().valueOf() / 1000 } ) + onClicked: Notes.createNote( { 'content': "", 'modified': new Date().valueOf() / 1000 } ) } MenuItem { text: Nextcloud.networkAccessible && !Nextcloud.busy ? qsTr("Reload") : qsTr("Updating...") visible: appSettings.currentAccount !== "" enabled: Nextcloud.networkAccessible && !Nextcloud.busy - onClicked: Nextcloud.getAllNotes() + onClicked: Notes.getAllNotes() } MenuLabel { visible: appSettings.currentAccount !== "" @@ -227,7 +228,7 @@ Page { ViewPlaceholder { id: noLoginPlaceholder - enabled: appSettings.accounts.length <= 0 + enabled: appSettings.accountList.length <= 0 text: qsTr("No account yet") hintText: qsTr("Got to the settings to add an account") } diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml index 13d88c0..34a9151 100644 --- a/qml/pages/SettingsPage.qml +++ b/qml/pages/SettingsPage.qml @@ -32,7 +32,7 @@ Page { } Label { id: noAccountsLabel - visible: appSettings.accounts.length <= 0 + visible: appSettings.accountList.length <= 0 text: qsTr("No Nextcloud account yet") font.pixelSize: Theme.fontSizeLarge color: Theme.secondaryHighlightColor @@ -43,7 +43,7 @@ Page { } Repeater { id: accountRepeater - model: appSettings.accounts + model: appSettings.accountList delegate: ListItem { id: accountListItem @@ -53,15 +53,17 @@ Page { ConfigurationGroup { id: settingsAccount path: appSettings.path + "/accounts/" + modelData - onPathChanged: console.log(path) - Component.onCompleted: { - accountTextSwitch.text = value("name", qsTr("Account %1").arg(index+1)) - accountTextSwitch.description = value("username") + "@" + value("url") - } + property url url: value("url", "", String) + property string username: value("username", "", String) + property string passowrd: value("password", "", String) + property string name: value("name", qsTr("Account %1").arg(index+1), String) + property var update: value("update", new Date(0), Date) } TextSwitch { id: accountTextSwitch + text: settingsAccount.name + description: settingsAccount.username + "@" + settingsAccount.url automaticCheck: false checked: modelData === appSettings.currentAccount onClicked: { diff --git a/src/apps/abstractnextcloudapp.h b/src/apps/abstractnextcloudapp.h index 9342e96..8cfcc7f 100644 --- a/src/apps/abstractnextcloudapp.h +++ b/src/apps/abstractnextcloudapp.h @@ -13,9 +13,9 @@ class AbstractNextcloudApp : public QObject { public: AbstractNextcloudApp(QObject *parent = nullptr, QString name = QString(), NextcloudApi* api = nullptr) : QObject(parent), m_appName(name), m_api(api) { - connect(this, SIGNAL(capabilitiesChanged(QJsonObject*)), this, SLOT(updateCapabilities(QJsonObject*))); + //connect(this, SIGNAL(capabilitiesChanged(QJsonObject*)), this, SLOT(updateCapabilities(QJsonObject*))); connect(m_api, SIGNAL(capabilitiesChanged(QJsonObject*)), this, SLOT(updateApiCapabilities(QJsonObject*))); - connect(this, SIGNAL(replyReceived(QNetworkReply*)), this, SLOT(updateReply(QNetworkReply*))); + //connect(this, SIGNAL(replyReceived(QNetworkReply*)), this, SLOT(updateReply(QNetworkReply*))); connect(m_api, SIGNAL(apiFinished(QNetworkReply*)), this, SLOT(updateApiReply(QNetworkReply*))); } diff --git a/src/apps/notes/notesapp.cpp b/src/apps/notes/notesapp.cpp index 4bfb5c6..a04175d 100644 --- a/src/apps/notes/notesapp.cpp +++ b/src/apps/notes/notesapp.cpp @@ -3,6 +3,8 @@ NotesApp::NotesApp(QObject *parent, NextcloudApi* api) : AbstractNextcloudApp(parent, "notes", api) { m_notesProxy.setSourceModel(&m_notesModel); + connect(this, SIGNAL(capabilitiesChanged(QJsonObject*)), this, SLOT(updateCapabilities(QJsonObject*))); + connect(this, SIGNAL(replyReceived(QNetworkReply*)), this, SLOT(updateReply(QNetworkReply*))); } // QML singleton @@ -41,12 +43,28 @@ bool NotesApp::getAllNotes(const QStringList& exclude) { QUrlQuery query; if (!exclude.isEmpty()) query.addQueryItem(EXCLUDE_QUERY, exclude.join(",")); - return m_api->get(NOTES_APP_ENDPOINT, query); + QNetworkReply* reply = m_api->get(QString(NOTES_APP_ENDPOINT).append("/notes"), query); + if (reply->error() == QNetworkReply::NoError) { + m_replies << reply; + return true; + } + else { + reply->deleteLater(); + return false; + } } bool NotesApp::getNote(const int id) { qDebug() << "Getting note: " << id; - return m_api->get(NOTES_APP_ENDPOINT + QString("/%1").arg(id)); + QNetworkReply* reply = m_api->get(QString(NOTES_APP_ENDPOINT).append("/notes/%1").arg(id)); + if (reply->error() == QNetworkReply::NoError) { + m_replies << reply; + return true; + } + else { + reply->deleteLater(); + return false; + } } bool NotesApp::createNote(const QJsonObject& note, bool local) { @@ -56,7 +74,15 @@ bool NotesApp::createNote(const QJsonObject& note, bool local) { m_notes.append(value); } if (!local) { - return m_api->post(NOTES_APP_ENDPOINT, QJsonDocument(note).toJson()); + QNetworkReply* reply = m_api->post(QString(NOTES_APP_ENDPOINT).append("/notes"), QJsonDocument(note).toJson()); + if (reply->error() == QNetworkReply::NoError) { + m_replies << reply; + return true; + } + else { + reply->deleteLater(); + return false; + } } return true; } @@ -85,7 +111,15 @@ bool NotesApp::updateNote(const int id, const QJsonObject& note, bool local) { } } if (!local) { - return m_api->put(NOTES_APP_ENDPOINT + QString("/%1").arg(id), QJsonDocument(note).toJson()); + QNetworkReply* reply = m_api->put(QString(NOTES_APP_ENDPOINT).append("/notes/%1").arg(id), QJsonDocument(note).toJson()); + if (reply->error() == QNetworkReply::NoError) { + m_replies << reply; + return true; + } + else { + reply->deleteLater(); + return false; + } } return done; } @@ -102,7 +136,15 @@ bool NotesApp::deleteNote(const int id, bool local) { } } if (!local) { - return m_api->del(NOTES_APP_ENDPOINT + QString("/%1").arg(id)); + QNetworkReply* reply = m_api->del(QString(NOTES_APP_ENDPOINT).append("/notes/%1").arg(id)); + if (reply->error() == QNetworkReply::NoError) { + m_replies << reply; + return true; + } + else { + reply->deleteLater(); + return false; + } } return done; } @@ -112,7 +154,9 @@ void NotesApp::updateReply(QNetworkReply* reply) { qDebug() << reply->error() << reply->errorString(); QByteArray data = reply->readAll(); + //qDebug() << data; QJsonDocument json = QJsonDocument::fromJson(data); + qDebug() << json; if (json.isObject()) { QJsonObject obj = json.object(); updateNote(obj.value("id").toInt(), obj, true); diff --git a/src/nextcloudapi.cpp b/src/nextcloudapi.cpp index aff493a..01c7b82 100644 --- a/src/nextcloudapi.cpp +++ b/src/nextcloudapi.cpp @@ -351,9 +351,6 @@ void NextcloudApi::replyFinished(QNetworkReply* reply) { qDebug() << reply->error() << reply->errorString(); qDebug() << reply->url().toDisplayString(); - QByteArray data = reply->readAll(); - QJsonDocument json = QJsonDocument::fromJson(data); - //qDebug() << data; switch (reply->error()) { case QNetworkReply::NoError: @@ -362,34 +359,32 @@ void NextcloudApi::replyFinished(QNetworkReply* reply) { case QNetworkAccessManager::GetOperation: if (reply->url().toString().endsWith(STATUS_ENDPOINT)) { qDebug() << "Nextcloud status.php"; - updateStatus(json.object()); + updateStatus(QJsonDocument::fromJson(reply->readAll()).object()); } else if (reply->url().toString().endsWith(GET_APPPASSWORD_ENDPOINT)) { qDebug() << "App password received"; - updateAppPassword(json.object()); + updateAppPassword(QJsonDocument::fromJson(reply->readAll()).object()); } else if (reply->url().toString().contains(QString(USER_METADATA_ENDPOINT).remove(QRegExp("/%[0-9]")))) { qDebug() << "User metadata for" << reply->url().toString().split('/').last() << "received"; - updateUserMeta(json.object()); + updateUserMeta(QJsonDocument::fromJson(reply->readAll()).object()); } else if (reply->url().toString().endsWith(LIST_USERS_ENDPOINT)) { qDebug() << "User list received"; - updateUserList(json.object()); + updateUserList(QJsonDocument::fromJson(reply->readAll()).object()); } else if (reply->url().toString().endsWith(CAPABILITIES_ENDPOINT)) { qDebug() << "Capabilites received"; - updateCapabilities(json.object()); + updateCapabilities(QJsonDocument::fromJson(reply->readAll()).object()); } else if (reply->url().toString().endsWith(USER_NOTIFICATION_ENDPOINT)) { qDebug() << "Notifications are not yet implemented!"; - qDebug() << json.object().value("ocs").toObject().value("data").toArray(); + qDebug() << QJsonDocument::fromJson(reply->readAll()).object().value("ocs").toObject().value("data").toArray(); } else { qDebug() << "GET reply received"; break; } - m_replies.removeOne(reply); - reply->deleteLater(); break; case QNetworkAccessManager::PutOperation: if (reply->url().toString().endsWith(DIRECT_DOWNLOAD_ENDPOINT)) { @@ -399,43 +394,37 @@ void NextcloudApi::replyFinished(QNetworkReply* reply) { qDebug() << "PUT reply received"; break; } - m_replies.removeOne(reply); - reply->deleteLater(); break; case QNetworkAccessManager::PostOperation: if (reply->url().toString().endsWith(LOGIN_FLOWV2_ENDPOINT)) { qDebug() << "Login Flow v2 initiated."; - updateLoginFlow(json.object()); + updateLoginFlow(QJsonDocument::fromJson(reply->readAll()).object()); } else if (reply->url() == m_pollUrl) { qDebug() << "Login Flow v2 finished."; - updateLoginCredentials(json.object()); + updateLoginCredentials(QJsonDocument::fromJson(reply->readAll()).object()); } else { qDebug() << "POST reply received"; break; } - m_replies.removeOne(reply); - reply->deleteLater(); break; case QNetworkAccessManager::DeleteOperation: if (reply->url().toString().endsWith(DEL_APPPASSWORD_ENDPOINT)) { - deleteAppPassword(json.object()); + deleteAppPassword(QJsonDocument::fromJson(reply->readAll()).object()); } else { qDebug() << "DELETE reply received"; break; } - m_replies.removeOne(reply); - reply->deleteLater(); break; default: qDebug() << "Unknown reply received:" << reply->operation() << reply->url(); - m_replies.removeOne(reply); - reply->deleteLater(); break; } emit apiFinished(reply); + m_replies.removeOne(reply); + reply->deleteLater(); break; case QNetworkReply::AuthenticationRequiredError: qDebug() << reply->errorString(); diff --git a/translations/harbour-nextcloudnotes.ts b/translations/harbour-nextcloudnotes.ts index 462abe8..d3d69a4 100644 --- a/translations/harbour-nextcloudnotes.ts +++ b/translations/harbour-nextcloudnotes.ts @@ -407,97 +407,97 @@ NotesPage - + Settings - + Add note - + Reload - + Updating... - + Last update - + never - + Nextcloud Notes - + Modified - + Delete - + Deleting note - + Loading notes... - + No account yet - + Got to the settings to add an account - + No notes yet - + Pull down to add a note - + No result - + Try another query - + An error occurred - + Open the settings to configure your Nextcloud accounts @@ -525,182 +525,182 @@ - + Account %1 - + Edit - + Delete - + Deleting account - + Add account - + Synchronization - + Auto-Sync - + Periodically pull notes from the server - + Disabled - + every - + Minutes - + Seconds - + The Answer is 42 - + Congratulation you found the Answer to the Ultimate Question of Life, The Universe, and Everything! - + Appearance - + No sorting - + Favorites on top - + Show notes marked as favorite above the others - + Reset - + Reset app settings - + Cleared app data - + Resetting the app wipes all application data from the device! This includes offline synced notes, app settings and accounts. - + Last edited - + Category - + Title alphabetically - + Sort notes by - + This will also change how the notes are grouped - + Show separator - + Show a separator line between the notes - + lines - + Number of lines in the preview - + Editing - + Monospaced font - + Use a monospeced font to edit a note - + Capital 'X' in checkboxes - + For interoperability with other apps such as Joplin @@ -912,27 +912,27 @@ You can also use other markdown syntax inside them. harbour-nextcloudnotes - + Notes - + Offline - + Synced - + API error - + File error