Work in progress: Login, Markdown, ...
This commit is contained in:
parent
811bb27a09
commit
6262b35302
9 changed files with 218 additions and 119 deletions
|
@ -18,7 +18,6 @@ SOURCES += src/harbour-nextcloudnotes.cpp
|
|||
|
||||
DISTFILES += qml/harbour-nextcloudnotes.qml \
|
||||
qml/cover/CoverPage.qml \
|
||||
qml/pages/FirstPage.qml \
|
||||
qml/pages/NotesApi.qml \
|
||||
rpm/harbour-nextcloudnotes.changes.in \
|
||||
rpm/harbour-nextcloudnotes.changes.run.in \
|
||||
|
@ -27,7 +26,9 @@ DISTFILES += qml/harbour-nextcloudnotes.qml \
|
|||
translations/*.ts \
|
||||
harbour-nextcloudnotes.desktop \
|
||||
qml/pages/NotePage.qml \
|
||||
qml/pages/LoginPage.qml
|
||||
qml/pages/NotesPage.qml \
|
||||
qml/pages/LoginDialog.qml \
|
||||
qml/pages/EditPage.qml
|
||||
|
||||
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
||||
|
||||
|
|
|
@ -11,9 +11,19 @@ ApplicationWindow
|
|||
id: appSettings
|
||||
path: "/apps/harbour-nextcloudnotes/settings"
|
||||
property string lastUpdate: qsTr("never")
|
||||
property url server: "https://127.0.0.1"
|
||||
property string username: "test"
|
||||
property string password // TODO provide password before testing. Just use revocable passwords for testing!
|
||||
property url server: ""
|
||||
property string username: ""
|
||||
property string password: ""
|
||||
property bool unsecureConnection: false
|
||||
// For testing
|
||||
Component.onCompleted: {
|
||||
//server = ""
|
||||
//username = ""
|
||||
//password = ""
|
||||
console.log("Server: " + server)
|
||||
console.log("Username: " + username)
|
||||
console.log("Password: " + password)
|
||||
}
|
||||
}
|
||||
|
||||
property var notes: NotesApi {
|
||||
|
@ -25,7 +35,7 @@ ApplicationWindow
|
|||
onLastUpdateChanged: appSettings.lastUpdate = notes.lastUpdate
|
||||
}
|
||||
|
||||
initialPage: Component { FirstPage { } }
|
||||
initialPage: Component { NotesPage { } }
|
||||
cover: Qt.resolvedUrl("cover/CoverPage.qml")
|
||||
allowedOrientations: defaultAllowedOrientations
|
||||
}
|
||||
|
|
BIN
qml/img/nextcloud-logo-transparent.png
Normal file
BIN
qml/img/nextcloud-logo-transparent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
30
qml/pages/EditPage.qml
Normal file
30
qml/pages/EditPage.qml
Normal file
|
@ -0,0 +1,30 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
Page {
|
||||
id: page
|
||||
|
||||
property var note
|
||||
|
||||
SilicaFlickable {
|
||||
id: flickable
|
||||
anchors.fill: parent
|
||||
contentHeight: column.height
|
||||
|
||||
Column {
|
||||
id: column
|
||||
width: parent.width// - 2*x
|
||||
|
||||
PageHeader {
|
||||
title: note.title
|
||||
}
|
||||
|
||||
TextArea {
|
||||
width: parent.width
|
||||
text: note.content
|
||||
}
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {}
|
||||
}
|
||||
}
|
73
qml/pages/LoginDialog.qml
Normal file
73
qml/pages/LoginDialog.qml
Normal file
|
@ -0,0 +1,73 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
Dialog {
|
||||
id: loginDialog
|
||||
|
||||
property url server
|
||||
property string username
|
||||
property string password
|
||||
|
||||
canAccept: (serverField.acceptableInput && usernameField.text.length > 0 && passwordField.text.length > 0)
|
||||
onAccepted: {
|
||||
server = serverField.text
|
||||
username = usernameField.text
|
||||
password = passwordField.text
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
|
||||
DialogHeader {
|
||||
id: header
|
||||
//title: qsTr("Nextcloud Login")
|
||||
acceptText: qsTr("Login")
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: Theme.itemSizeHuge
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "../img/nextcloud-logo-transparent.png"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: serverField
|
||||
focus: true
|
||||
width: parent.width
|
||||
text: (server.toString().length > 0) ? server : "https://"
|
||||
placeholderText: qsTr("Nextcloud server")
|
||||
label: placeholderText + " " + qsTr("(starting with \"https://\")")
|
||||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||
// regExp from https://stackoverflow.com/a/3809435 (EDIT: removed ? after https to force SSL)
|
||||
validator: RegExpValidator { regExp: /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/ } // TODO disable unencrypted communication
|
||||
EnterKey.enabled: acceptableInput
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-next"
|
||||
EnterKey.onClicked: usernameField.focus = true
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: usernameField
|
||||
width: parent.width
|
||||
text: (username.length > 0) ? username : ""
|
||||
placeholderText: qsTr("Username")
|
||||
label: placeholderText
|
||||
inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
|
||||
errorHighlight: text.length === 0 && focus === true
|
||||
EnterKey.enabled: text.length > 0
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-next"
|
||||
EnterKey.onClicked: passwordField.focus = true
|
||||
}
|
||||
|
||||
PasswordField {
|
||||
id: passwordField
|
||||
width: parent.width
|
||||
text: (password.length > 0) ? 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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
Page {
|
||||
id: page
|
||||
|
||||
allowedOrientations: Orientation.Portrait
|
||||
|
||||
SilicaFlickable {
|
||||
id: webView
|
||||
anchors.fill: parent
|
||||
|
||||
PullDownMenu {
|
||||
MenuItem {
|
||||
text: qsTr("Reload")
|
||||
onClicked: webView.reload()
|
||||
}
|
||||
}
|
||||
|
||||
PageHeader {
|
||||
title: qsTr("Login")
|
||||
}
|
||||
|
||||
Column {
|
||||
TextField {
|
||||
focus: true
|
||||
width: parent.width
|
||||
placeholderText: qsTr("https://cloud.nextcloud.com")
|
||||
label: qsTr("Nextcloud server")
|
||||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||
}
|
||||
|
||||
TextField {
|
||||
width: parent.width
|
||||
placeholderText: qsTr("Username")
|
||||
label: qsTr("Nextcloud user")
|
||||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||
}
|
||||
|
||||
TextField {
|
||||
width: parent.width
|
||||
placeholderText: qsTr("Password")
|
||||
label: qsTr("Nextcloud App-Password")
|
||||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,41 +5,52 @@ Page {
|
|||
id: page
|
||||
|
||||
property var note
|
||||
|
||||
property int id
|
||||
property string etag
|
||||
property date modified
|
||||
property string title
|
||||
property string category
|
||||
property bool favorite
|
||||
property string content
|
||||
property bool error
|
||||
property string errorMessage
|
||||
|
||||
|
||||
// The effective value will be restricted by ApplicationWindow.allowedOrientations
|
||||
allowedOrientations: Orientation.All
|
||||
property var markdown: [
|
||||
{ regex: new RegExp(/(^#\s)(.*)$/gm), replace: '<h1>$2</h1>' },
|
||||
{ regex: new RegExp(/(^##\s)(.*)$/gm), replace: '<h2>$2</h2>' },
|
||||
{ regex: new RegExp(/(^###\s)(.*)$/gm), replace: '<h3>$2</h3>' },
|
||||
{ regex: new RegExp(/(^####\s)(.*)$/gm), replace: '<h4>$2</h4>' },
|
||||
{ regex: new RegExp(/(^#####\s)(.*)$/gm), replace: '<h5>$2</h5>' },
|
||||
{ regex: new RegExp(/(^######\s)(.*)$/gm), replace: '<h6>$2</h6>' },
|
||||
{ regex: new RegExp(/(^-\s)(.*)$/gm), replace: '<ul><li>$2</li></ul>' },
|
||||
{ regex: new RegExp(/(^\d{1,}.\s)(.*)$/gm), replace: '<ol><li>$2</li></ol>' }
|
||||
]
|
||||
|
||||
SilicaFlickable {
|
||||
id: flickable
|
||||
anchors.fill: parent
|
||||
contentHeight: column.height
|
||||
|
||||
PullDownMenu {
|
||||
quickSelect: true
|
||||
MenuItem {
|
||||
text: qsTr("Edit")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("EditPage.qml"), { note: note } )
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: column
|
||||
//x: Theme.horizontalPageMargin
|
||||
width: parent.width// - 2*x
|
||||
width: parent.width
|
||||
|
||||
PageHeader {
|
||||
title: note.title
|
||||
}
|
||||
|
||||
TextArea {
|
||||
width: parent.width
|
||||
readOnly: true
|
||||
LinkedLabel {
|
||||
x: Theme.horizontalPageMargin
|
||||
width: parent.width - 2*x
|
||||
textFormat: Text.StyledText
|
||||
text: note.content
|
||||
Component.onCompleted: {
|
||||
for (var i=0; i < markdown.length; i++) {
|
||||
text = text.replace(markdown[i].regex, markdown[i].replace)
|
||||
}
|
||||
console.log(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,17 +7,31 @@ Page {
|
|||
SilicaListView {
|
||||
id: notesList
|
||||
anchors.fill: parent
|
||||
spacing: Theme.paddingLarge
|
||||
|
||||
PullDownMenu {
|
||||
busy: notes.busy
|
||||
MenuItem {
|
||||
text: qsTr("Settings")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("Settings.qml"))
|
||||
onClicked: {
|
||||
var login = pageStack.push(Qt.resolvedUrl("LoginDialog.qml"), { server: appSettings.server, username: appSettings.username, password: appSettings.password } )
|
||||
login.accepted.connect(function() {
|
||||
console.log(login.username + ":" + login.password + "@" + login.server)
|
||||
appSettings.server = login.server
|
||||
appSettings.username = login.username
|
||||
appSettings.password = login.password
|
||||
notes.getNotes()
|
||||
})
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Add note")
|
||||
onClicked: console.log("Add note")
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Update")
|
||||
onClicked: notes.getNotes()
|
||||
}
|
||||
MenuLabel {
|
||||
text: qsTr("Last update") + ": " + new Date(appSettings.lastUpdate).toLocaleString(Qt.locale(), Locale.ShortFormat)
|
||||
}
|
||||
|
@ -34,7 +48,12 @@ Page {
|
|||
}
|
||||
|
||||
currentIndex: -1
|
||||
Component.onCompleted: notes.getNotes()
|
||||
Component.onCompleted: {
|
||||
if (appSettings.server.toString().length > 0 && appSettings.username.length > 0 && appSettings.password.length > 0)
|
||||
notes.getNotes()
|
||||
}
|
||||
|
||||
//Component.onCompleted: notes.getNotes()
|
||||
//Component.onCompleted: notes.getNote("1212725")
|
||||
//Component.onCompleted: notes.createNote("Hello World!", "Test")
|
||||
//Component.onCompleted: notes.updateNote(1212725, "# Hello World!\nIs this working?", "Test")
|
||||
|
@ -49,7 +68,8 @@ Page {
|
|||
IconButton {
|
||||
id: isFavoriteIcon
|
||||
anchors.left: parent.left
|
||||
anchors.top: titleLabel.top
|
||||
anchors.leftMargin: Theme.paddingSmall
|
||||
anchors.top: parent.top
|
||||
width: Theme.iconSizeMedium
|
||||
icon.source: (favorite ? "image://theme/icon-m-favorite-selected?" : "image://theme/icon-m-favorite?") +
|
||||
(note.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor)
|
||||
|
@ -67,7 +87,6 @@ Page {
|
|||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.horizontalPageMargin
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.paddingSmall
|
||||
text: title
|
||||
truncationMode: TruncationMode.Fade
|
||||
color: note.highlighted ? Theme.highlightColor : Theme.primaryColor
|
||||
|
@ -80,11 +99,12 @@ Page {
|
|||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.horizontalPageMargin
|
||||
anchors.top: titleLabel.bottom
|
||||
anchors.bottomMargin: Theme.paddingSmall
|
||||
anchors.topMargin: Theme.paddingMedium
|
||||
height: Theme.itemSizeExtraLarge
|
||||
text: content
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: 5
|
||||
elide: Text.ElideRight
|
||||
color: note.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
||||
}
|
||||
|
@ -92,14 +112,6 @@ Page {
|
|||
onClicked: pageStack.push(Qt.resolvedUrl("NotePage.qml"), { note: notesList.model.get(index) } )
|
||||
|
||||
menu: ContextMenu {
|
||||
/*Label {
|
||||
id: categoryLabel
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: (typeof category !== 'undefined') ? qsTr("Category") + ": " + category : ""
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.highlightColor
|
||||
visible: text.length > 0
|
||||
}*/
|
||||
Label {
|
||||
id: modifiedLabel
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
@ -130,11 +142,18 @@ Page {
|
|||
}
|
||||
|
||||
ViewPlaceholder {
|
||||
enabled: notesList.count === 0 && !notes.busy
|
||||
enabled: notesList.count === 0 && !notes.busy && !noLoginPlaceholder.enabled
|
||||
text: qsTr("No notes yet")
|
||||
hintText: qsTr("Pull down to add a note")
|
||||
}
|
||||
|
||||
ViewPlaceholder {
|
||||
id: noLoginPlaceholder
|
||||
enabled: (appSettings.server.length === 0 || appSettings.username.length === 0 || appSettings.password.length === 0)
|
||||
text: qsTr("No Nextcloud account")
|
||||
hintText: qsTr("Pull down to go to the settings")
|
||||
}
|
||||
|
||||
VerticalScrollDecorator { flickable: notesList }
|
||||
}
|
||||
}
|
|
@ -9,7 +9,33 @@
|
|||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>FirstPage</name>
|
||||
<name>LoginDialog</name>
|
||||
<message>
|
||||
<source>Login</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(starting with "https://")</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Username</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nextcloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NotePage</name>
|
||||
<message>
|
||||
<source>Edit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NotesPage</name>
|
||||
<message>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -26,6 +52,10 @@
|
|||
<source>Nextcloud Notes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Modified</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -39,42 +69,15 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Modified</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginFlow</name>
|
||||
<message>
|
||||
<source>Reload</source>
|
||||
<source>Update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Login</source>
|
||||
<source>No Nextcloud account</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>https://cloud.nextcloud.com</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nextcloud server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Username</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nextcloud user</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nextcloud App-Password</source>
|
||||
<source>Pull down to go to the settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
|
Loading…
Reference in a new issue