221 lines
6.9 KiB
QML
221 lines
6.9 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import qs.Commons
|
|
import qs.Services.UI
|
|
import qs.Widgets
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property var pluginApi: null
|
|
property var screen: null
|
|
|
|
// Function to sync all notecard changes before saving
|
|
function syncAllChanges() {
|
|
for (let i = 0; i < noteCardsRepeater.count; i++) {
|
|
const card = noteCardsRepeater.itemAt(i);
|
|
if (card && card.syncChanges) {
|
|
card.syncChanges();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Background MouseArea - ALWAYS closes panel on click
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
z: -1
|
|
|
|
onClicked: {
|
|
const closeButtonOn = root.pluginApi?.pluginSettings?.showCloseButton ?? false;
|
|
if (!closeButtonOn && root.pluginApi && root.screen) {
|
|
root.pluginApi.closePanel(root.screen);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Empty state UI (shown when no notes)
|
|
Item {
|
|
anchors.centerIn: parent
|
|
width: 400
|
|
height: 200
|
|
visible: !(root.pluginApi && root.pluginApi.mainInstance && root.pluginApi.mainInstance.noteCards) || root.pluginApi.mainInstance.noteCards.length === 0
|
|
|
|
ColumnLayout {
|
|
anchors.centerIn: parent
|
|
spacing: 16
|
|
|
|
NIcon {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
icon: "notes"
|
|
pointSize: 64
|
|
color: Color.mOnSurfaceVariant
|
|
opacity: 0.5
|
|
}
|
|
|
|
NText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: pluginApi?.tr("notecards.empty-state")
|
|
font.pointSize: Style.fontSizeL
|
|
font.bold: true
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
|
|
NText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: pluginApi?.tr("notecards.empty-hint")
|
|
font.pointSize: Style.fontSizeM
|
|
color: Color.mOnSurfaceVariant
|
|
opacity: 0.7
|
|
}
|
|
|
|
NButton {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.topMargin: 16
|
|
text: pluginApi?.tr("notecards.create-note")
|
|
icon: "add"
|
|
|
|
onClicked: {
|
|
if (root.pluginApi && root.pluginApi.mainInstance) {
|
|
root.pluginApi.mainInstance.createNoteCard("");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Use ListModel to avoid binding loop
|
|
ListModel {
|
|
id: noteCardsModel
|
|
}
|
|
|
|
property int lastRevision: -1
|
|
|
|
// Manual update function
|
|
function updateNoteCardsModel() {
|
|
noteCardsModel.clear();
|
|
if (root.pluginApi && root.pluginApi.mainInstance) {
|
|
const notes = root.pluginApi.mainInstance.noteCards || [];
|
|
for (let i = 0; i < notes.length; i++) {
|
|
noteCardsModel.append({
|
|
"noteData": notes[i],
|
|
"noteIdx": i
|
|
});
|
|
}
|
|
lastRevision = root.pluginApi.mainInstance.noteCardsRevision || 0;
|
|
}
|
|
}
|
|
|
|
// Timer to check for changes
|
|
Timer {
|
|
id: revisionTimer
|
|
interval: 200
|
|
running: root.visible
|
|
repeat: true
|
|
onTriggered: {
|
|
if (root.pluginApi && root.pluginApi.mainInstance) {
|
|
const currentRevision = root.pluginApi.mainInstance.noteCardsRevision || 0;
|
|
if (currentRevision !== root.lastRevision) {
|
|
root.updateNoteCardsModel();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
updateNoteCardsModel();
|
|
}
|
|
|
|
// Repeater for note cards
|
|
Repeater {
|
|
id: noteCardsRepeater
|
|
model: noteCardsModel
|
|
|
|
NoteCard {
|
|
pluginApi: root.pluginApi
|
|
note: noteData
|
|
noteIndex: noteIdx
|
|
z: 1 // Above background MouseArea
|
|
}
|
|
}
|
|
Rectangle {
|
|
anchors.left: parent.left
|
|
anchors.top: parent.top
|
|
anchors.margins: 16
|
|
width: contentRow.width + 16
|
|
height: 40
|
|
color: Color.mSurfaceVariant
|
|
border.color: Color.mOnSurfaceVariant
|
|
border.width: 1
|
|
radius: Style.radiusM
|
|
visible: (root.pluginApi && root.pluginApi.mainInstance && root.pluginApi.mainInstance.noteCards) ? root.pluginApi.mainInstance.noteCards.length > 0 : false
|
|
z: 2 // Above everything
|
|
|
|
RowLayout {
|
|
id: contentRow
|
|
anchors.centerIn: parent
|
|
spacing: 8
|
|
|
|
// Add note button
|
|
NIconButton {
|
|
width: 28
|
|
height: 28
|
|
icon: "add"
|
|
tooltipText: pluginApi?.tr("notecards.create-note")
|
|
colorBg: Color.mPrimary
|
|
colorFg: Color.mOnPrimary
|
|
colorBgHover: Qt.lighter(Color.mPrimary, 1.2)
|
|
colorFgHover: Color.mOnPrimary
|
|
|
|
onClicked: {
|
|
if (root.pluginApi && root.pluginApi.mainInstance) {
|
|
const count = root.pluginApi.mainInstance.noteCards ? root.pluginApi.mainInstance.noteCards.length : 0;
|
|
const max = root.pluginApi.mainInstance.maxNoteCards || 20;
|
|
|
|
if (count >= max) {
|
|
ToastService.showWarning(pluginApi?.tr("toast.max-notes").replace("{max}", max));
|
|
} else {
|
|
root.pluginApi.mainInstance.createNoteCard("");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Vertical separator
|
|
Rectangle {
|
|
width: 1
|
|
height: 24
|
|
color: Color.mOnSurfaceVariant
|
|
opacity: 0.3
|
|
}
|
|
|
|
// Note icon
|
|
NIcon {
|
|
icon: "note"
|
|
pointSize: 16
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
|
|
// Count text
|
|
NText {
|
|
text: {
|
|
const count = (root.pluginApi && root.pluginApi.mainInstance && root.pluginApi.mainInstance.noteCards) ? root.pluginApi.mainInstance.noteCards.length : 0;
|
|
const max = (root.pluginApi && root.pluginApi.mainInstance) ? (root.pluginApi.mainInstance.maxNoteCards || 20) : 20;
|
|
return count + " / " + max;
|
|
}
|
|
font.pointSize: Style.fontSizeM
|
|
font.bold: true
|
|
color: {
|
|
const count = (root.pluginApi && root.pluginApi.mainInstance && root.pluginApi.mainInstance.noteCards) ? root.pluginApi.mainInstance.noteCards.length : 0;
|
|
const max = (root.pluginApi && root.pluginApi.mainInstance) ? (root.pluginApi.mainInstance.maxNoteCards || 20) : 20;
|
|
return count >= max ? Color.mError : Color.mOnSurfaceVariant;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component.onDestruction: {
|
|
revisionTimer.stop();
|
|
noteCardsModel.clear();
|
|
}
|
|
}
|