API Implemented in javascript. Currently just readonly functionality. No possibility to set user credentials
13
harbour-nextcloudnotes.desktop
Normal file
|
@ -0,0 +1,13 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
X-Nemo-Application-Type=silica-qt5
|
||||
Icon=harbour-nextcloudnotes
|
||||
Exec=harbour-nextcloudnotes
|
||||
Name=harbour-nextcloudnotes
|
||||
# translation example:
|
||||
# your app name in German locale (de)
|
||||
#
|
||||
# Remember to comment out the following line, if you do not want to use
|
||||
# a different app name in German locale (de).
|
||||
Name[de]=harbour-nextcloudnotes
|
||||
Name[de_DE]=harbour-nextcloudnotes.desktop
|
43
harbour-nextcloudnotes.pro
Normal file
|
@ -0,0 +1,43 @@
|
|||
# NOTICE:
|
||||
#
|
||||
# Application name defined in TARGET has a corresponding QML filename.
|
||||
# If name defined in TARGET is changed, the following needs to be done
|
||||
# to match new name:
|
||||
# - corresponding QML filename must be changed
|
||||
# - desktop icon filename must be changed
|
||||
# - desktop filename must be changed
|
||||
# - icon definition filename in desktop file must be changed
|
||||
# - translation filenames have to be changed
|
||||
|
||||
# The name of your application
|
||||
TARGET = harbour-nextcloudnotes
|
||||
|
||||
CONFIG += sailfishapp
|
||||
|
||||
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 \
|
||||
rpm/harbour-nextcloudnotes.spec \
|
||||
rpm/harbour-nextcloudnotes.yaml \
|
||||
translations/*.ts \
|
||||
harbour-nextcloudnotes.desktop \
|
||||
qml/pages/NotePage.qml
|
||||
|
||||
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
||||
|
||||
# to disable building translations every time, comment out the
|
||||
# following CONFIG line
|
||||
CONFIG += sailfishapp_i18n
|
||||
|
||||
# German translation is enabled as an example. If you aren't
|
||||
# planning to localize your app, remember to comment out the
|
||||
# following TRANSLATIONS line. And also do not forget to
|
||||
# modify the localized app name in the the .desktop file.
|
||||
TRANSLATIONS += translations/harbour-nextcloudnotes-de.ts
|
||||
|
||||
HEADERS +=
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
@ -9,21 +9,20 @@ ApplicationWindow
|
|||
|
||||
ConfigurationGroup {
|
||||
id: appSettings
|
||||
path: "/apps/harbour-nextcloud-notes/settings"
|
||||
path: "/apps/harbour-nextcloudnotes/settings"
|
||||
property string lastUpdate: qsTr("never")
|
||||
property url nextcloudServer: "https://cloud.scharel.name"
|
||||
property string username: "scharel"
|
||||
property string password: ""
|
||||
property url server: "https://cloud.scharel.name" + "/index.php/apps/notes/api/v0.2/notes"
|
||||
property string username: "test"
|
||||
property string password // TODO provide password before testing
|
||||
}
|
||||
|
||||
property var notesModel: JSONListModel {
|
||||
url: appSettings.nextcloudServer + "/index.php/apps/notes/api/v0.2/notes"
|
||||
property var notes: NotesApi {
|
||||
name: "notes"
|
||||
saveFile: false
|
||||
}
|
||||
Connections {
|
||||
target: notesModel
|
||||
onLastUpdateChanged: appSettings.lastUpdate = notesModel.lastUpdate
|
||||
target: notes
|
||||
onLastUpdateChanged: appSettings.lastUpdate = notes.lastUpdate
|
||||
}
|
||||
|
||||
initialPage: Component { FirstPage { } }
|
|
@ -1,6 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
//import harbour.nextcloudnotes 0.1
|
||||
|
||||
Page {
|
||||
id: page
|
||||
|
@ -10,7 +9,7 @@ Page {
|
|||
anchors.fill: parent
|
||||
|
||||
PullDownMenu {
|
||||
busy: notesModel.busy
|
||||
busy: notes.busy
|
||||
MenuItem {
|
||||
text: qsTr("Settings")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("Settings.qml"))
|
||||
|
@ -20,42 +19,33 @@ Page {
|
|||
onClicked: console.log("Add note")
|
||||
}
|
||||
MenuLabel {
|
||||
text: qsTr("Last update") + ": " + appSettings.lastUpdate
|
||||
text: qsTr("Last update") + ": " + new Date(appSettings.lastUpdate).toLocaleString(Qt.locale(), Locale.ShortFormat)
|
||||
}
|
||||
}
|
||||
|
||||
header: SearchField {
|
||||
width: parent.width
|
||||
placeholderText: qsTr("Nextcloud Notes")
|
||||
onTextChanged: notesModel.search(text.toLowerCase())
|
||||
onTextChanged: notes.search(text.toLowerCase())
|
||||
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||
EnterKey.onClicked: focus = false
|
||||
enabled: notesModel.json.length > 0
|
||||
enabled: notes.json.length > 0
|
||||
}
|
||||
|
||||
currentIndex: -1
|
||||
Component.onCompleted: notesModel.update()
|
||||
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")
|
||||
//Component.onCompleted: notes.deleteNote(1212725)
|
||||
|
||||
model: notesModel
|
||||
model: notes.model
|
||||
|
||||
delegate: ListItem {
|
||||
id: note
|
||||
contentHeight: Theme.itemSizeMedium
|
||||
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("NotePage.qml"),
|
||||
{id: id,
|
||||
etag: etag,
|
||||
modified: modified,
|
||||
title: title,
|
||||
category: category,
|
||||
favorite: favorite,
|
||||
content: content,
|
||||
error: error,
|
||||
errorMessage: errorMessage})
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: isFavoriteIcon
|
||||
x: Theme.horizontalPageMargin
|
||||
|
@ -66,6 +56,7 @@ Page {
|
|||
onClicked: {
|
||||
console.log("Toggle favorite")
|
||||
favorite = !favorite
|
||||
notes.updateNote(id, {'favorite': favorite} )
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,11 +77,13 @@ Page {
|
|||
anchors.leftMargin: Theme.paddingSmall
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.verticalCenter
|
||||
text: new Date(modified * 1000).toLocaleDateString()
|
||||
text: new Date(modified * 1000).toLocaleString(Qt.locale(), Locale.ShortFormat)
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
color: note.highlighted ? Theme.highlightColor : Theme.primaryColor
|
||||
}
|
||||
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("NotePage.qml"), { note: notesList.model.get(index) } )
|
||||
|
||||
menu: ContextMenu {
|
||||
Text {
|
||||
id: descriptionText
|
||||
|
@ -114,17 +107,23 @@ Page {
|
|||
section.criteria: ViewSection.FullString
|
||||
section.labelPositioning: ViewSection.InlineLabels
|
||||
section.delegate: SectionHeader {
|
||||
text: section.empty ? qsTr("No category") : section
|
||||
text: section
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
id: busyIndicator
|
||||
anchors.centerIn: parent
|
||||
size: BusyIndicatorSize.Large
|
||||
visible: notesList.count === 0
|
||||
visible: notesList.count === 0 && notes.busy
|
||||
running: visible
|
||||
}
|
||||
|
||||
ViewPlaceholder {
|
||||
enabled: notesList.count === 0 && !notes.busy
|
||||
text: qsTr("No notes yet")
|
||||
hintText: qsTr("Pull down to add a note")
|
||||
}
|
||||
|
||||
VerticalScrollDecorator { flickable: notesList }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import Sailfish.Silica 1.0
|
|||
Page {
|
||||
id: page
|
||||
|
||||
property var note
|
||||
|
||||
property int id
|
||||
property string etag
|
||||
property date modified
|
||||
|
@ -29,14 +31,13 @@ Page {
|
|||
width: parent.width// - 2*x
|
||||
|
||||
PageHeader {
|
||||
title: page.title
|
||||
title: note.title
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: note
|
||||
width: parent.width
|
||||
readOnly: true
|
||||
text: page.content
|
||||
text: note.content
|
||||
}
|
||||
}
|
||||
VerticalScrollDecorator {}
|
||||
|
|
|
@ -1,17 +1,87 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import Nemo.Configuration 1.0
|
||||
|
||||
ListModel {
|
||||
property url url
|
||||
property string json
|
||||
Item {
|
||||
property string name
|
||||
property var model: ListModel { }
|
||||
|
||||
property string json
|
||||
property string file: StandardPaths.data + "/" + name + ".json"
|
||||
property bool saveFile: false
|
||||
property bool busy: false
|
||||
property int status: 200
|
||||
property date lastUpdate: new Date(0)
|
||||
|
||||
function callApi(method, data) {
|
||||
busy = true
|
||||
|
||||
var endpoint = ""
|
||||
if (data && (method === "GET" || method === "PUT" || method === "DELETE"))
|
||||
if (data.id)
|
||||
endpoint = "/" + data.id
|
||||
|
||||
var apiReq = new XMLHttpRequest
|
||||
apiReq.open(method, appSettings.server + endpoint, true)
|
||||
apiReq.setRequestHeader('User-Agent', 'SailfishOS/harbour-lidderbuch')
|
||||
apiReq.setRequestHeader('OCS-APIRequest', 'true')
|
||||
apiReq.setRequestHeader("Content-Type", "application/json");
|
||||
apiReq.setRequestHeader("Authorization", "Basic " + Qt.btoa(appSettings.username + ":" + appSettings.password))
|
||||
apiReq.onreadystatechange = function() {
|
||||
if (apiReq.readyState === XMLHttpRequest.DONE) {
|
||||
if (apiReq.status === 200) {
|
||||
console.log("Successfull request!")
|
||||
console.log(apiReq.responseText)
|
||||
// TODO handle non arrays
|
||||
var elements = JSON.parse(apiReq.responseText)
|
||||
for (var element in elements) {
|
||||
model.append(elements[element])
|
||||
}
|
||||
}
|
||||
else if (apiReq.status === 404) {
|
||||
console.log("Note does not exist!")
|
||||
}
|
||||
else {
|
||||
console.log("Unknown error: " + apiReq.statusText + " (" + apiReq.status + ")")
|
||||
}
|
||||
busy = false
|
||||
}
|
||||
}
|
||||
if (method === "GET") {
|
||||
apiReq.send()
|
||||
}
|
||||
else if (method === "POST" || method === "PUT" || method === "DELETE") {
|
||||
apiReq.send(JSON.stringify(data))
|
||||
}
|
||||
else {
|
||||
console.log("Unsupported method: " + method)
|
||||
apiReq.abort()
|
||||
}
|
||||
}
|
||||
|
||||
function getNotes() {
|
||||
callApi("GET")
|
||||
}
|
||||
|
||||
function getNote(id) {
|
||||
if (id)
|
||||
callApi("GET", { 'id': id } )
|
||||
}
|
||||
|
||||
function createNote(data) {
|
||||
callApi("POST", data)
|
||||
}
|
||||
|
||||
function updateNote(id, data) {
|
||||
if (id) {
|
||||
data.id = id
|
||||
callApi("PUT", data)
|
||||
}
|
||||
}
|
||||
|
||||
function deleteNote(id) {
|
||||
if (id)
|
||||
callApi("DELETE", { 'id': id } )
|
||||
}
|
||||
|
||||
onJsonChanged: refresh()
|
||||
|
||||
function flush() {
|
||||
|
@ -19,7 +89,7 @@ ListModel {
|
|||
var filePut = new XMLHttpRequest
|
||||
filePut.open("PUT", file)
|
||||
filePut.send(json)
|
||||
clear()
|
||||
model.clear()
|
||||
lastUpdate = new Date(0)
|
||||
status = 200
|
||||
}
|
||||
|
@ -29,7 +99,7 @@ ListModel {
|
|||
}
|
||||
|
||||
function search(query) {
|
||||
clear()
|
||||
model.clear()
|
||||
var elements = parseJson()
|
||||
for (var element in elements) {
|
||||
elements[element].section = ""
|
||||
|
@ -40,7 +110,7 @@ ListModel {
|
|||
}
|
||||
}
|
||||
if (query === "" || match)
|
||||
append(elements[element])
|
||||
model.append(elements[element])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,43 +123,12 @@ ListModel {
|
|||
return null
|
||||
}
|
||||
else {
|
||||
clear()
|
||||
model.clear()
|
||||
return elements
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
busy = true
|
||||
var apiReq = new XMLHttpRequest
|
||||
apiReq.open("GET", url, true)//, appSettings.username, appSettings.password)
|
||||
apiReq.setRequestHeader('User-Agent', 'SailfishOS/harbour-lidderbuch')
|
||||
apiReq.setRequestHeader('OCS-APIRequest', 'true')
|
||||
apiReq.setRequestHeader("Authorization", "Basic " + Qt.btoa(appSettings.username + ":" + appSettings.password))
|
||||
apiReq.onreadystatechange = function() {
|
||||
if (apiReq.readyState === XMLHttpRequest.DONE) {
|
||||
if (apiReq.status === 200) {
|
||||
console.log("Successfully loaded " + url)
|
||||
json = apiReq.responseText
|
||||
//console.log(json)
|
||||
if (saveFile) {
|
||||
var filePut = new XMLHttpRequest
|
||||
filePut.open("PUT", file)
|
||||
filePut.send(json)
|
||||
}
|
||||
lastUpdate = new Date()
|
||||
}
|
||||
else {
|
||||
console.log("Error loading " + url + " - " + apiReq.status)
|
||||
//lastUpdate = new Date(0)
|
||||
}
|
||||
status = apiReq.status
|
||||
busy = false
|
||||
}
|
||||
}
|
||||
apiReq.send()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
/*Component.onCompleted: {
|
||||
if (saveFile) {
|
||||
if (name === "") {
|
||||
saveFile = false
|
||||
|
@ -113,5 +152,5 @@ ListModel {
|
|||
fileReq.send()
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
# Rename this file as harbour-nextcloud-notes.changes to include changelog
|
||||
# Rename this file as harbour-nextcloudnotes.changes to include changelog
|
||||
# entries in your RPM file.
|
||||
#
|
||||
# Add new changelog entries following the format below.
|
||||
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
# Alternatively, if your changelog is automatically generated (e.g. with
|
||||
# the git-change-log command provided with Sailfish OS SDK), create a
|
||||
# harbour-nextcloud-notes.changes.run script to let mb2 run the required commands for you.
|
||||
# harbour-nextcloudnotes.changes.run script to let mb2 run the required commands for you.
|
||||
|
||||
# * date Author's Name <author's email> version-release
|
||||
# - Summary of changes
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Rename this file as harbour-nextcloud-notes.changes.run to let mb2 automatically
|
||||
# Rename this file as harbour-nextcloudnotes.changes.run to let mb2 automatically
|
||||
# generate changelog from well formatted Git commit messages and tag
|
||||
# annotations.
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
# Generated by: spectacle version 0.27
|
||||
#
|
||||
|
||||
Name: harbour-nextcloud-notes
|
||||
Name: harbour-nextcloudnotes
|
||||
|
||||
# >> macros
|
||||
# << macros
|
||||
|
@ -19,7 +19,7 @@ Group: Qt/Qt
|
|||
License: LICENSE
|
||||
URL: http://example.org/
|
||||
Source0: %{name}-%{version}.tar.bz2
|
||||
Source100: harbour-nextcloud-notes.yaml
|
||||
Source100: harbour-nextcloudnotes.yaml
|
||||
Requires: sailfishsilica-qt5 >= 0.10.9
|
||||
BuildRequires: pkgconfig(sailfishapp) >= 1.0.2
|
||||
BuildRequires: pkgconfig(Qt5Core)
|
|
@ -1,4 +1,4 @@
|
|||
Name: harbour-nextcloud-notes
|
||||
Name: harbour-nextcloudnotes
|
||||
Summary: Nextcloud Notes
|
||||
Version: 0.1
|
||||
Release: 1
|
|
@ -8,16 +8,16 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
QGuiApplication* app = SailfishApp::application(argc, argv);
|
||||
app->setApplicationDisplayName("Nextcloud Notes");
|
||||
app->setApplicationName("harbour-nextcloud-notes");
|
||||
app->setApplicationName("harbour-nextcloudnotes");
|
||||
app->setApplicationVersion("0.1");
|
||||
app->setOrganizationDomain("https://github.com/scharel");
|
||||
app->setOrganizationName("harbour-nextcloud-notes");
|
||||
app->setOrganizationName("harbour-nextcloudnotes");
|
||||
|
||||
qDebug() << app->applicationDisplayName() << app->applicationVersion();
|
||||
|
||||
QQuickView* view = SailfishApp::createView();
|
||||
|
||||
view->setSource(SailfishApp::pathTo("qml/harbour-nextcloud-notes.qml"));
|
||||
view->setSource(SailfishApp::pathTo("qml/harbour-nextcloudnotes.qml"));
|
||||
view->show();
|
||||
|
||||
return app->exec();
|
|
@ -18,6 +18,10 @@
|
|||
<source>Add note</source>
|
||||
<translation>Neue Notiz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Last update</source>
|
||||
<translation>Zuletzt aktualisiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nextcloud Notes</source>
|
||||
<translation>Nextcloud Notizen</translation>
|
||||
|
@ -27,16 +31,16 @@
|
|||
<translation>Löschen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No category</source>
|
||||
<translation>Ohne Kategorie</translation>
|
||||
<source>No notes yet</source>
|
||||
<translatio>Noch keine Notizen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Last update</source>
|
||||
<translation>Zuletzt aktualisiert</translation>
|
||||
<source>Pull down to add a note</source>
|
||||
<translation>Herunterziehen um eine neue Notiz zu erzeugen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>harbour-nextcloud-notes</name>
|
||||
<name>harbour-nextcloudnotes</name>
|
||||
<message>
|
||||
<source>never</source>
|
||||
<translation>noch nie</translation>
|
|
@ -18,6 +18,10 @@
|
|||
<source>Add note</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Last update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nextcloud Notes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -27,16 +31,16 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No category</source>
|
||||
<source>No notes yet</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Last update</source>
|
||||
<source>Pull down to add a note</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>harbour-nextcloud-notes</name>
|
||||
<name>harbour-nextcloudnotes</name>
|
||||
<message>
|
||||
<source>never</source>
|
||||
<translation type="unfinished"></translation>
|