Files
harbour-quill/qml/pages/MainPage.qml
T

187 lines
6.2 KiB
QML

import QtQuick 2.2
import Sailfish.Silica 1.0
import "../components"
Page {
id: page
property var dav
property string currentPath: ""
property string coverText: currentPath === "" ? qsTr("Notes") : currentPath
property bool loading: false
property var pendingEditor: null
property var allEntries: []
property string filterText: ""
onFilterTextChanged: page.applyFilter()
onStatusChanged: {
if (status === PageStatus.Active) {
if (page.pendingEditor) {
// New note accepted: the dialog pops itself, then we open the
// editor (push here — after the dialog pop — avoids stack races).
var ed = page.pendingEditor
page.pendingEditor = null
pageStack.push(Qt.resolvedUrl("EditorPage.qml"),
{ dav: page.dav,
notePath: ed.path,
noteName: ed.name,
initialContent: "# " + ed.name.replace(/\.md$/, "") + "\n\n",
skipLoad: true })
} else {
reload()
}
}
}
Component.onCompleted: reload()
function reload() {
if (!dav || dav.busy) return
loading = true
dav.listDir(currentPath)
}
function applyFilter() {
notesModel.clear()
var f = page.filterText.trim().toLowerCase()
for (var i = 0; i < allEntries.length; i++) {
var e = allEntries[i]
// All files are shown (not only .md) — any file can be opened as text.
if (f && e.name.toLowerCase().indexOf(f) < 0) continue
notesModel.append({ name: e.name, path: e.path, isDir: e.isDir, mtime: e.mtime, size: e.size })
}
}
ListModel {
id: notesModel
}
Connections {
target: dav
onListReady: {
loading = false
allEntries = entries
console.log("Quill listReady:", entries.length, "entries in", page.currentPath)
page.applyFilter()
}
// Refresh the list whenever a write completes elsewhere (new note,
// editor save, delete) — the list under the stack stays fresh.
onWriteDone: page.reload()
onDeleteDone: page.reload()
onFailed: {
loading = false
banner.show(message, true)
}
}
SilicaListView {
id: listView
anchors.fill: parent
model: notesModel
header: Column {
width: parent.width
PageHeader { title: "Quill" }
SearchField {
id: searchField
width: parent.width
placeholderText: qsTr("Search")
// Bound to the page property so the delegates (which cannot
// see header ids) can clear it via page.filterText.
text: page.filterText
onTextChanged: {
if (text !== page.filterText) page.filterText = text
}
}
ListItem {
visible: page.currentPath !== ""
contentHeight: Theme.itemSizeSmall
onClicked: {
page.filterText = ""
page.currentPath = ""
page.reload()
}
Label {
anchors.verticalCenter: parent.verticalCenter
x: Theme.paddingLarge
width: parent.width - 2 * Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeSmall
text: "▲ " + page.currentPath
}
}
}
ViewPlaceholder {
enabled: notesModel.count === 0 && !page.loading
text: page.currentPath === "" ? qsTr("No notes yet. Create one from the pulley menu.")
: qsTr("Empty folder")
}
delegate: ListItem {
id: noteItem
contentHeight: Theme.itemSizeMedium
onClicked: {
if (model.isDir) {
page.filterText = ""
page.currentPath = model.path
page.reload()
} else {
pageStack.push(Qt.resolvedUrl("EditorPage.qml"),
{ dav: page.dav, notePath: model.path, noteName: model.name })
}
}
Column {
anchors.verticalCenter: parent.verticalCenter
x: Theme.paddingLarge
width: parent.width - 2 * Theme.paddingLarge
Label {
text: model.name + (model.isDir ? "/" : "")
color: model.isDir ? Theme.highlightColor : Theme.primaryColor
font.pixelSize: Theme.fontSizeMedium
truncationMode: TruncationMode.Fade
}
Label {
visible: !model.isDir
text: model.mtime
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeSmall
truncationMode: TruncationMode.Fade
}
}
}
VerticalScrollDecorator {}
PullDownMenu {
MenuItem {
text: qsTr("Settings")
onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"), { dav: page.dav })
}
MenuItem {
text: qsTr("New note")
onClicked: {
var dlg = pageStack.push(Qt.resolvedUrl("NewNoteDialog.qml"), { dav: page.dav })
dlg.accepted.connect(function () {
if (dlg.resultPath) {
page.pendingEditor = { path: dlg.resultPath, name: dlg.resultName }
}
})
}
}
MenuItem {
text: qsTr("Refresh")
onClicked: page.reload()
}
}
BusyIndicator {
anchors.centerIn: parent
running: page.loading
}
}
Banner { id: banner }
}