Making progess...
This commit is contained in:
parent
34484748f5
commit
629d752dee
15 changed files with 313 additions and 226 deletions
|
@ -1,7 +1,6 @@
|
|||
import QtQuick 2.5
|
||||
import Sailfish.Silica 1.0
|
||||
import Nemo.Configuration 1.0
|
||||
import harbour.nextcloudnotes.notesapi 1.0
|
||||
|
||||
Page {
|
||||
id: loginPage
|
||||
|
|
|
@ -5,15 +5,9 @@ import "../js/showdown/dist/showdown.js" as ShowDown
|
|||
Dialog {
|
||||
id: noteDialog
|
||||
|
||||
property int id
|
||||
property int modified
|
||||
property string title
|
||||
property string category
|
||||
property string content
|
||||
property bool favorite
|
||||
property string etag
|
||||
property bool error
|
||||
property string errorMessage
|
||||
property int index
|
||||
property var note: notesModel.getNote(notesModel.index(index, 0))
|
||||
|
||||
|
||||
property var showdown: ShowDown.showdown
|
||||
property var converter: new showdown.Converter(
|
||||
|
@ -50,9 +44,21 @@ Dialog {
|
|||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
console.log(title)
|
||||
parseContent()
|
||||
}
|
||||
Connections {
|
||||
target: notesModel
|
||||
onDataChanged: {
|
||||
console.log(topLeft, bottomRight, index)
|
||||
if (notesModel.index(topLeft, bottomRight) === index) {
|
||||
console.log("This note changed")
|
||||
}
|
||||
else {
|
||||
console.log("Another note changed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function reloadContent() {
|
||||
//notesApi.getNoteFromApi(id)
|
||||
|
@ -66,7 +72,7 @@ Dialog {
|
|||
|
||||
function parseContent() {
|
||||
//note = notesApi.getNoteFromApi(id, false)
|
||||
var convertedText = converter.makeHtml(content)
|
||||
var convertedText = converter.makeHtml(note["content"])
|
||||
var occurence = -1
|
||||
convertedText = convertedText.replace(/^<li>(<p>)?\[ \] (.*)(<.*)$/gmi,
|
||||
function(match, p1, p2, p3, offset) {
|
||||
|
@ -109,12 +115,12 @@ Dialog {
|
|||
|
||||
MenuItem {
|
||||
text: qsTr("Delete")
|
||||
onClicked: remorse.execute("Deleting", function() { notesApi.deleteNote(id) } )
|
||||
onClicked: remorse.execute("Deleting", function() { notesApi.deleteNote(note["id"]) } )
|
||||
}
|
||||
MenuItem {
|
||||
text: enabled ? qsTr("Reload") : qsTr("Updating...")
|
||||
enabled: !notesApi.busy
|
||||
onClicked: notesApi.getNote(id)
|
||||
onClicked: notesApi.getNote(note["id"])
|
||||
}
|
||||
MenuLabel {
|
||||
visible: appSettings.currentAccount.length >= 0
|
||||
|
@ -159,7 +165,7 @@ Dialog {
|
|||
onLinkActivated: {
|
||||
//console.log(link)
|
||||
var occurence = -1
|
||||
var newContent = content
|
||||
var newContent = note["content"]
|
||||
if (/^tasklist:checkbox_(\d+)$/m.test(link)) {
|
||||
newContent = newContent.replace(/- \[ \] (.*)$/gm,
|
||||
function(match, p1, offset, string) {
|
||||
|
@ -237,18 +243,18 @@ Dialog {
|
|||
width: parent.width - x
|
||||
IconButton {
|
||||
id: favoriteButton
|
||||
property bool selected: favorite
|
||||
property bool selected: note["favorite"]
|
||||
width: Theme.iconSizeMedium
|
||||
icon.source: (selected ? "image://theme/icon-m-favorite-selected?" : "image://theme/icon-m-favorite?") +
|
||||
(favoriteButton.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor)
|
||||
onClicked: {
|
||||
notesApi.updateNote(id, {'favorite': !favorite, 'modified': new Date().valueOf() / 1000 })
|
||||
notesApi.updateNote(note["id"], {'favorite': selected, 'modified': new Date().valueOf() / 1000 })
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
id: categoryField
|
||||
width: parent.width - favoriteButton.width
|
||||
text: category
|
||||
text: note["category"]
|
||||
placeholderText: qsTr("No category")
|
||||
label: qsTr("Category")
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-accept"
|
||||
|
@ -266,7 +272,7 @@ Dialog {
|
|||
DetailItem {
|
||||
id: modifiedDetail
|
||||
label: qsTr("Modified")
|
||||
value: new Date(noteDialog.modified * 1000).toLocaleString(Qt.locale(), Locale.ShortFormat)
|
||||
value: new Date(note["modified"] * 1000).toLocaleString(Qt.locale(), Locale.ShortFormat)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,18 +103,7 @@ Page {
|
|||
id: remorse
|
||||
}
|
||||
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("../pages/NotePage.qml"),
|
||||
{ //note: noteListModel.get(index),
|
||||
id: id,
|
||||
modified: modified,
|
||||
title: title,
|
||||
category: category,
|
||||
content: content,
|
||||
favorite: favorite,
|
||||
etag: etag,
|
||||
error: error,
|
||||
errorMessage: errorMessage
|
||||
})
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("../pages/NotePage.qml"), { index: index } )
|
||||
onPressAndHold: menu.open(note)
|
||||
|
||||
Separator {
|
||||
|
@ -131,6 +120,7 @@ Page {
|
|||
icon.source: (favorite ? "image://theme/icon-m-favorite-selected?" : "image://theme/icon-m-favorite?") +
|
||||
(note.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor)
|
||||
onClicked: {
|
||||
notesStore.updateNote(id, {'favorite': !favorite, 'modified': new Date().valueOf() / 1000 } )
|
||||
notesApi.updateNote(id, {'favorite': !favorite, 'modified': new Date().valueOf() / 1000 } )
|
||||
}
|
||||
}
|
||||
|
@ -201,6 +191,7 @@ Page {
|
|||
text: qsTr("Delete")
|
||||
onClicked: {
|
||||
remorse.execute(note, qsTr("Deleting note"), function() {
|
||||
//notesStore.deleteNote(id)
|
||||
notesApi.deleteNote(id)
|
||||
})
|
||||
}
|
||||
|
|
31
src/note.cpp
31
src/note.cpp
|
@ -126,6 +126,31 @@ const QJsonDocument Note::toJsonDocument() const {
|
|||
return QJsonDocument(m_json);
|
||||
}
|
||||
|
||||
Note::NoteField Note::noteFieldsFromStringList(QStringList fields) {
|
||||
QList<NoteField> list = noteFields();
|
||||
QFlags<NoteField> flags;
|
||||
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
if (fields.contains(noteFieldName(list[i]))) {
|
||||
flags |= list[i];
|
||||
}
|
||||
}
|
||||
return static_cast<NoteField>((int)flags);
|
||||
}
|
||||
|
||||
QStringList Note::noteFieldsToStringList(NoteField fields) {
|
||||
QList<NoteField> list = noteFields();
|
||||
QFlags<NoteField> flags(fields);
|
||||
QStringList stringList;
|
||||
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
if (flags.testFlag(list[i])) {
|
||||
stringList << noteFieldName(list[i]);
|
||||
}
|
||||
}
|
||||
return stringList;
|
||||
}
|
||||
|
||||
int Note::id() const {
|
||||
return m_json.value(noteFieldName(Id)).toInt(-1);
|
||||
}
|
||||
|
@ -232,10 +257,14 @@ bool Note::favorite(const QJsonObject &jobj) {
|
|||
return jobj.value(noteFieldName(Favorite)).toBool();
|
||||
}
|
||||
void Note::setFavorite(bool favorite) {
|
||||
if (favorite != this->favorite()) {
|
||||
if (favorite && favorite != this->favorite()) {
|
||||
m_json.insert(noteFieldName(Favorite), QJsonValue(favorite));
|
||||
emit favoriteChanged(this->favorite());
|
||||
}
|
||||
else {
|
||||
m_json.remove(noteFieldName(Favorite));
|
||||
emit favoriteChanged(this->favorite());
|
||||
}
|
||||
}
|
||||
|
||||
QString Note::etag() const {
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
Q_INVOKABLE static QStringList noteFieldNames() {
|
||||
return m_noteFieldNames.values();
|
||||
}
|
||||
Q_INVOKABLE static NoteField noteFieldsFromStringList(QStringList fields);
|
||||
Q_INVOKABLE static QStringList noteFieldsToStringList(Note::NoteField fields);
|
||||
|
||||
Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged)
|
||||
int id() const;
|
||||
|
|
206
src/notesapi.cpp
206
src/notesapi.cpp
|
@ -11,9 +11,6 @@ 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()));
|
||||
m_statusReply = NULL;
|
||||
m_loginReply = NULL;
|
||||
m_pollReply = NULL;
|
||||
setNcStatusStatus(NextcloudStatus::NextcloudUnknown);
|
||||
setLoginStatus(LoginStatus::LoginUnknown);
|
||||
m_ncStatusStatus = NextcloudStatus::NextcloudUnknown;
|
||||
|
@ -53,6 +50,10 @@ void NotesApi::setAccount(const QString &account) {
|
|||
}
|
||||
}
|
||||
|
||||
void NotesApi::getAllNotes(const QStringList exclude) {
|
||||
getAllNotes(Note::noteFieldsFromStringList(exclude));
|
||||
}
|
||||
|
||||
void NotesApi::getAllNotes(Note::NoteField exclude) {
|
||||
qDebug() << "Getting all notes";
|
||||
QUrl url = apiEndpointUrl(m_notesEndpoint);
|
||||
|
@ -71,11 +72,15 @@ void NotesApi::getAllNotes(Note::NoteField exclude) {
|
|||
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
qDebug() << "GET" << url.toDisplayString();
|
||||
m_authenticatedRequest.setUrl(url);
|
||||
m_notesReplies << m_manager.get(m_authenticatedRequest);
|
||||
m_getAllNotesReplies << m_manager.get(m_authenticatedRequest);
|
||||
emit busyChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
void NotesApi::getNote(const int id, const QStringList exclude) {
|
||||
getNote(id, Note::noteFieldsFromStringList(exclude));
|
||||
}
|
||||
|
||||
void NotesApi::getNote(const int id, Note::NoteField exclude) {
|
||||
qDebug() << "Getting note: " << id;
|
||||
QUrl url = apiEndpointUrl(m_notesEndpoint + QString("/%1").arg(id));
|
||||
|
@ -94,29 +99,39 @@ void NotesApi::getNote(const int id, Note::NoteField exclude) {
|
|||
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
qDebug() << "GET" << url.toDisplayString();
|
||||
m_authenticatedRequest.setUrl(url);
|
||||
m_notesReplies << m_manager.get(m_authenticatedRequest);
|
||||
m_getNoteReplies << m_manager.get(m_authenticatedRequest);
|
||||
emit busyChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
void NotesApi::createNote(const QVariantMap ¬e) {
|
||||
createNote(Note(QJsonObject::fromVariantMap(note)));
|
||||
}
|
||||
|
||||
void NotesApi::createNote(const Note ¬e) {
|
||||
qDebug() << "Creating note";
|
||||
QUrl url = apiEndpointUrl(m_notesEndpoint);
|
||||
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
qDebug() << "POST" << url.toDisplayString();
|
||||
m_authenticatedRequest.setUrl(url);
|
||||
m_notesReplies << m_manager.post(m_authenticatedRequest, noteApiData(note));
|
||||
m_createNoteReplies << m_manager.post(m_authenticatedRequest, noteApiData(note));
|
||||
emit busyChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
void NotesApi::updateNote(const int id, const QVariantMap ¬e) {
|
||||
Note newNote(QJsonObject::fromVariantMap(note));
|
||||
newNote.setId(id);
|
||||
updateNote(newNote);
|
||||
}
|
||||
|
||||
void NotesApi::updateNote(const Note ¬e) {
|
||||
qDebug() << "Updating note: " << note.id();
|
||||
QUrl url = apiEndpointUrl(m_notesEndpoint + QString("/%1").arg(note.id()));
|
||||
if (note.isValid() && url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
qDebug() << "PUT" << url.toDisplayString();
|
||||
m_authenticatedRequest.setUrl(url);
|
||||
m_notesReplies << m_manager.put(m_authenticatedRequest, noteApiData(note));
|
||||
m_updateNoteReplies << m_manager.put(m_authenticatedRequest, noteApiData(note));
|
||||
emit busyChanged(true);
|
||||
}
|
||||
}
|
||||
|
@ -127,11 +142,23 @@ void NotesApi::deleteNote(const int id) {
|
|||
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
qDebug() << "DELETE" << url.toDisplayString();
|
||||
m_authenticatedRequest.setUrl(url);
|
||||
m_notesReplies << m_manager.deleteResource(m_authenticatedRequest);
|
||||
m_deleteNoteReplies << m_manager.deleteResource(m_authenticatedRequest);
|
||||
emit busyChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool NotesApi::busy() const {
|
||||
return !(m_getAllNotesReplies.empty() ||
|
||||
m_getNoteReplies.empty() ||
|
||||
m_createNoteReplies.empty() ||
|
||||
m_updateNoteReplies.empty() ||
|
||||
m_deleteNoteReplies.empty() ||
|
||||
m_statusReplies.empty() ||
|
||||
m_loginReplies.empty() ||
|
||||
m_pollReplies.empty() ||
|
||||
m_ocsReplies.empty());
|
||||
}
|
||||
|
||||
const QByteArray NotesApi::noteApiData(const Note ¬e) {
|
||||
QJsonObject json = note.toJsonObject();
|
||||
json.remove(Note::noteFieldName(Note::Id));
|
||||
|
@ -264,7 +291,7 @@ bool NotesApi::getNcStatus() {
|
|||
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
setNcStatusStatus(NextcloudStatus::NextcloudBusy);
|
||||
m_request.setUrl(url);
|
||||
m_statusReply = m_manager.post(m_request, QByteArray());
|
||||
m_statusReplies << m_manager.post(m_request, QByteArray());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
@ -283,7 +310,7 @@ bool NotesApi::initiateFlowV2Login() {
|
|||
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
setLoginStatus(LoginStatus::LoginFlowV2Initiating);
|
||||
m_request.setUrl(url);
|
||||
m_loginReply = m_manager.post(m_request, QByteArray());
|
||||
m_loginReplies << m_manager.post(m_request, QByteArray());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
@ -307,7 +334,7 @@ void NotesApi::pollLoginUrl() {
|
|||
qDebug() << "POST" << m_pollUrl.toDisplayString();
|
||||
if (m_pollUrl.isValid() && !m_pollUrl.scheme().isEmpty() && !m_pollUrl.host().isEmpty() && !m_pollToken.isEmpty()) {
|
||||
m_request.setUrl(m_pollUrl);
|
||||
m_pollReply = m_manager.post(m_request, QByteArray("token=").append(m_pollToken));
|
||||
m_pollReplies << m_manager.post(m_request, QByteArray("token=").append(m_pollToken));
|
||||
}
|
||||
else {
|
||||
qDebug() << "URL not valid!";
|
||||
|
@ -327,7 +354,7 @@ void NotesApi::verifyLogin(QString username, QString password) {
|
|||
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
|
||||
qDebug() << "GET" << url.toDisplayString();
|
||||
m_ocsRequest.setUrl(url);
|
||||
m_ocsReply = m_manager.get(m_ocsRequest);
|
||||
m_ocsReplies << m_manager.get(m_ocsRequest);
|
||||
emit busyChanged(true);
|
||||
}
|
||||
}
|
||||
|
@ -343,12 +370,6 @@ const QString NotesApi::errorMessage(ErrorCodes error) const {
|
|||
case CommunicationError:
|
||||
message = tr("Failed to communicate with the Nextcloud server");
|
||||
break;
|
||||
case LocalFileReadError:
|
||||
message = tr("An error happened while reading from the local storage");
|
||||
break;
|
||||
case LocalFileWriteError:
|
||||
message = tr("An error happened while writing to the local storage");
|
||||
break;
|
||||
case SslHandshakeError:
|
||||
message = tr("An error occured while establishing an encrypted connection");
|
||||
break;
|
||||
|
@ -380,16 +401,92 @@ void NotesApi::onNetworkAccessibleChanged(QNetworkAccessManager::NetworkAccessib
|
|||
}
|
||||
|
||||
void NotesApi::replyFinished(QNetworkReply *reply) {
|
||||
//qDebug() << reply->error() << reply->errorString();
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
qDebug() << reply->error() << reply->errorString();
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError)
|
||||
emit error(NoError);
|
||||
else if (reply->error() == QNetworkReply::AuthenticationRequiredError)
|
||||
emit error(AuthenticationError);
|
||||
else if (reply->error() == QNetworkReply::ContentNotFoundError && m_pollReplies.contains(reply))
|
||||
emit error(NoError);
|
||||
else
|
||||
emit error(CommunicationError);
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument json = QJsonDocument::fromJson(data);
|
||||
|
||||
if (reply == m_ocsReply) {
|
||||
if (m_getAllNotesReplies.contains(reply)) {
|
||||
qDebug() << "Get all notes reply";
|
||||
if (reply->error() == QNetworkReply::NoError && json.isArray())
|
||||
updateApiNotes(json.array());
|
||||
m_getAllNotesReplies.removeOne(reply);
|
||||
}
|
||||
else if (m_getNoteReplies.contains(reply)) {
|
||||
qDebug() << "Get note reply";
|
||||
if (reply->error() == QNetworkReply::NoError && json.isObject())
|
||||
updateApiNote(json.object());
|
||||
m_getNoteReplies.removeOne(reply);
|
||||
}
|
||||
else if (m_createNoteReplies.contains(reply)) {
|
||||
qDebug() << "Create note reply";
|
||||
if (reply->error() == QNetworkReply::NoError && json.isObject())
|
||||
updateApiNote(json.object());
|
||||
m_createNoteReplies.removeOne(reply);
|
||||
}
|
||||
else if (m_updateNoteReplies.contains(reply)) {
|
||||
qDebug() << "Update note reply";
|
||||
if (reply->error() == QNetworkReply::NoError && json.isObject())
|
||||
updateApiNote(json.object());
|
||||
m_updateNoteReplies.removeOne(reply);
|
||||
}
|
||||
else if (m_deleteNoteReplies.contains(reply)) {
|
||||
qDebug() << "Delete note reply";
|
||||
bool ok;
|
||||
QString idString = reply->url().path().split('/', QString::SkipEmptyParts).last();
|
||||
int id = idString.toInt(&ok);
|
||||
if (reply->error() == QNetworkReply::NoError && ok)
|
||||
emit noteDeleted(id);
|
||||
m_deleteNoteReplies.removeOne(reply);
|
||||
}
|
||||
else if (m_loginReplies.contains(reply)) {
|
||||
qDebug() << "Login reply";
|
||||
if (reply->error() == QNetworkReply::NoError && json.isObject())
|
||||
updateLoginFlow(json.object());
|
||||
else {
|
||||
m_loginStatus = LoginStatus::LoginFailed;
|
||||
emit loginStatusChanged(m_loginStatus);
|
||||
}
|
||||
m_loginReplies.removeOne(reply);
|
||||
}
|
||||
else if (m_pollReplies.contains(reply)) {
|
||||
qDebug() << "Poll reply, finished";
|
||||
if (reply->error() == QNetworkReply::NoError && json.isObject())
|
||||
updateLoginCredentials(json.object());
|
||||
else if (reply->error() == QNetworkReply::ContentNotFoundError) {
|
||||
qDebug() << "Polling not finished yet" << reply->url().toDisplayString();
|
||||
m_loginStatus = LoginStatus::LoginFlowV2Polling;
|
||||
emit loginStatusChanged(m_loginStatus);
|
||||
}
|
||||
else {
|
||||
m_loginStatus = LoginStatus::LoginFailed;
|
||||
emit loginStatusChanged(m_loginStatus);
|
||||
}
|
||||
m_pollReplies.removeOne(reply);
|
||||
abortFlowV2Login();
|
||||
}
|
||||
else if (m_statusReplies.contains(reply)) {
|
||||
qDebug() << "Status reply";
|
||||
if (reply->error() == QNetworkReply::NoError && json.isObject())
|
||||
updateNcStatus(json.object());
|
||||
else
|
||||
updateNcStatus(QJsonObject());
|
||||
m_statusReplies.removeOne(reply);
|
||||
}
|
||||
else if (m_ocsReplies.contains(reply)) {
|
||||
qDebug() << "OCS reply";
|
||||
QString xml(data);
|
||||
if (xml.contains("<status>ok</status>")) {
|
||||
if (reply->error() == QNetworkReply::NoError && xml.contains("<status>ok</status>")) {
|
||||
qDebug() << "Login Success!";
|
||||
setLoginStatus(LoginSuccess);
|
||||
}
|
||||
|
@ -397,73 +494,14 @@ void NotesApi::replyFinished(QNetworkReply *reply) {
|
|||
qDebug() << "Login Failed!";
|
||||
setLoginStatus(LoginFailed);
|
||||
}
|
||||
m_ocsReplies.removeOne(reply);
|
||||
}
|
||||
else {
|
||||
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 (json.isArray())
|
||||
updateApiNotes(json.array());
|
||||
else if (json.isObject())
|
||||
updateApiNote(json.object());
|
||||
m_notesReplies.removeOne(reply);
|
||||
emit busyChanged(busy());
|
||||
}
|
||||
else {
|
||||
qDebug() << "Unknown or double reply";
|
||||
qDebug() << "Unknown reply";
|
||||
}
|
||||
//qDebug() << data;
|
||||
}
|
||||
}
|
||||
else if (reply->error() == QNetworkReply::AuthenticationRequiredError) {
|
||||
emit error(AuthenticationError);
|
||||
}
|
||||
else if (reply->error() == QNetworkReply::ContentNotFoundError && reply == m_pollReply) {
|
||||
qDebug() << "Polling not finished yet" << reply->url().toDisplayString();
|
||||
}
|
||||
else {
|
||||
if (reply == m_loginReply) {
|
||||
m_loginReply = NULL;
|
||||
m_loginStatus = LoginStatus::LoginFailed;
|
||||
emit loginStatusChanged(m_loginStatus);
|
||||
}
|
||||
else if (reply == m_pollReply) {
|
||||
m_pollReply = NULL;
|
||||
m_loginStatus = LoginStatus::LoginFlowV2Polling;
|
||||
emit loginStatusChanged(m_loginStatus);
|
||||
}
|
||||
else if (reply == m_statusReply) {
|
||||
m_statusReply = NULL;
|
||||
updateNcStatus(QJsonObject());
|
||||
//m_statusStatus = RequestStatus::StatusError;
|
||||
//emit statusStatusChanged(m_statusStatus);
|
||||
}
|
||||
else if (m_notesReplies.contains(reply)) {
|
||||
m_notesReplies.removeOne(reply);
|
||||
|
||||
emit busyChanged(busy());
|
||||
}
|
||||
if (reply != m_statusReply)
|
||||
emit error(CommunicationError);
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
|
||||
QDateTime lastSync() const { return m_lastSync; }
|
||||
|
||||
bool busy() const { return !m_notesReplies.empty();; }
|
||||
bool busy() const;
|
||||
|
||||
enum NextcloudStatus {
|
||||
NextcloudUnknown, // Nothing known about the nextcloud server
|
||||
|
@ -134,8 +134,6 @@ public:
|
|||
NoError,
|
||||
NoConnectionError,
|
||||
CommunicationError,
|
||||
LocalFileReadError,
|
||||
LocalFileWriteError,
|
||||
SslHandshakeError,
|
||||
AuthenticationError
|
||||
};
|
||||
|
@ -146,10 +144,14 @@ public:
|
|||
void setAccount(const QString& account);
|
||||
|
||||
public slots:
|
||||
Q_INVOKABLE void getAllNotes(Note::NoteField exclude = Note::None);
|
||||
Q_INVOKABLE void getNote(const int id, Note::NoteField exclude = Note::None);
|
||||
Q_INVOKABLE void createNote(const Note& note);
|
||||
Q_INVOKABLE void updateNote(const Note& note);
|
||||
Q_INVOKABLE void getAllNotes(const QStringList exclude = QStringList());
|
||||
void getAllNotes(Note::NoteField exclude);
|
||||
Q_INVOKABLE void getNote(const int id, const QStringList exclude = QStringList());
|
||||
void getNote(const int id, Note::NoteField exclude);
|
||||
Q_INVOKABLE void createNote(const QVariantMap& note);
|
||||
void createNote(const Note& note);
|
||||
Q_INVOKABLE void updateNote(const int id, const QVariantMap& note);
|
||||
void updateNote(const Note& note);
|
||||
Q_INVOKABLE void deleteNote(const int id);
|
||||
|
||||
signals:
|
||||
|
@ -205,7 +207,7 @@ private:
|
|||
|
||||
// Nextcloud status.php
|
||||
const QString m_statusEndpoint;
|
||||
QNetworkReply* m_statusReply;
|
||||
QVector<QNetworkReply*> m_statusReplies;
|
||||
void updateNcStatus(const QJsonObject &status);
|
||||
NextcloudStatus m_ncStatusStatus;
|
||||
void setNcStatusStatus(NextcloudStatus status, bool *changed = NULL);
|
||||
|
@ -220,8 +222,8 @@ private:
|
|||
|
||||
// Nextcloud Login Flow v2 - https://docs.nextcloud.com/server/18/developer_manual/client_apis/LoginFlow/index.html#login-flow-v2
|
||||
const QString m_loginEndpoint;
|
||||
QNetworkReply* m_loginReply;
|
||||
QNetworkReply* m_pollReply;
|
||||
QVector<QNetworkReply*> m_loginReplies;
|
||||
QVector<QNetworkReply*> m_pollReplies;
|
||||
bool updateLoginFlow(const QJsonObject &login);
|
||||
bool updateLoginCredentials(const QJsonObject &credentials);
|
||||
LoginStatus m_loginStatus;
|
||||
|
@ -233,11 +235,15 @@ private:
|
|||
|
||||
// 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;
|
||||
QVector<QNetworkReply*> m_ocsReplies;
|
||||
|
||||
// Nextcloud Notes API - https://github.com/nextcloud/notes/wiki/Notes-0.2
|
||||
const QString m_notesEndpoint;
|
||||
QVector<QNetworkReply*> m_notesReplies;
|
||||
QVector<QNetworkReply*> m_getAllNotesReplies;
|
||||
QVector<QNetworkReply*> m_getNoteReplies;
|
||||
QVector<QNetworkReply*> m_createNoteReplies;
|
||||
QVector<QNetworkReply*> m_updateNoteReplies;
|
||||
QVector<QNetworkReply*> m_deleteNoteReplies;
|
||||
void updateApiNotes(const QJsonArray& json);
|
||||
void updateApiNote(const QJsonObject& json);
|
||||
QDateTime m_lastSync;
|
||||
|
|
|
@ -13,22 +13,29 @@ class NotesInterface : public QObject
|
|||
Q_CLASSINFO("url", "https://github.com/scharel/harbour-nextcloudnotes")
|
||||
|
||||
public:
|
||||
explicit NotesInterface(QObject *parent = nullptr) : QObject(parent) { }
|
||||
explicit NotesInterface(QObject *parent = nullptr) : QObject(parent) {
|
||||
}
|
||||
|
||||
virtual QString account() const = 0;
|
||||
virtual void setAccount(const QString& account) = 0;
|
||||
|
||||
public slots:
|
||||
Q_INVOKABLE virtual void getAllNotes(Note::NoteField exclude = Note::None) = 0;
|
||||
Q_INVOKABLE virtual void getNote(const int id, Note::NoteField exclude = Note::None) = 0;
|
||||
Q_INVOKABLE virtual void createNote(const Note& note) = 0;
|
||||
Q_INVOKABLE virtual void updateNote(const Note& note) = 0;
|
||||
Q_INVOKABLE virtual void getAllNotes(const QStringList exclude = QStringList()) = 0;
|
||||
virtual void getAllNotes(Note::NoteField exclude) = 0;
|
||||
Q_INVOKABLE virtual void getNote(const int id, const QStringList exclude = QStringList()) = 0;
|
||||
virtual void getNote(const int id, Note::NoteField) = 0;
|
||||
Q_INVOKABLE virtual void createNote(const QVariantMap& note) = 0;
|
||||
virtual void createNote(const Note& note) = 0;
|
||||
Q_INVOKABLE virtual void updateNote(const int id, const QVariantMap& note) = 0;
|
||||
virtual void updateNote(const Note& note) = 0;
|
||||
Q_INVOKABLE virtual void deleteNote(const int id) = 0;
|
||||
|
||||
signals:
|
||||
void accountChanged(const QString& account);
|
||||
void noteUpdated(const QVariantMap& note);
|
||||
void noteUpdated(const Note& note);
|
||||
void noteDeleted(const int id);
|
||||
|
||||
};
|
||||
|
||||
#endif // NOTESINTERFACE_H
|
||||
|
|
|
@ -27,6 +27,18 @@ int NotesProxyModel::roleFromName(const QString &name) const {
|
|||
return roleNames().key(name.toLocal8Bit());
|
||||
}
|
||||
|
||||
const QVariantMap NotesProxyModel::getNote(const QModelIndex &index) const {
|
||||
QMap<int, QVariant> item = sourceModel()->itemData(mapToSource(index));
|
||||
QHash<int, QByteArray> names = roleNames();
|
||||
QVariantMap note;
|
||||
QMapIterator<int, QVariant> i(item);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
note[names.value(i.key())] = i.value();
|
||||
}
|
||||
return note;
|
||||
}
|
||||
|
||||
bool NotesProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const {
|
||||
QAbstractItemModel* source = sourceModel();
|
||||
if (m_favoritesOnTop && source->data(source_left, NotesModel::FavoriteRole).toBool() != source->data(source_right, NotesModel::FavoriteRole).toBool())
|
||||
|
@ -63,7 +75,7 @@ int NotesModel::insertNote(const Note ¬e) {
|
|||
int position = m_notes.indexOf(note);
|
||||
if (position >= 0) {
|
||||
if (m_notes.at(position).equal(note)) {
|
||||
qDebug() << "Note already present unchanged.";
|
||||
qDebug() << "Note already present and unchanged.";
|
||||
}
|
||||
else {
|
||||
qDebug() << "Note already present, updating it.";
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
|
||||
Q_INVOKABLE void sort();
|
||||
Q_INVOKABLE int roleFromName(const QString &name) const;
|
||||
Q_INVOKABLE const QVariantMap getNote(const QModelIndex &index) const;
|
||||
|
||||
protected:
|
||||
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
|
||||
|
|
|
@ -39,6 +39,10 @@ void NotesStore::setAccount(const QString& account) {
|
|||
}
|
||||
}
|
||||
|
||||
void NotesStore::getAllNotes(const QStringList exclude) {
|
||||
getAllNotes(Note::noteFieldsFromStringList(exclude));
|
||||
}
|
||||
|
||||
void NotesStore::getAllNotes(Note::NoteField exclude) {
|
||||
qDebug() << "Getting all notes";
|
||||
QFileInfoList files = m_dir.entryInfoList();
|
||||
|
@ -51,6 +55,10 @@ void NotesStore::getAllNotes(Note::NoteField exclude) {
|
|||
}
|
||||
}
|
||||
|
||||
void NotesStore::getNote(const int id, const QStringList exclude) {
|
||||
getNote(id, Note::noteFieldsFromStringList(exclude));
|
||||
}
|
||||
|
||||
void NotesStore::getNote(const int id, Note::NoteField exclude) {
|
||||
qDebug() << "Getting note: " << id;
|
||||
if (id >= 0) {
|
||||
|
@ -60,6 +68,10 @@ void NotesStore::getNote(const int id, Note::NoteField exclude) {
|
|||
}
|
||||
}
|
||||
|
||||
void NotesStore::createNote(const QVariantMap ¬e) {
|
||||
createNote(Note(QJsonObject::fromVariantMap(note)));
|
||||
}
|
||||
|
||||
void NotesStore::createNote(const Note& note) {
|
||||
qDebug() << "Creating note: " << note.id();
|
||||
if (!note.isValid()) {
|
||||
|
@ -76,6 +88,12 @@ void NotesStore::createNote(const Note& note) {
|
|||
}
|
||||
}
|
||||
|
||||
void NotesStore::updateNote(const int id, const QVariantMap ¬e) {
|
||||
Note newNote(QJsonObject::fromVariantMap(note));
|
||||
newNote.setId(id);
|
||||
updateNote(newNote);
|
||||
}
|
||||
|
||||
void NotesStore::updateNote(const Note& note) {
|
||||
qDebug() << "Updating note: " << note.id();
|
||||
if (note.isValid()) {
|
||||
|
|
|
@ -21,10 +21,14 @@ public:
|
|||
void setAccount(const QString& account);
|
||||
|
||||
public slots:
|
||||
Q_INVOKABLE void getAllNotes(Note::NoteField exclude = Note::None);
|
||||
Q_INVOKABLE void getNote(const int id, Note::NoteField exclude = Note::None);
|
||||
Q_INVOKABLE void createNote(const Note& note);
|
||||
Q_INVOKABLE void updateNote(const Note& note);
|
||||
Q_INVOKABLE void getAllNotes(const QStringList exclude = QStringList());
|
||||
void getAllNotes(Note::NoteField exclude);
|
||||
Q_INVOKABLE void getNote(const int id, const QStringList exclude = QStringList());
|
||||
void getNote(const int id, Note::NoteField exclude);
|
||||
Q_INVOKABLE void createNote(const QVariantMap& note);
|
||||
void createNote(const Note& note);
|
||||
Q_INVOKABLE void updateNote(const int id, const QVariantMap& note);
|
||||
void updateNote(const Note& note);
|
||||
Q_INVOKABLE void deleteNote(const int id);
|
||||
|
||||
private:
|
||||
|
|
|
@ -262,14 +262,6 @@
|
|||
<source>Failed to communicate with the Nextcloud server</source>
|
||||
<translation>Fehler bei der Server-Kommunikation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error happened while reading from the local storage</source>
|
||||
<translation>Fehler beim Lesen der lokalen Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error happened while writing to the local storage</source>
|
||||
<translation>Fehler beim Schreiben der lokalen Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error occured while establishing an encrypted connection</source>
|
||||
<translation>Fehler beim Aufbau einer verschlüsselten Kommunikation</translation>
|
||||
|
|
|
@ -262,14 +262,6 @@
|
|||
<source>Failed to communicate with the Nextcloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error happened while reading from the local storage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error happened while writing to the local storage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error occured while establishing an encrypted connection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
|
|
@ -133,98 +133,98 @@
|
|||
<context>
|
||||
<name>LoginPage</name>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="18"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="17"/>
|
||||
<source>Nextcloud Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="168"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="167"/>
|
||||
<source>Nextcloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="227"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="226"/>
|
||||
<source>Username</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="238"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="237"/>
|
||||
<source>Password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="213"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="212"/>
|
||||
<source>Abort</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="95"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="94"/>
|
||||
<source>Follow the instructions in the browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="104"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="103"/>
|
||||
<source>Login successfull!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="101"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="110"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="100"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="109"/>
|
||||
<source>Login failed!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="90"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="89"/>
|
||||
<source>Enter your credentials</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="213"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="212"/>
|
||||
<source>Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="213"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="212"/>
|
||||
<source>Re-Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="247"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="246"/>
|
||||
<source>Test Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="253"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="252"/>
|
||||
<source>Note</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="261"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="260"/>
|
||||
<source>The <a href="https://apps.nextcloud.com/apps/notes">Notes</a> app needs to be installed on the Nextcloud server for this app to work.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="265"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="264"/>
|
||||
<source>Security</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="272"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="271"/>
|
||||
<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="276"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="275"/>
|
||||
<source>Do not check certificates</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="277"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="276"/>
|
||||
<source>Enable this option to allow selfsigned certificates</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="286"/>
|
||||
<location filename="../qml/pages/LoginPage.qml" line="285"/>
|
||||
<source>Allow unencrypted connections</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -245,12 +245,12 @@
|
|||
<context>
|
||||
<name>Note</name>
|
||||
<message>
|
||||
<location filename="../src/note.cpp" line="306"/>
|
||||
<location filename="../src/note.cpp" line="335"/>
|
||||
<source>Today</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/note.cpp" line="308"/>
|
||||
<location filename="../src/note.cpp" line="337"/>
|
||||
<source>Yesterday</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -258,52 +258,52 @@
|
|||
<context>
|
||||
<name>NotePage</name>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="111"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="117"/>
|
||||
<source>Delete</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="115"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="121"/>
|
||||
<source>Reload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="115"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="121"/>
|
||||
<source>Updating...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="121"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="127"/>
|
||||
<source>Last update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="124"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="130"/>
|
||||
<source>never</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="131"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="137"/>
|
||||
<source>Edit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="132"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="138"/>
|
||||
<source>Notes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="252"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="258"/>
|
||||
<source>No category</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="253"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="259"/>
|
||||
<source>Category</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotePage.qml" line="268"/>
|
||||
<location filename="../qml/pages/NotePage.qml" line="274"/>
|
||||
<source>Modified</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -311,37 +311,27 @@
|
|||
<context>
|
||||
<name>NotesApi</name>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="341"/>
|
||||
<location filename="../src/notesapi.cpp" line="368"/>
|
||||
<source>No network connection available</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="344"/>
|
||||
<location filename="../src/notesapi.cpp" line="371"/>
|
||||
<source>Failed to communicate with the Nextcloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="347"/>
|
||||
<source>An error happened while reading from the local storage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="350"/>
|
||||
<source>An error happened while writing to the local storage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="353"/>
|
||||
<location filename="../src/notesapi.cpp" line="374"/>
|
||||
<source>An error occured while establishing an encrypted connection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="356"/>
|
||||
<location filename="../src/notesapi.cpp" line="377"/>
|
||||
<source>Could not authenticate to the Nextcloud instance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/notesapi.cpp" line="359"/>
|
||||
<location filename="../src/notesapi.cpp" line="380"/>
|
||||
<source>Unknown error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -349,97 +339,97 @@
|
|||
<context>
|
||||
<name>NotesPage</name>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="30"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="29"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="34"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="33"/>
|
||||
<source>Add note</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="39"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="38"/>
|
||||
<source>Reload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="39"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="38"/>
|
||||
<source>Updating...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="45"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="44"/>
|
||||
<source>Last update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="48"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="47"/>
|
||||
<source>never</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="58"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="57"/>
|
||||
<source>Nextcloud Notes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="199"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="188"/>
|
||||
<source>Modified</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="202"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="191"/>
|
||||
<source>Delete</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="204"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="193"/>
|
||||
<source>Deleting note</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="234"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="224"/>
|
||||
<source>Loading notes...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="240"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="230"/>
|
||||
<source>No account yet</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="241"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="231"/>
|
||||
<source>Got to the settings to add an account</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="247"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="237"/>
|
||||
<source>No notes yet</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="248"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="238"/>
|
||||
<source>Pull down to add a note</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="254"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="244"/>
|
||||
<source>No result</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="255"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="245"/>
|
||||
<source>Try another query</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="261"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="251"/>
|
||||
<source>An error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="272"/>
|
||||
<location filename="../qml/pages/NotesPage.qml" line="262"/>
|
||||
<source>Open the settings to configure your Nextcloud accounts</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
Loading…
Reference in a new issue