diff --git a/harbour-nextcloudnotes.pro b/harbour-nextcloudnotes.pro index fea69f6..91b80aa 100644 --- a/harbour-nextcloudnotes.pro +++ b/harbour-nextcloudnotes.pro @@ -27,6 +27,8 @@ SOURCES += src/harbour-nextcloudnotes.cpp \ DISTFILES += qml/harbour-nextcloudnotes.qml \ qml/cover/CoverPage.qml \ + qml/img/nextcloud-logo-dark.png \ + qml/img/nextcloud-logo-light.png \ qml/pages/LoginPage.qml \ rpm/harbour-nextcloudnotes.changes.run.in \ rpm/harbour-nextcloudnotes.changes \ diff --git a/icons/108x108/harbour-nextcloudnotes.png b/icons/108x108/harbour-nextcloudnotes.png index ab10628..3de4f51 100644 Binary files a/icons/108x108/harbour-nextcloudnotes.png and b/icons/108x108/harbour-nextcloudnotes.png differ diff --git a/icons/128x128/harbour-nextcloudnotes.png b/icons/128x128/harbour-nextcloudnotes.png index 54375c5..683925b 100644 Binary files a/icons/128x128/harbour-nextcloudnotes.png and b/icons/128x128/harbour-nextcloudnotes.png differ diff --git a/icons/172x172/harbour-nextcloudnotes.png b/icons/172x172/harbour-nextcloudnotes.png index 36eee58..a74aafe 100644 Binary files a/icons/172x172/harbour-nextcloudnotes.png and b/icons/172x172/harbour-nextcloudnotes.png differ diff --git a/icons/86x86/harbour-nextcloudnotes.png b/icons/86x86/harbour-nextcloudnotes.png index ad316d6..90a6dce 100644 Binary files a/icons/86x86/harbour-nextcloudnotes.png and b/icons/86x86/harbour-nextcloudnotes.png differ diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml index 0a4ed9f..e4d0bc3 100644 --- a/qml/cover/CoverPage.qml +++ b/qml/cover/CoverPage.qml @@ -4,7 +4,7 @@ import Sailfish.Silica 1.0 CoverBackground { CoverPlaceholder { - icon.source: "../img/nextcloud-logo-transparent.png" + icon.source: Theme.colorScheme === Theme.DarkOnLight ? "../img/nextcloud-logo-dark.png" : "../img/nextcloud-logo-light.png" icon.width: parent.width icon.fillMode: Image.PreserveAspectFit text: qsTr("Notes") diff --git a/qml/img/nextcloud-logo-dark.png b/qml/img/nextcloud-logo-dark.png new file mode 100644 index 0000000..e6a599d Binary files /dev/null and b/qml/img/nextcloud-logo-dark.png differ diff --git a/qml/img/nextcloud-logo-transparent.png b/qml/img/nextcloud-logo-light.png similarity index 100% rename from qml/img/nextcloud-logo-transparent.png rename to qml/img/nextcloud-logo-light.png diff --git a/src/harbour-nextcloudnotes.cpp b/src/harbour-nextcloudnotes.cpp index f2c1e52..00550a0 100644 --- a/src/harbour-nextcloudnotes.cpp +++ b/src/harbour-nextcloudnotes.cpp @@ -26,10 +26,8 @@ int main(int argc, char *argv[]) notesProxyModel->setFilterRole(NotesModel::ContentRole); notesProxyModel->setSourceModel(notesModel); - //NotesStore* notesStore = new NotesStore; NotesApi* notesApi = new NotesApi; notesModel->setNotesApi(notesApi); - //notesModel->setNotesStore(notesStore); QQuickView* view = SailfishApp::createView(); #ifdef QT_DEBUG @@ -39,7 +37,6 @@ int main(int argc, char *argv[]) #endif view->rootContext()->setContextProperty("notesModel", notesModel); view->rootContext()->setContextProperty("notesProxyModel", notesProxyModel); - //view->rootContext()->setContextProperty("notesStore", notesStore); view->rootContext()->setContextProperty("notesApi", notesApi); view->setSource(SailfishApp::pathTo("qml/harbour-nextcloudnotes.qml")); @@ -48,7 +45,6 @@ int main(int argc, char *argv[]) int retval = app->exec(); notesApi->deleteLater(); - //notesStore->deleteLater(); notesProxyModel->deleteLater(); notesModel->deleteLater(); return retval; diff --git a/src/notesapi.cpp b/src/notesapi.cpp index 4842786..a1e4319 100644 --- a/src/notesapi.cpp +++ b/src/notesapi.cpp @@ -12,6 +12,7 @@ NotesApi::NotesApi(const QString statusEndpoint, const QString loginEndpoint, co // TODO verify connections (also in destructor) m_loginPollTimer.setInterval(POLL_INTERVALL); connect(&m_loginPollTimer, SIGNAL(timeout()), this, SLOT(pollLoginUrl())); + setCababilitiesStatus(CapabilitiesStatus::CapabilitiesUnknown); setNcStatusStatus(NextcloudStatus::NextcloudUnknown); setLoginStatus(LoginStatus::LoginUnknown); m_ncStatusStatus = NextcloudStatus::NextcloudUnknown; @@ -29,6 +30,7 @@ NotesApi::NotesApi(const QString statusEndpoint, const QString loginEndpoint, co m_request.setHeader(QNetworkRequest::UserAgentHeader, QGuiApplication::applicationDisplayName() + " " + QGuiApplication::applicationVersion() + " - " + QSysInfo::machineHostName()); m_request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/x-www-form-urlencoded").toUtf8()); m_request.setRawHeader("OCS-APIREQUEST", "true"); + m_request.setRawHeader("Accept", "application/json"); m_authenticatedRequest = m_request; m_authenticatedRequest.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json").toUtf8()); } @@ -374,6 +376,8 @@ void NotesApi::replyFinished(QNetworkReply *reply) { emit noteError(CommunicationError); QByteArray data = reply->readAll(); + //qDebug() << data; + qDebug() << reply->rawHeader("X-Notes-API-Versions"); QJsonDocument json = QJsonDocument::fromJson(data); if (m_getAllNotesReplies.contains(reply)) { @@ -488,21 +492,25 @@ QUrl NotesApi::apiEndpointUrl(const QString endpoint) const { } void NotesApi::updateNcStatus(const QJsonObject &status) { - if (m_status_installed != status.value("installed").toBool()) { - m_status_installed = status.value("installed").toBool(); + bool tmpStatus = status.value("installed").toBool(); + if (m_status_installed != tmpStatus) { + m_status_installed = tmpStatus; emit statusInstalledChanged(m_status_installed); } - if (m_status_maintenance != status.value("maintenance").toBool()) { - m_status_maintenance = status.value("maintenance").toBool(); + bool tmpMaintenance = status.value("maintenance").toBool(); + if (m_status_maintenance != tmpMaintenance) { + m_status_maintenance = tmpMaintenance; emit statusMaintenanceChanged(m_status_maintenance); } - if (m_status_needsDbUpgrade != status.value("needsDbUpgrade").toBool()) { - m_status_needsDbUpgrade = status.value("needsDbUpgrade").toBool(); + bool tmpNeedsDbUpgrade = status.value("needsDbUpgrade").toBool(); + if (m_status_needsDbUpgrade != tmpNeedsDbUpgrade) { + m_status_needsDbUpgrade = tmpNeedsDbUpgrade; emit statusNeedsDbUpgradeChanged(m_status_needsDbUpgrade); } - if (m_status_version != status.value("version").toString()) { - m_status_version = status.value("version").toString(); - emit statusVersionChanged(m_status_version); + QVersionNumber tmpVersion = QVersionNumber::fromString(status.value("version").toString()); + if (m_status_version != tmpVersion) { + m_status_version = tmpVersion; + emit statusVersionChanged(m_status_version.toString()); } if (m_status_versionstring != status.value("versionstring").toString()) { m_status_versionstring = status.value("versionstring").toString(); @@ -526,6 +534,15 @@ void NotesApi::updateNcStatus(const QJsonObject &status) { setNcStatusStatus(NextcloudStatus::NextcloudSuccess); } +void NotesApi::setCababilitiesStatus(CapabilitiesStatus status, bool *changed) { + if (status != m_capabilitiesStatus) { + if (changed) + *changed = true; + m_capabilitiesStatus = status; + emit capabilitiesStatusChanged(m_capabilitiesStatus); + } +} + void NotesApi::setNcStatusStatus(NextcloudStatus status, bool *changed) { if (status != m_ncStatusStatus) { if (changed) diff --git a/src/notesapi.h b/src/notesapi.h index f2c6446..3c288ae 100644 --- a/src/notesapi.h +++ b/src/notesapi.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -15,12 +16,15 @@ #define NOTES_ENDPOINT "/index.php/apps/notes/api/v0.2/notes" #define OCS_ENDPOINT "/ocs/v1.php/cloud" #define EXCLUDE_QUERY "exclude=" +#define PURGE_QUERY "purgeBefore=" +#define ETAG_HEADER "If-None-Match" #define POLL_INTERVALL 5000 class NotesApi : public QObject { Q_OBJECT + // Generic API properties Q_PROPERTY(bool verifySsl READ verifySsl WRITE setVerifySsl NOTIFY verifySslChanged) Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(QString server READ server WRITE setServer NOTIFY serverChanged) @@ -31,11 +35,20 @@ class NotesApi : public QObject Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) + // Status information Q_PROPERTY(bool urlValid READ urlValid NOTIFY urlValidChanged) Q_PROPERTY(bool networkAccessible READ networkAccessible NOTIFY networkAccessibleChanged) Q_PROPERTY(QDateTime lastSync READ lastSync NOTIFY lastSyncChanged) Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) + // Nextcloud capabilities + Q_PROPERTY(CapabilitiesStatus capabilitiesStatus READ capabilitiesStatus NOTIFY capabilitiesStatusChanged) + //Q_PROPERTY(bool notesAppInstalled READ notesAppInstalled NOTIFY notesAppInstalledChanged) + //Q_PROPERTY(QStringList notesAppApiVersions READ notesAppApiVersions NOTIFY notesAppApiVersionsChanged) + //Q_PROPERTY(QString notesAppApiMaxVersion READ notesAppApiMaxVersion NOTIFY notesAppApiMaxVersionChanged) + //Q_PROPERTY(QString notesAppApiMinVersion READ notesAppApiMinVersion NOTIFY notesAppApiMinVersionChanged) + + // Nextcloud status (status.php) Q_PROPERTY(NextcloudStatus ncStatusStatus READ ncStatusStatus NOTIFY ncStatusStatusChanged) Q_PROPERTY(bool statusInstalled READ statusInstalled NOTIFY statusInstalledChanged) Q_PROPERTY(bool statusMaintenance READ statusMaintenance NOTIFY statusMaintenanceChanged) @@ -46,6 +59,7 @@ class NotesApi : public QObject Q_PROPERTY(QString statusProductName READ statusProductName NOTIFY statusProductNameChanged) Q_PROPERTY(bool statusExtendedSupport READ statusExtendedSupport NOTIFY statusExtendedSupportChanged) + // Login status Q_PROPERTY(LoginStatus loginStatus READ loginStatus NOTIFY loginStatusChanged) Q_PROPERTY(QUrl loginUrl READ loginUrl NOTIFY loginUrlChanged) @@ -57,6 +71,34 @@ public: QObject *parent = nullptr); virtual ~NotesApi(); + enum CapabilitiesStatus { + CapabilitiesUnknown, // Initial unknown state + CapabilitiesBusy, // Gettin information + CapabilitiesSuccess, // Capabilities successfully read + CapabilitiesStatusFailed // Faild to retreive capabilities + }; + Q_ENUM(CapabilitiesStatus) + + enum NextcloudStatus { + NextcloudUnknown, // Initial unknown state + NextcloudBusy, // Getting information from the nextcloud server + NextcloudSuccess, // Got information about the nextcloud server + NextcloudFailed // Error getting information from the nextcloud server, see error() + }; + Q_ENUM(NextcloudStatus) + + enum LoginStatus { + LoginUnknown, // Inital unknown state + LoginLegacyReady, // Ready for legacy login + LoginFlowV2Initiating, // Initiating login flow v2 + LoginFlowV2Polling, // Ready for login flow v2 + LoginFlowV2Success, // Finished login flow v2 + LoginFlowV2Failed, // An error in login flow v2 + LoginSuccess, // Login has been verified successfull + LoginFailed // Login has failed, see error() + }; + Q_ENUM(LoginStatus) + bool verifySsl() const { return m_authenticatedRequest.sslConfiguration().peerVerifyMode() == QSslSocket::VerifyPeer; } void setVerifySsl(bool verify); @@ -92,30 +134,13 @@ public: bool busy() const; - enum NextcloudStatus { - NextcloudUnknown, // Nothing known about the nextcloud server - NextcloudBusy, // Getting information from the nextcloud server - NextcloudSuccess, // Got information about the nextcloud server - NextcloudFailed // Error getting information from the nextcloud server, see error() - }; - Q_ENUM(NextcloudStatus) - enum LoginStatus { - LoginUnknown, // Inital unknown state - LoginLegacyReady, // Ready for legacy login - LoginFlowV2Initiating, // Initiating login flow v2 - LoginFlowV2Polling, // Ready for login flow v2 - LoginFlowV2Success, // Finished login flow v2 - LoginFlowV2Failed, // An error in login flow v2 - LoginSuccess, // Login has been verified successfull - LoginFailed // Login has failed, see error() - }; - Q_ENUM(LoginStatus) + CapabilitiesStatus capabilitiesStatus() const { return m_capabilitiesStatus; } NextcloudStatus ncStatusStatus() const { return m_ncStatusStatus; } bool statusInstalled() const { return m_status_installed; } bool statusMaintenance() const { return m_status_maintenance; } bool statusNeedsDbUpgrade() const { return m_status_needsDbUpgrade; } - QString statusVersion() const { return m_status_version; } + QString statusVersion() const { return m_status_version.toString(); } QString statusVersionString() const { return m_status_versionstring; } QString statusEdition() const { return m_status_edition; } QString statusProductName() const { return m_status_productname; } @@ -169,6 +194,8 @@ signals: void lastSyncChanged(QDateTime lastSync); void busyChanged(bool busy); + void capabilitiesStatusChanged(CapabilitiesStatus status); + void ncStatusStatusChanged(NextcloudStatus status); void statusInstalledChanged(bool installed); void statusMaintenanceChanged(bool maintenance); @@ -204,6 +231,9 @@ private: QNetworkRequest m_ocsRequest; QUrl apiEndpointUrl(const QString endpoint) const; + CapabilitiesStatus m_capabilitiesStatus; + void setCababilitiesStatus(CapabilitiesStatus status, bool *changed = NULL); + // Nextcloud status.php const QString m_statusEndpoint; QVector m_statusReplies; @@ -213,7 +243,8 @@ private: bool m_status_installed; bool m_status_maintenance; bool m_status_needsDbUpgrade; - QString m_status_version; + QVersionNumber m_status_version; + //QString m_status_version; QString m_status_versionstring; QString m_status_edition; QString m_status_productname; @@ -238,6 +269,7 @@ private: // Nextcloud Notes API - https://github.com/nextcloud/notes/wiki/Notes-0.2 const QString m_notesEndpoint; + QVersionNumber m_notesApiVersion; QVector m_getAllNotesReplies; QVector m_getNoteReplies; QVector m_createNoteReplies; diff --git a/src/notesmodel.h b/src/notesmodel.h index 2bbfaed..b9aee8f 100644 --- a/src/notesmodel.h +++ b/src/notesmodel.h @@ -103,7 +103,6 @@ signals: private: const static QHash m_roleNames; - //QMap m_files; QDir m_fileDir; const static QString m_fileSuffix; diff --git a/translations/harbour-nextcloudnotes.ts b/translations/harbour-nextcloudnotes.ts index a92b47d..af5acc2 100644 --- a/translations/harbour-nextcloudnotes.ts +++ b/translations/harbour-nextcloudnotes.ts @@ -316,32 +316,32 @@ NotesApi - + No error - + No network connection available - + Failed to communicate with the Nextcloud server - + An error occured while establishing an encrypted connection - + Could not authenticate to the Nextcloud instance - + Unknown error @@ -349,97 +349,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