Used new state info in the Login Dialog
This commit is contained in:
parent
00921391a2
commit
9616dfc6be
9 changed files with 307 additions and 293 deletions
|
@ -8,13 +8,25 @@ import "pages"
|
|||
ApplicationWindow
|
||||
{
|
||||
id: appWindow
|
||||
/*
|
||||
|
||||
//property NotesApi notesApi
|
||||
|
||||
Component.onCompleted: {
|
||||
notesApi.scheme = account.allowUnecrypted ? "http" : "https"
|
||||
notesApi.host = account.server
|
||||
notesApi.username = account.username
|
||||
notesApi.password = account.password
|
||||
notesApi.sslVerify = !account.doNotVerifySsl
|
||||
notesApi.dataFile = appSettings.currentAccount !== "" ? StandardPaths.data + "/" + appSettings.currentAccount + ".json" : ""
|
||||
|
||||
}
|
||||
|
||||
ConfigurationValue {
|
||||
id: accounts
|
||||
key: appSettings.path + "/accountIDs"
|
||||
defaultValue: [ ]
|
||||
}
|
||||
*/
|
||||
|
||||
ConfigurationGroup {
|
||||
id: account
|
||||
path: "/apps/harbour-nextcloudnotes/accounts/" + appSettings.currentAccount
|
||||
|
@ -129,13 +141,16 @@ ApplicationWindow
|
|||
|
||||
NotesApi {
|
||||
id: notesApi
|
||||
|
||||
scheme: account.allowUnecrypted ? "http" : "https"
|
||||
host: account.server
|
||||
username: account.username
|
||||
password: account.password
|
||||
sslVerify: !account.doNotVerifySsl
|
||||
dataFile: appSettings.currentAccount !== "" ? StandardPaths.data + "/" + appSettings.currentAccount + ".json" : ""
|
||||
Component.onCompleted: getAllNotes()
|
||||
Component.onCompleted: {
|
||||
getAllNotes()
|
||||
}
|
||||
onNetworkAccessibleChanged: {
|
||||
console.log("Device is " + (networkAccessible ? "online" : "offline"))
|
||||
networkAccessible ? offlineNotification.close(Notification.Closed) : offlineNotification.publish()
|
||||
|
@ -152,6 +167,7 @@ ApplicationWindow
|
|||
}
|
||||
|
||||
initialPage: Component { NotesPage { } }
|
||||
//initialPage: Component { LoginPage { } } // testing
|
||||
cover: Qt.resolvedUrl("cover/CoverPage.qml")
|
||||
allowedOrientations: defaultAllowedOrientations
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import QtQuick 2.2
|
||||
import QtQuick 2.5
|
||||
import Sailfish.Silica 1.0
|
||||
import Nemo.Configuration 1.0
|
||||
import harbour.nextcloudnotes.notesapi 1.0
|
||||
|
@ -8,17 +8,19 @@ Page {
|
|||
|
||||
property string accountId
|
||||
|
||||
property bool legacyLoginPossible: false
|
||||
property bool flowLoginV2Possible: false
|
||||
|
||||
ConfigurationGroup {
|
||||
id: account
|
||||
path: "/apps/harbour-nextcloudnotes/accounts/" + accountId
|
||||
Component.onCompleted: {
|
||||
//nameField.text = value("name", "", String)
|
||||
pageHeader.title = value("name", qsTr("Nextcloud Login"), String)
|
||||
serverField.text = "https://" + value("server", "", String)
|
||||
usernameField.text = value("username", "", String)
|
||||
passwordField.text = value("password", "", String)
|
||||
unsecureConnectionTextSwitch.checked = value("unsecureConnection", false, Boolean)
|
||||
unencryptedConnectionTextSwitch.checked = value("unencryptedConnection", false, Boolean)
|
||||
serverField.text === "https://" ? serverField.focus = true : (usernameField.text === "" ? usernameField.focus = true : (passwordField.text === "" ? passwordField.focus = true : passwordField.focus = false))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,59 +31,66 @@ Page {
|
|||
|
||||
Connections {
|
||||
target: notesApi
|
||||
onStatusStatusChanged: {
|
||||
switch(notesApi.statusStatus) {
|
||||
case NotesApi.StatusNone:
|
||||
console.log("Status: none")
|
||||
break;
|
||||
case NotesApi.StatusInitiated:
|
||||
console.log("Status: initiated")
|
||||
break;
|
||||
case NotesApi.StatusBusy:
|
||||
console.log("Status: busy")
|
||||
apiProgressBar.label = qsTr("Verifying server address")
|
||||
break;
|
||||
case NotesApi.StatusFinished:
|
||||
console.log("Status: finished")
|
||||
apiProgressBar.label = qsTr("Server address is valid")
|
||||
break
|
||||
case NotesApi.StatusError:
|
||||
console.log("Status: error")
|
||||
apiProgressBar.label = qsTr("Please enter a valid server address")
|
||||
break;
|
||||
}
|
||||
console.log(notesApi.statusStatus)
|
||||
}
|
||||
onLoginStatusChanged: {
|
||||
console.log(notesApi.loginStatus)
|
||||
switch(notesApi.statusStatus) {
|
||||
case NotesApi.StatusNone:
|
||||
console.log("Login: none")
|
||||
break;
|
||||
case NotesApi.StatusInitiated:
|
||||
console.log("Login: initiated")
|
||||
apiProgressBar.label = qsTr("Initiating login")
|
||||
break;
|
||||
case NotesApi.StatusBusy:
|
||||
console.log("Login: busy")
|
||||
apiProgressBar.label = qsTr("Follow the login procedure in the browser")
|
||||
break;
|
||||
case NotesApi.StatusFinished:
|
||||
console.log("Login: finished")
|
||||
apiProgressBar.label = qsTr("Login successfull")
|
||||
break
|
||||
case NotesApi.StatusError:
|
||||
console.log("Login: error")
|
||||
apiProgressBar.label = qsTr("Error while loggin in")
|
||||
break;
|
||||
}
|
||||
}
|
||||
onStatusInstalledChanged: {
|
||||
if (notesApi.statusInstalled) {
|
||||
console.log("Nextcloud instance found")
|
||||
}
|
||||
if (notesApi.statusInstalled)
|
||||
serverField.focus = false
|
||||
}
|
||||
onStatusVersionChanged: {
|
||||
if (notesApi.statusVersion) {
|
||||
if (notesApi.statusVersion.split('.')[0] >= 16) {
|
||||
legacyLoginPossible = false
|
||||
flowLoginV2Possible = true
|
||||
console.log("Using Flow Login v2")
|
||||
}
|
||||
else {
|
||||
legacyLoginPossible = true
|
||||
flowLoginV2Possible = false
|
||||
console.log("Using Legacy Login")
|
||||
}
|
||||
}
|
||||
else {
|
||||
legacyLoginPossible = false
|
||||
flowLoginV2Possible = false
|
||||
}
|
||||
}
|
||||
onStatusVersionStringChanged: {
|
||||
if (notesApi.statusVersionString)
|
||||
console.log("Nextcloud " + notesApi.statusVersionString)
|
||||
}
|
||||
onStatusProductNameChanged: {
|
||||
if (notesApi.statusProductName) {
|
||||
pageHeader.title = notesApi.statusProductName
|
||||
account.setValue("name", notesApi.statusProductName)
|
||||
}
|
||||
}
|
||||
onLoginStatusChanged: {
|
||||
switch(notesApi.loginStatus) {
|
||||
case NotesApi.LoginLegacyReady:
|
||||
apiProgressBar.label = qsTr("Enter your credentials")
|
||||
break;
|
||||
//case NotesApi.LoginFlowV2Initiating:
|
||||
// break;
|
||||
case NotesApi.LoginFlowV2Polling:
|
||||
apiProgressBar.label = qsTr("Follow the instructions in the browser")
|
||||
break;
|
||||
case NotesApi.LoginFlowV2Success:
|
||||
notesApi.verifyLogin()
|
||||
break;
|
||||
case NotesApi.LoginFlowV2Failed:
|
||||
apiProgressBar.label = qsTr("Login failed!")
|
||||
break
|
||||
case NotesApi.LoginSuccess:
|
||||
apiProgressBar.label = qsTr("Login successfull!")
|
||||
account.setValue("username", notesApi.username)
|
||||
account.setValue("password", notesApi.password)
|
||||
break;
|
||||
case NotesApi.LoginFailed:
|
||||
apiProgressBar.label = qsTr("Login failed!")
|
||||
break;
|
||||
default:
|
||||
apiProgressBar.label = ""
|
||||
break;
|
||||
}
|
||||
}
|
||||
onLoginUrlChanged: {
|
||||
if (notesApi.loginUrl) {
|
||||
|
@ -92,8 +101,11 @@ Page {
|
|||
}
|
||||
}
|
||||
onServerChanged: {
|
||||
console.log("Login server: " + notesApi.server)
|
||||
serverField.text = notesApi.server
|
||||
if (notesApi.server) {
|
||||
console.log("Login server: " + notesApi.server)
|
||||
account.setValue("server", notesApi.server)
|
||||
serverField.text = notesApi.server
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +119,7 @@ Page {
|
|||
spacing: Theme.paddingLarge
|
||||
|
||||
PageHeader {
|
||||
title: notesApi.statusProductName ? notesApi.statusProductName : qsTr("Nextcloud Login")
|
||||
id: pageHeader
|
||||
}
|
||||
|
||||
Image {
|
||||
|
@ -122,10 +134,8 @@ Page {
|
|||
id: apiProgressBar
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width
|
||||
indeterminate: notesApi.statusStatus === NotesApi.StatusInitiated ||
|
||||
notesApi.statusStatus === NotesApi.StatusBusy ||
|
||||
notesApi.loginStatus === NotesApi.StatusInitiated ||
|
||||
notesApi.loginStatus === NotesApi.StatusBusy
|
||||
indeterminate: notesApi.loginStatus === NotesApi.LoginFlowV2Initiating ||
|
||||
notesApi.loginStatus === NotesApi.LoginFlowV2Polling
|
||||
}
|
||||
|
||||
Row {
|
||||
|
@ -139,17 +149,33 @@ Page {
|
|||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||
onClicked: if (text === "") text = "https://"
|
||||
onTextChanged: {
|
||||
statusBusyIndicatorTimer.restart()
|
||||
if (acceptableInput)
|
||||
notesApi.server = text
|
||||
}
|
||||
EnterKey.enabled: text.length > 0
|
||||
EnterKey.iconSource: legacyLoginColumn.visible ? "image://theme/icon-m-enter-next" : "icon-m-enter-accept"
|
||||
EnterKey.onClicked: legacyLoginColumn.visible ? passwordField.focus = true : (notesApi.loginBusy ? notesApi.abortFlowV2Login() : notesApi.initiateFlowV2Login())
|
||||
//EnterKey.enabled: text.length > 0
|
||||
EnterKey.iconSource: legacyLoginPossible ? "image://theme/icon-m-enter-next" : flowLoginV2Possible ? "image://theme/icon-m-enter-accept" : "image://theme/icon-m-enter-close"
|
||||
EnterKey.onClicked: {
|
||||
if (legacyLoginPossible)
|
||||
usernameField.focus = true
|
||||
else if (flowLoginV2Possible && notesApi.loginStatus !== NotesApi.LoginFlowV2Polling)
|
||||
notesApi.initiateFlowV2Login()
|
||||
focus = false
|
||||
}
|
||||
}
|
||||
Icon {
|
||||
id: statusIcon
|
||||
highlighted: serverField.highlighted
|
||||
source: notesApi.statusInstalled ? "image://theme/icon-s-accept" : "image://theme/icon-s-decline"
|
||||
source: notesApi.statusInstalled ? "image://theme/icon-m-acknowledge" : "image://theme/icon-m-question"
|
||||
BusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
size: BusyIndicatorSize.Medium
|
||||
running: notesApi.ncStatusStatus === NotesApi.NextcloudBusy || (serverField.focus && statusBusyIndicatorTimer.running && !notesApi.statusInstalled)
|
||||
Timer {
|
||||
id: statusBusyIndicatorTimer
|
||||
interval: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,18 +184,12 @@ Page {
|
|||
width: parent.width
|
||||
spacing: Theme.paddingLarge
|
||||
visible: opacity !== 0.0
|
||||
opacity: notesApi.statusStatus === NotesApi.StatusFinished && notesApi.statusVersion.split('.')[0] >= 16 ? 1.0 : 0.0
|
||||
opacity: flowLoginV2Possible ? 1.0 : 0.0
|
||||
Behavior on opacity { FadeAnimator {} }
|
||||
Label {
|
||||
text: "Flow Login v2"
|
||||
x: Theme.horizontalPageMargin
|
||||
}
|
||||
Button {
|
||||
id: loginButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
property bool pushed: false
|
||||
text: notesApi.loginBusy ? qsTr("Abort") : qsTr("Login")
|
||||
onClicked: notesApi.loginBusy ? notesApi.abortFlowV2Login() : notesApi.initiateFlowV2Login()
|
||||
text: notesApi.loginStatus === NotesApi.LoginFlowV2Polling ? qsTr("Abort") : qsTr("Login")
|
||||
onClicked: notesApi.loginStatus === NotesApi.LoginFlowV2Polling ? notesApi.abortFlowV2Login() : notesApi.initiateFlowV2Login()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,16 +197,11 @@ Page {
|
|||
id: legacyLoginColumn
|
||||
width: parent.width
|
||||
visible: opacity !== 0.0
|
||||
opacity: notesApi.statusStatus === NotesApi.StatusFinished && notesApi.statusVersion.split('.')[0] < 16 ? 1.0 : 0.0
|
||||
opacity: legacyLoginPossible ? 1.0 : 0.0
|
||||
Behavior on opacity { FadeAnimator {} }
|
||||
Label {
|
||||
text: "Legacy Login"
|
||||
x: Theme.horizontalPageMargin
|
||||
}
|
||||
TextField {
|
||||
id: usernameField
|
||||
width: parent.width
|
||||
//text: account.value("name", "", String)
|
||||
placeholderText: qsTr("Username")
|
||||
label: placeholderText
|
||||
inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
|
||||
|
@ -198,50 +213,20 @@ Page {
|
|||
PasswordField {
|
||||
id: passwordField
|
||||
width: parent.width
|
||||
//text: account.value("password", "", String)
|
||||
placeholderText: qsTr("Password")
|
||||
label: placeholderText
|
||||
errorHighlight: text.length === 0// && focus === true
|
||||
EnterKey.enabled: text.length > 0
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-accept"
|
||||
EnterKey.onClicked: loginDialog.accept()
|
||||
EnterKey.onClicked: notesApi.verifyLogin(usernameField.text, passwordField.text)
|
||||
}
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: qsTr("Test Login")
|
||||
onClicked: notesApi.verifyLogin(usernameField.text, passwordField.text)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TextField {
|
||||
id: nameField
|
||||
width: parent.width
|
||||
//text: account.value("name", "", String)
|
||||
text: notesApi.statusProductName
|
||||
enabled: false
|
||||
placeholderText: qsTr("Account name")
|
||||
label: placeholderText
|
||||
errorHighlight: text.length === 0// && focus === true
|
||||
EnterKey.enabled: text.length > 0
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-next"
|
||||
EnterKey.onClicked: serverField.focus = true
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: serverField
|
||||
// regExp combined from https://stackoverflow.com/a/3809435 (EDIT: removed ? after https to force SSL) and https://www.regextester.com/22
|
||||
//property var encryptedRegEx: /^https:\/\/(((www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b|((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))))([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/
|
||||
//property var unencryptedRegEx : /^https?:\/\/(((www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b|((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))))([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/
|
||||
width: parent.width
|
||||
//text: account.value("server", "https://", String)
|
||||
placeholderText: qsTr("Nextcloud server")
|
||||
label: placeholderText// + " " + qsTr("(starting with \"https://\")")
|
||||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||
//validator: RegExpValidator { regExp: unencryptedConnectionTextSwitch.checked ? serverField.unencryptedRegEx : serverField.encryptedRegEx }
|
||||
errorHighlight: !acceptableInput// && focus === true
|
||||
EnterKey.enabled: acceptableInput
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-next"
|
||||
EnterKey.onClicked: usernameField.focus = true
|
||||
onTextChanged: notesApi.host = text
|
||||
}
|
||||
*/
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Security")
|
||||
}
|
||||
|
@ -256,14 +241,12 @@ Page {
|
|||
id: unsecureConnectionTextSwitch
|
||||
text: qsTr("Do not check certificates")
|
||||
description: qsTr("Enable this option to allow selfsigned certificates")
|
||||
//checked: account.value("allowUnencryptedConnection", false, Boolean)
|
||||
}
|
||||
TextSwitch {
|
||||
id: unencryptedConnectionTextSwitch
|
||||
automaticCheck: false
|
||||
text: qsTr("Allow unencrypted connections")
|
||||
description: qsTr("")
|
||||
//checked: account.value("unencryptedConnection", false, Boolean)
|
||||
onClicked: {
|
||||
if (checked) {
|
||||
checked = false
|
||||
|
|
|
@ -2,7 +2,7 @@ import QtQuick 2.2
|
|||
import Sailfish.Silica 1.0
|
||||
import Nemo.Configuration 1.0
|
||||
import Nemo.Notifications 1.0
|
||||
import harbour.nextcloudnotes.notesmodel 1.0
|
||||
//import harbour.nextcloudnotes.notesmodel 1.0
|
||||
|
||||
Page {
|
||||
id: page
|
||||
|
|
|
@ -16,12 +16,16 @@ int main(int argc, char *argv[])
|
|||
app->setOrganizationName("harbour-nextcloudnotes");
|
||||
|
||||
qDebug() << app->applicationDisplayName() << app->applicationVersion();
|
||||
|
||||
qmlRegisterType<NotesApi>("harbour.nextcloudnotes.notesapi", 1, 0, "NotesApi");
|
||||
qmlRegisterType<NotesProxyModel>("harbour.nextcloudnotes.notesmodel", 1, 0, "NotesModel");
|
||||
|
||||
NotesApi notesApi;
|
||||
QQuickView* view = SailfishApp::createView();
|
||||
|
||||
//view->engine()->rootContext()->setContextProperty("notesApi", ¬esApi);
|
||||
//view->engine()->rootContext()->setContextProperty("notesModel", notesApi.model());
|
||||
view->setSource(SailfishApp::pathTo("qml/harbour-nextcloudnotes.qml"));
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
view->rootContext()->setContextProperty("debug", QVariant(true));
|
||||
#else
|
||||
|
|
135
src/notesapi.cpp
135
src/notesapi.cpp
|
@ -4,8 +4,8 @@
|
|||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
NotesApi::NotesApi(const QString statusEndpoint, const QString loginEndpoint, const QString notesEndpoint, QObject *parent)
|
||||
: QObject(parent), m_statusEndpoint(statusEndpoint), m_loginEndpoint(loginEndpoint), m_notesEndpoint(notesEndpoint)
|
||||
NotesApi::NotesApi(const QString statusEndpoint, const QString loginEndpoint, const QString ocsEndpoint, const QString notesEndpoint, QObject *parent)
|
||||
: QObject(parent), m_statusEndpoint(statusEndpoint), m_loginEndpoint(loginEndpoint), m_ocsEndpoint(ocsEndpoint), m_notesEndpoint(notesEndpoint)
|
||||
{
|
||||
// TODO verify connections (also in destructor)
|
||||
m_loginPollTimer.setInterval(POLL_INTERVALL);
|
||||
|
@ -16,6 +16,10 @@ NotesApi::NotesApi(const QString statusEndpoint, const QString loginEndpoint, co
|
|||
setNcStatusStatus(NextcloudStatus::NextcloudUnknown);
|
||||
setLoginStatus(LoginStatus::LoginUnknown);
|
||||
m_ncStatusStatus = NextcloudStatus::NextcloudUnknown;
|
||||
m_status_installed = false;
|
||||
m_status_maintenance = false;
|
||||
m_status_needsDbUpgrade = false;
|
||||
m_status_extendedSupport = false;
|
||||
m_loginStatus = LoginStatus::LoginUnknown;
|
||||
mp_model = new NotesModel(this);
|
||||
mp_modelProxy = new NotesProxyModel(this);
|
||||
|
@ -86,8 +90,7 @@ QString NotesApi::server() const {
|
|||
}
|
||||
|
||||
void NotesApi::setServer(QString serverUrl) {
|
||||
QUrl url(serverUrl);
|
||||
qDebug() << serverUrl << server();
|
||||
QUrl url(serverUrl.trimmed());
|
||||
if (serverUrl != server()) {
|
||||
setScheme(url.scheme());
|
||||
setHost(url.host());
|
||||
|
@ -100,6 +103,7 @@ void NotesApi::setScheme(QString scheme) {
|
|||
if (scheme != m_url.scheme() && (scheme == "http" || scheme == "https")) {
|
||||
m_url.setScheme(scheme);
|
||||
emit schemeChanged(m_url.scheme());
|
||||
emit serverChanged(server());
|
||||
emit urlChanged(m_url);
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +112,7 @@ void NotesApi::setHost(QString host) {
|
|||
if (host != m_url.host()) {
|
||||
m_url.setHost(host);
|
||||
emit hostChanged(m_url.host());
|
||||
emit serverChanged(server());
|
||||
emit urlChanged(m_url);
|
||||
}
|
||||
}
|
||||
|
@ -116,6 +121,7 @@ void NotesApi::setPort(int port) {
|
|||
if (port != m_url.port() && port >= 1 && port <= 65535) {
|
||||
m_url.setPort(port);
|
||||
emit portChanged(m_url.port());
|
||||
emit serverChanged(server());
|
||||
emit urlChanged(m_url);
|
||||
}
|
||||
}
|
||||
|
@ -148,11 +154,12 @@ void NotesApi::setPath(QString path) {
|
|||
if (path != m_url.path()) {
|
||||
m_url.setPath(path);
|
||||
emit pathChanged(m_url.path());
|
||||
emit serverChanged(server());
|
||||
emit urlChanged(m_url);
|
||||
}
|
||||
}
|
||||
|
||||
void NotesApi::setDataFile(QString dataFile) {
|
||||
void NotesApi::setDataFile(const QString &dataFile) {
|
||||
if (dataFile != m_jsonFile.fileName()) {
|
||||
m_jsonFile.close();
|
||||
m_jsonFile.setFileName(dataFile);
|
||||
|
@ -202,10 +209,6 @@ void NotesApi::abortFlowV2Login() {
|
|||
emit loginUrlChanged(m_loginUrl);
|
||||
m_pollUrl.clear();
|
||||
m_pollToken.clear();
|
||||
if (m_loginReply->isRunning())
|
||||
m_loginReply->abort();
|
||||
if (m_pollReply->isRunning())
|
||||
m_pollReply->abort();
|
||||
setLoginStatus(LoginStatus::LoginUnknown);
|
||||
}
|
||||
|
||||
|
@ -222,6 +225,22 @@ void NotesApi::pollLoginUrl() {
|
|||
}
|
||||
}
|
||||
|
||||
void NotesApi::verifyLogin(QString username, QString password) {
|
||||
m_ocsRequest = m_authenticatedRequest;
|
||||
if (username.isEmpty())
|
||||
username = this->username();
|
||||
if (password.isEmpty())
|
||||
password = this->password();
|
||||
QUrl url = apiEndpointUrl(m_ocsEndpoint + QString("/users/%1").arg(username));
|
||||
m_ocsRequest.setRawHeader("Authorization", "Basic " + QString(username + ":" + password).toLocal8Bit().toBase64());
|
||||
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
qDebug() << "GET" << url.toDisplayString();
|
||||
m_ocsRequest.setUrl(url);
|
||||
m_ocsReply = m_manager.get(m_ocsRequest);
|
||||
emit busyChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
void NotesApi::getAllNotes(QStringList excludeFields) {
|
||||
QUrl url = apiEndpointUrl(m_notesEndpoint + "/notes");
|
||||
if (!excludeFields.isEmpty())
|
||||
|
@ -347,54 +366,56 @@ void NotesApi::replyFinished(QNetworkReply *reply) {
|
|||
emit error(NoError);
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument json = QJsonDocument::fromJson(data);
|
||||
/*if (reply->url().toString().contains(m_loginEndpoint)) {
|
||||
qDebug() << "Login reply";
|
||||
}
|
||||
else if (reply->url() == m_pollUrl) {
|
||||
qDebug() << "Poll reply";
|
||||
}
|
||||
else if (reply->url().toString().contains(m_statusEndpoint)) {
|
||||
qDebug() << "Status reply";
|
||||
}
|
||||
else if (reply->url().toString().contains(m_notesEndpoint)) {
|
||||
qDebug() << "Notes reply";
|
||||
}*/
|
||||
|
||||
if (reply == m_loginReply) {
|
||||
qDebug() << "Login reply";
|
||||
if (json.isObject())
|
||||
updateLoginFlow(json.object());
|
||||
m_loginReply = NULL;
|
||||
}
|
||||
else if (reply == m_pollReply) {
|
||||
qDebug() << "Poll reply, finished";
|
||||
if (json.isObject())
|
||||
updateLoginCredentials(json.object());
|
||||
m_pollReply = NULL;
|
||||
abortFlowV2Login();
|
||||
}
|
||||
else if (reply == m_statusReply) {
|
||||
qDebug() << "Status reply";
|
||||
if (json.isObject())
|
||||
updateNcStatus(json.object());
|
||||
m_statusReply = NULL;
|
||||
}
|
||||
else if (m_notesReplies.contains(reply)) {
|
||||
qDebug() << "Notes reply";
|
||||
if (mp_model) {
|
||||
if (mp_model->fromJsonDocument(json)) {
|
||||
m_lastSync = QDateTime::currentDateTimeUtc();
|
||||
emit lastSyncChanged(m_lastSync);
|
||||
}
|
||||
if (reply == m_ocsReply) {
|
||||
qDebug() << "OCS reply";
|
||||
QString xml(data);
|
||||
if (xml.contains("<status>ok</status>")) {
|
||||
qDebug() << "Login Success!";
|
||||
setLoginStatus(LoginSuccess);
|
||||
}
|
||||
else {
|
||||
qDebug() << "Login Failed!";
|
||||
setLoginStatus(LoginFailed);
|
||||
}
|
||||
m_notesReplies.removeOne(reply);
|
||||
emit busyChanged(busy());
|
||||
}
|
||||
else {
|
||||
qDebug() << "Unknown reply";
|
||||
QJsonDocument json = QJsonDocument::fromJson(data);
|
||||
if (reply == m_loginReply) {
|
||||
qDebug() << "Login reply";
|
||||
if (json.isObject())
|
||||
updateLoginFlow(json.object());
|
||||
m_loginReply = NULL;
|
||||
}
|
||||
else if (reply == m_pollReply) {
|
||||
qDebug() << "Poll reply, finished";
|
||||
if (json.isObject())
|
||||
updateLoginCredentials(json.object());
|
||||
m_pollReply = NULL;
|
||||
abortFlowV2Login();
|
||||
}
|
||||
else if (reply == m_statusReply) {
|
||||
qDebug() << "Status reply";
|
||||
if (json.isObject())
|
||||
updateNcStatus(json.object());
|
||||
m_statusReply = NULL;
|
||||
}
|
||||
else if (m_notesReplies.contains(reply)) {
|
||||
qDebug() << "Notes reply";
|
||||
if (mp_model) {
|
||||
if (mp_model->fromJsonDocument(json)) {
|
||||
m_lastSync = QDateTime::currentDateTimeUtc();
|
||||
emit lastSyncChanged(m_lastSync);
|
||||
}
|
||||
}
|
||||
m_notesReplies.removeOne(reply);
|
||||
emit busyChanged(busy());
|
||||
}
|
||||
else {
|
||||
qDebug() << "Unknown reply";
|
||||
}
|
||||
//qDebug() << data;
|
||||
}
|
||||
//qDebug() << data;
|
||||
}
|
||||
else if (reply->error() == QNetworkReply::AuthenticationRequiredError) {
|
||||
emit error(AuthenticationError);
|
||||
|
@ -494,8 +515,9 @@ void NotesApi::updateNcStatus(const QJsonObject &status) {
|
|||
}
|
||||
|
||||
void NotesApi::setNcStatusStatus(NextcloudStatus status, bool *changed) {
|
||||
*changed = status != m_ncStatusStatus;
|
||||
if (*changed) {
|
||||
if (status != m_ncStatusStatus) {
|
||||
if (changed)
|
||||
*changed = true;
|
||||
m_ncStatusStatus = status;
|
||||
emit ncStatusStatusChanged(m_ncStatusStatus);
|
||||
}
|
||||
|
@ -558,8 +580,9 @@ bool NotesApi::updateLoginCredentials(const QJsonObject &credentials) {
|
|||
}
|
||||
|
||||
void NotesApi::setLoginStatus(LoginStatus status, bool *changed) {
|
||||
*changed = status != m_loginStatus;
|
||||
if (*changed) {
|
||||
if (status != m_loginStatus) {
|
||||
if (changed)
|
||||
*changed = true;
|
||||
m_loginStatus = status;
|
||||
emit loginStatusChanged(m_loginStatus);
|
||||
}
|
||||
|
|
|
@ -13,68 +13,85 @@
|
|||
#define STATUS_ENDPOINT "/status.php"
|
||||
#define LOGIN_ENDPOINT "/index.php/login/v2"
|
||||
#define NOTES_ENDPOINT "/index.php/apps/notes/api/v0.2"
|
||||
#define OCS_ENDPOINT "/ocs/v1.php/cloud"
|
||||
#define POLL_INTERVALL 5000
|
||||
|
||||
class NotesApi : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool sslVerify READ sslVerify WRITE setSslVerify NOTIFY sslVerifyChanged)
|
||||
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
|
||||
Q_PROPERTY(bool urlValid READ urlValid NOTIFY urlValidChanged)
|
||||
Q_PROPERTY(QString server READ server WRITE setServer NOTIFY serverChanged)
|
||||
Q_PROPERTY(QString scheme READ scheme WRITE setScheme NOTIFY schemeChanged)
|
||||
Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged)
|
||||
Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged)
|
||||
Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged)
|
||||
Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged)
|
||||
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
|
||||
Q_PROPERTY(QString dataFile READ dataFile WRITE setDataFile NOTIFY dataFileChanged)
|
||||
Q_PROPERTY(bool networkAccessible READ networkAccessible NOTIFY networkAccessibleChanged)
|
||||
Q_PROPERTY(QDateTime lastSync READ lastSync NOTIFY lastSyncChanged)
|
||||
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
|
||||
|
||||
Q_PROPERTY(NextcloudStatus ncStatusStatus READ ncStatusStatus NOTIFY ncStatusStatusChanged)
|
||||
Q_PROPERTY(bool statusInstalled READ statusInstalled NOTIFY statusInstalledChanged)
|
||||
Q_PROPERTY(bool statusMaintenance READ statusMaintenance NOTIFY statusMaintenanceChanged)
|
||||
Q_PROPERTY(bool statusNeedsDbUpgrade READ statusNeedsDbUpgrade NOTIFY statusNeedsDbUpgradeChanged)
|
||||
Q_PROPERTY(QString statusVersion READ statusVersion NOTIFY statusVersionChanged)
|
||||
Q_PROPERTY(QString statusVersionString READ statusVersionString NOTIFY statusVersionStringChanged)
|
||||
Q_PROPERTY(QString statusEdition READ statusEdition NOTIFY statusEditionChanged)
|
||||
Q_PROPERTY(QString statusProductName READ statusProductName NOTIFY statusProductNameChanged)
|
||||
Q_PROPERTY(bool statusExtendedSupport READ statusExtendedSupport NOTIFY statusExtendedSupportChanged)
|
||||
|
||||
Q_PROPERTY(LoginStatus loginStatus READ loginStatus NOTIFY loginStatusChanged)
|
||||
Q_PROPERTY(QUrl loginUrl READ loginUrl NOTIFY loginUrlChanged)
|
||||
|
||||
public:
|
||||
explicit NotesApi(const QString statusEndpoint = STATUS_ENDPOINT,
|
||||
const QString loginEndpoint = LOGIN_ENDPOINT,
|
||||
const QString ocsEndpoint = OCS_ENDPOINT,
|
||||
const QString notesEndpoint = NOTES_ENDPOINT,
|
||||
QObject *parent = nullptr);
|
||||
QObject *parent = NULL);
|
||||
virtual ~NotesApi();
|
||||
|
||||
Q_PROPERTY(bool sslVerify READ sslVerify WRITE setSslVerify NOTIFY sslVerifyChanged)
|
||||
bool sslVerify() const { return m_authenticatedRequest.sslConfiguration().peerVerifyMode() == QSslSocket::VerifyPeer; }
|
||||
void setSslVerify(bool verify);
|
||||
|
||||
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
|
||||
QUrl url() const { return m_url; }
|
||||
void setUrl(QUrl url);
|
||||
|
||||
Q_PROPERTY(bool urlValid READ urlValid NOTIFY urlValidChanged)
|
||||
bool urlValid() const { return m_url.isValid(); }
|
||||
|
||||
Q_PROPERTY(QString server READ server WRITE setServer NOTIFY serverChanged)
|
||||
QString server() const;
|
||||
void setServer(QString server);
|
||||
|
||||
Q_PROPERTY(QString scheme READ scheme WRITE setScheme NOTIFY schemeChanged)
|
||||
QString scheme() const { return m_url.scheme(); }
|
||||
void setScheme(QString scheme);
|
||||
|
||||
Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged)
|
||||
QString host() const { return m_url.host(); }
|
||||
void setHost(QString host);
|
||||
|
||||
Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged)
|
||||
int port() const { return m_url.port(); }
|
||||
void setPort(int port);
|
||||
|
||||
Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged)
|
||||
QString username() const { return m_url.userName(); }
|
||||
void setUsername(QString username);
|
||||
|
||||
Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged)
|
||||
QString password() const { return m_url.password(); }
|
||||
void setPassword(QString password);
|
||||
|
||||
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
|
||||
QString path() const { return m_url.path(); }
|
||||
void setPath(QString path);
|
||||
|
||||
Q_PROPERTY(QString dataFile READ dataFile WRITE setDataFile NOTIFY dataFileChanged)
|
||||
QString dataFile() const { return m_jsonFile.fileName(); }
|
||||
void setDataFile(QString dataFile);
|
||||
void setDataFile(const QString &dataFile);
|
||||
|
||||
Q_PROPERTY(bool networkAccessible READ networkAccessible NOTIFY networkAccessibleChanged)
|
||||
bool networkAccessible() const { return m_manager.networkAccessible() == QNetworkAccessManager::Accessible; }
|
||||
|
||||
Q_PROPERTY(QDateTime lastSync READ lastSync NOTIFY lastSyncChanged)
|
||||
QDateTime lastSync() const { return m_lastSync; }
|
||||
|
||||
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
|
||||
bool busy() const { return !m_notesReplies.empty();; }
|
||||
|
||||
enum NextcloudStatus {
|
||||
|
@ -96,33 +113,23 @@ public:
|
|||
};
|
||||
Q_ENUM(LoginStatus)
|
||||
|
||||
Q_PROPERTY(NextcloudStatus ncStatusStatus READ ncStatusStatus NOTIFY ncStatusStatusChanged)
|
||||
NextcloudStatus ncStatusStatus() const { return m_ncStatusStatus; }
|
||||
Q_PROPERTY(bool statusInstalled READ statusInstalled NOTIFY statusInstalledChanged)
|
||||
bool statusInstalled() const { return m_status_installed; }
|
||||
Q_PROPERTY(bool statusMaintenance READ statusMaintenance NOTIFY statusMaintenanceChanged)
|
||||
bool statusMaintenance() const { return m_status_maintenance; }
|
||||
Q_PROPERTY(bool statusNeedsDbUpgrade READ statusNeedsDbUpgrade NOTIFY statusNeedsDbUpgradeChanged)
|
||||
bool statusNeedsDbUpgrade() const { return m_status_needsDbUpgrade; }
|
||||
Q_PROPERTY(QString statusVersion READ statusVersion NOTIFY statusVersionChanged)
|
||||
QString statusVersion() const { return m_status_version; }
|
||||
Q_PROPERTY(QString statusVersionString READ statusVersionString NOTIFY statusVersionStringChanged)
|
||||
QString statusVersionString() const { return m_status_versionstring; }
|
||||
Q_PROPERTY(QString statusEdition READ statusEdition NOTIFY statusEditionChanged)
|
||||
QString statusEdition() const { return m_status_edition; }
|
||||
Q_PROPERTY(QString statusProductName READ statusProductName NOTIFY statusProductNameChanged)
|
||||
QString statusProductName() const { return m_status_productname; }
|
||||
Q_PROPERTY(bool statusExtendedSupport READ statusExtendedSupport NOTIFY statusExtendedSupportChanged)
|
||||
bool statusExtendedSupport() const { return m_status_extendedSupport; }
|
||||
|
||||
Q_PROPERTY(LoginStatus loginStatus READ loginStatus NOTIFY loginStatusChanged)
|
||||
LoginStatus loginStatus() const { return m_loginStatus; }
|
||||
Q_PROPERTY(QUrl loginUrl READ loginUrl NOTIFY loginUrlChanged)
|
||||
QUrl loginUrl() const { return m_loginUrl; }
|
||||
|
||||
Q_INVOKABLE bool getNcStatus();
|
||||
Q_INVOKABLE bool initiateFlowV2Login();
|
||||
Q_INVOKABLE void abortFlowV2Login();
|
||||
Q_INVOKABLE void verifyLogin(QString username = QString(), QString password = QString());
|
||||
Q_INVOKABLE void getAllNotes(QStringList excludeFields = QStringList());
|
||||
Q_INVOKABLE void getNote(double noteId, QStringList excludeFields = QStringList());
|
||||
Q_INVOKABLE void createNote(QVariantMap fields = QVariantMap());
|
||||
|
@ -139,6 +146,7 @@ public:
|
|||
SslHandshakeError,
|
||||
AuthenticationError
|
||||
};
|
||||
Q_ENUM(ErrorCodes)
|
||||
Q_INVOKABLE const QString errorMessage(ErrorCodes error) const;
|
||||
|
||||
signals:
|
||||
|
@ -187,6 +195,7 @@ private:
|
|||
QNetworkAccessManager m_manager;
|
||||
QNetworkRequest m_request;
|
||||
QNetworkRequest m_authenticatedRequest;
|
||||
QNetworkRequest m_ocsRequest;
|
||||
QFile m_jsonFile;
|
||||
NotesModel* mp_model;
|
||||
NotesProxyModel* mp_modelProxy;
|
||||
|
@ -220,6 +229,10 @@ private:
|
|||
QUrl m_pollUrl;
|
||||
QString m_pollToken;
|
||||
|
||||
// Nextcloud OCS API - https://docs.nextcloud.com/server/18/developer_manual/client_apis/OCS/ocs-api-overview.html
|
||||
const QString m_ocsEndpoint;
|
||||
QNetworkReply* m_ocsReply;
|
||||
|
||||
// Nextcloud Notes API - https://github.com/nextcloud/notes/wiki/Notes-0.2
|
||||
const QString m_notesEndpoint;
|
||||
QVector<QNetworkReply*> m_notesReplies;
|
||||
|
|
|
@ -159,31 +159,23 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Verifying server address</source>
|
||||
<source>Follow the instructions in the browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server address is valid</source>
|
||||
<source>Login successfull!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Initiating login</source>
|
||||
<source>Login failed!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Follow the login procedure in the browser</source>
|
||||
<source>Enter your credentials</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Login successfull</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error while loggin in</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please enter a valid server address</source>
|
||||
<source>Test Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
@ -677,14 +669,14 @@ You can also use other markdown syntax inside them.</source>
|
|||
</context>
|
||||
<context>
|
||||
<name>harbour-nextcloudnotes</name>
|
||||
<message>
|
||||
<source>Offline</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Notes</source>
|
||||
<translation type="unfinished">Notizen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Offline</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Synced</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
|
|
@ -159,31 +159,23 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Verifying server address</source>
|
||||
<source>Follow the instructions in the browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server address is valid</source>
|
||||
<source>Login successfull!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Initiating login</source>
|
||||
<source>Login failed!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Follow the login procedure in the browser</source>
|
||||
<source>Enter your credentials</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Login successfull</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error while loggin in</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please enter a valid server address</source>
|
||||
<source>Test Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
@ -677,14 +669,14 @@ You can also use other markdown syntax inside them.</source>
|
|||
</context>
|
||||
<context>
|
||||
<name>harbour-nextcloudnotes</name>
|
||||
<message>
|
||||
<source>Offline</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Notes</source>
|
||||
<translation type="unfinished">Anteckningar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Offline</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Synced</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
|
|
@ -133,92 +133,83 @@
|
|||
<context>
|
||||
<name>LoginPage</name>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="42"/>
|
||||
<source>Verifying server address</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="46"/>
|
||||
<source>Server address is valid</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="63"/>
|
||||
<source>Initiating login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="67"/>
|
||||
<source>Follow the login procedure in the browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="71"/>
|
||||
<source>Login successfull</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="75"/>
|
||||
<source>Error while loggin in</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="110"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="18"/>
|
||||
<source>Nextcloud Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="136"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="146"/>
|
||||
<source>Nextcloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="190"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="205"/>
|
||||
<source>Username</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="202"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="216"/>
|
||||
<source>Password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="171"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="191"/>
|
||||
<source>Abort</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="50"/>
|
||||
<source>Please enter a valid server address</source>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="74"/>
|
||||
<source>Follow the instructions in the browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="171"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="83"/>
|
||||
<source>Login successfull!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="80"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="88"/>
|
||||
<source>Login failed!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="69"/>
|
||||
<source>Enter your credentials</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="191"/>
|
||||
<source>Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="246"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="225"/>
|
||||
<source>Test Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="231"/>
|
||||
<source>Security</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="253"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="238"/>
|
||||
<source><strong>CAUTION: Your password will be saved without any encryption on the device!</strong><br>Please consider creating a dedicated app password! Open your Nextcloud in a browser and go to <i>Settings</i> → <i>Security</i>.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="257"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="242"/>
|
||||
<source>Do not check certificates</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="258"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="243"/>
|
||||
<source>Enable this option to allow selfsigned certificates</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="264"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="248"/>
|
||||
<source>Allow unencrypted connections</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -305,37 +296,37 @@
|
|||
<context>
|
||||
<name>NotesApi</name>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="521"/>
|
||||
<location filename="../src/notesapi.cpp" line="319"/>
|
||||
<source>No network connection available</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="524"/>
|
||||
<location filename="../src/notesapi.cpp" line="322"/>
|
||||
<source>Failed to communicate with the Nextcloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="527"/>
|
||||
<location filename="../src/notesapi.cpp" line="325"/>
|
||||
<source>An error happened while reading from the local storage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="530"/>
|
||||
<location filename="../src/notesapi.cpp" line="328"/>
|
||||
<source>An error happened while writing to the local storage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="533"/>
|
||||
<location filename="../src/notesapi.cpp" line="331"/>
|
||||
<source>An error occured while establishing an encrypted connection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="536"/>
|
||||
<location filename="../src/notesapi.cpp" line="334"/>
|
||||
<source>Could not authenticate to the Nextcloud instance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="539"/>
|
||||
<location filename="../src/notesapi.cpp" line="337"/>
|
||||
<source>Unknown error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -833,22 +824,22 @@ You can also use other markdown syntax inside them.</source>
|
|||
<context>
|
||||
<name>harbour-nextcloudnotes</name>
|
||||
<message>
|
||||
<location filename="../qml/harbour-nextcloudnotes.qml" line="96"/>
|
||||
<location filename="../qml/harbour-nextcloudnotes.qml" line="108"/>
|
||||
<source>Notes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/harbour-nextcloudnotes.qml" line="97"/>
|
||||
<location filename="../qml/harbour-nextcloudnotes.qml" line="109"/>
|
||||
<source>Offline</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/harbour-nextcloudnotes.qml" line="98"/>
|
||||
<location filename="../qml/harbour-nextcloudnotes.qml" line="110"/>
|
||||
<source>Synced</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/harbour-nextcloudnotes.qml" line="105"/>
|
||||
<location filename="../qml/harbour-nextcloudnotes.qml" line="117"/>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
Loading…
Reference in a new issue