2020-05-03 19:30:39 +03:00
import QtQuick 2.2
2018-10-16 18:50:58 +03:00
import Sailfish . Silica 1.0
2019-03-11 23:53:04 +03:00
import "../js/showdown/dist/showdown.js" as ShowDown
2018-10-16 18:50:58 +03:00
2018-11-18 13:25:28 +03:00
Dialog {
id: noteDialog
2018-11-30 20:40:03 +03:00
2020-05-01 13:57:43 +03:00
property int id
2020-05-03 19:30:39 +03:00
property var note
2020-06-08 08:53:49 +03:00
onIdChanged: note = notesModel . note ( id )
2020-05-03 19:30:39 +03:00
onNoteChanged: {
if ( note [ "content" ] . split ( '\n' ) [ 0 ] . indexOf ( note [ "title" ] ) > 0 ) {
dialogHeader . title = ""
}
else {
dialogHeader . title = note [ "title" ]
}
favoriteButton . selected = note [ "favorite" ]
categoryField . text = note [ "category" ]
modifiedDetail . modified = note [ "modified" ]
parseContent ( )
}
2020-05-01 13:57:43 +03:00
Connections {
target: notesModel
onNoteUpdated: {
if ( id === noteDialog . id ) {
noteDialog . note = note
}
}
}
2018-11-30 20:40:03 +03:00
2020-05-03 19:30:39 +03:00
acceptDestination: Qt . resolvedUrl ( "EditPage.qml" )
onAcceptPendingChanged: {
if ( acceptPending )
acceptDestinationInstance . id = id
}
onStatusChanged: {
if ( status === PageStatus . Activating ) {
2020-06-08 08:53:49 +03:00
notesModel . note ( id )
2020-05-03 19:30:39 +03:00
}
}
2018-11-27 11:58:21 +03:00
property var showdown: ShowDown . showdown
2018-11-30 17:12:16 +03:00
property var converter: new showdown . Converter (
2018-12-04 17:22:57 +03:00
{ simplifiedAutoLink: true ,
excludeTrailingPunctuationFromURLs: true ,
2018-12-23 03:59:01 +03:00
parseImgDimensions: true ,
2018-12-04 17:22:57 +03:00
strikethrough: true ,
2018-11-30 17:12:16 +03:00
tables: true ,
2018-12-03 22:33:37 +03:00
tasklists: false , // this is handled by the function parseContent() because LinkedLabel HTML support is to basic
2018-12-23 03:59:01 +03:00
smoothLivePreview: true ,
2018-11-30 17:12:16 +03:00
simpleLineBreaks: true ,
emoji: true } )
2018-11-18 13:25:28 +03:00
2018-12-03 22:33:37 +03:00
function parseContent ( ) {
2020-04-12 21:27:54 +03:00
var convertedText = converter . makeHtml ( note [ "content" ] )
2018-11-28 16:05:36 +03:00
var occurence = - 1
2018-12-05 18:38:07 +03:00
convertedText = convertedText . replace ( /^<li>(<p>)?\[ \] (.*)(<.*)$/gmi ,
function ( match , p1 , p2 , p3 , offset ) {
2018-11-28 16:05:36 +03:00
occurence ++
2018-12-11 15:34:17 +03:00
return '<li class="tasklist"><a class="checkbox" href="tasklist:checkbox_' + occurence + '">' + ( p1 ? p1 : "" ) + '☐ ' + p2 + '</a>' + p3
2018-11-28 16:05:36 +03:00
} )
occurence = - 1
2018-12-05 18:38:07 +03:00
convertedText = convertedText . replace ( /^<li>(<p>)?\[[xX]\] (.*)(<.*)$/gmi ,
function ( match , p1 , p2 , p3 , offset ) {
2018-11-28 16:05:36 +03:00
occurence ++
2018-12-11 15:34:17 +03:00
return '<li class="tasklist"><a class="checkbox" href="tasklist:uncheckbox_' + occurence + '">' + ( p1 ? p1 : "" ) + '☑ ' + p2 + '</a>' + p3
2018-11-28 16:05:36 +03:00
} )
2018-12-23 03:59:01 +03:00
convertedText = convertedText . replace ( /<table>/gmi , "<table border='1' cellpadding='" + Theme . paddingMedium + "'>" )
2018-12-26 23:51:20 +03:00
convertedText = convertedText . replace ( /<del>(.*)<\/del>/gmi , function ( match , p1 ) { return "<s>" + p1 + "</s>" } )
convertedText = convertedText . replace ( /<hr \/>/gmi , "<p><img width=\"" + contentLabel . width + "\" height=\"1\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAPSURBVHjaYvr//z9AgAEABgYDACuJdK0AAAAASUVORK5CYII=\" /></p>" )
2018-12-11 15:34:17 +03:00
contentLabel . text = "<style>\n" +
2018-12-27 22:38:14 +03:00
"p,ul,ol,table,img { margin: " + Theme . paddingLarge + "px 0px; }\n" +
2018-12-04 17:22:57 +03:00
"a:link { color: " + Theme . primaryColor + "; }\n" +
2018-12-11 15:34:17 +03:00
"a.checkbox { text-decoration: none; padding: " + Theme . paddingSmall + "px; display: inline-block; }\n" +
"li.tasklist { font-size:large; margin: " + Theme . paddingMedium + "px 0px; }\n" +
"table { border-color: " + Theme . secondaryColor + "; }\n" +
"</style>\n" + convertedText
2018-12-27 22:38:14 +03:00
//if (debug) console.log(contentLabel.text)
2018-11-24 21:34:01 +03:00
}
2018-10-16 18:50:58 +03:00
SilicaFlickable {
anchors.fill: parent
2018-12-13 01:10:45 +03:00
contentHeight: mainColumn . height + Theme . paddingLarge
2018-10-16 18:50:58 +03:00
Column {
2018-11-26 19:21:33 +03:00
id: mainColumn
2018-10-21 02:44:23 +03:00
width: parent . width
2018-11-26 19:21:33 +03:00
2018-11-24 21:34:01 +03:00
RemorsePopup {
id: remorse
onTriggered: pageStack . pop ( )
}
PullDownMenu {
2019-11-12 01:23:41 +03:00
busy: notesApi . busy
2018-11-24 21:34:01 +03:00
MenuItem {
text: qsTr ( "Delete" )
2020-05-05 20:44:31 +03:00
onClicked: remorse . execute ( "Deleting" , function ( ) { notesModel . deleteNote ( note [ "id" ] ) } )
2018-11-24 21:34:01 +03:00
}
MenuItem {
text: enabled ? qsTr ( "Reload" ) : qsTr ( "Updating..." )
2019-11-12 01:23:41 +03:00
enabled: ! notesApi . busy
2020-06-08 08:53:49 +03:00
onClicked: notesModel . note ( note [ "id" ] )
2018-11-24 21:34:01 +03:00
}
2020-05-03 19:30:39 +03:00
/ * M e n u I t e m {
text: qsTr ( "Edit" )
onClicked: pageStack . push ( Qt . resolvedUrl ( "../pages/NotePage.qml" ) , { id: id } )
} * /
2018-11-24 21:34:01 +03:00
MenuLabel {
2018-12-07 02:30:18 +03:00
visible: appSettings . currentAccount . length >= 0
text: qsTr ( "Last update" ) + ": " + (
2020-01-04 16:53:50 +03:00
new Date ( account . update ) . valueOf ( ) !== 0 ?
new Date ( account . update ) . toLocaleString ( Qt . locale ( ) , Locale . ShortFormat ) :
2018-12-07 02:30:18 +03:00
qsTr ( "never" ) )
2018-11-24 21:34:01 +03:00
}
}
2018-10-16 18:50:58 +03:00
2018-11-18 13:25:28 +03:00
DialogHeader {
2018-11-18 17:01:32 +03:00
id: dialogHeader
2018-11-18 13:25:28 +03:00
acceptText: qsTr ( "Edit" )
cancelText: qsTr ( "Notes" )
2018-12-23 03:59:01 +03:00
}
BusyIndicator {
parent: dialogHeader . extraContent
anchors.verticalCenter: parent . verticalCenter
anchors.horizontalCenter: parent . horizontalCenter
size: BusyIndicatorSize . Medium
2019-11-12 01:23:41 +03:00
running: notesApi . busy
2018-10-16 18:50:58 +03:00
}
2018-11-26 19:21:33 +03:00
Column {
width: parent . width
spacing: Theme . paddingLarge
LinkedLabel {
id: contentLabel
x: Theme . horizontalPageMargin
width: parent . width - 2 * x
2018-12-04 17:22:57 +03:00
textFormat: Text . RichText
linkColor: Theme . primaryColor
2018-11-28 16:05:36 +03:00
defaultLinkActions: false
onLinkActivated: {
2018-12-05 19:09:02 +03:00
//console.log(link)
2018-11-28 16:05:36 +03:00
var occurence = - 1
2020-04-12 21:27:54 +03:00
var newContent = note [ "content" ]
2018-11-28 16:05:36 +03:00
if ( /^tasklist:checkbox_(\d+)$/m . test ( link ) ) {
2018-12-05 18:38:07 +03:00
newContent = newContent . replace ( /- \[ \] (.*)$/gm ,
2018-11-28 16:05:36 +03:00
function ( match , p1 , offset , string ) {
occurence ++
if ( occurence === parseInt ( link . split ( '_' ) [ 1 ] ) ) {
2018-12-04 13:44:06 +03:00
return ( appSettings . useCapitalX ? '- [X] ' : '- [x] ' ) + p1 }
2018-12-03 22:33:37 +03:00
else { return match }
2018-11-28 16:05:36 +03:00
} )
2020-05-04 21:15:17 +03:00
note [ "content" ] = newContent
2018-12-03 22:33:37 +03:00
parseContent ( )
2020-05-05 20:44:31 +03:00
notesModel . updateNote ( id , { 'content' : note [ "content" ] } )
2018-11-28 16:05:36 +03:00
}
else if ( /^tasklist:uncheckbox_(\d+)$/m . test ( link ) ) {
2018-12-05 18:38:07 +03:00
newContent = newContent . replace ( /- \[[xX]\] (.*)$/gm ,
2018-11-28 16:05:36 +03:00
function ( match , p1 , offset , string ) {
occurence ++
if ( occurence === parseInt ( link . split ( '_' ) [ 1 ] ) ) {
2018-12-03 22:33:37 +03:00
return '- [ ] ' + p1 }
else { return match }
2018-11-28 16:05:36 +03:00
} )
2020-05-04 21:15:17 +03:00
note [ "content" ] = newContent
2018-12-03 22:33:37 +03:00
parseContent ( )
2020-05-05 20:44:31 +03:00
notesModel . updateNote ( id , { 'content' : note [ "content" ] } )
2018-11-28 16:05:36 +03:00
}
else {
Qt . openUrlExternally ( link )
}
}
2018-11-26 19:21:33 +03:00
}
Separator {
width: parent . width
color: Theme . primaryColor
horizontalAlignment: Qt . AlignHCenter
}
2018-12-07 02:30:18 +03:00
Flow {
x: Theme . horizontalPageMargin
width: parent . width - 2 * x
spacing: Theme . paddingMedium
visible: opacity > 0.0
opacity: categoryField . focus ? 1.0 : 0.0
Behavior on opacity { FadeAnimator { } }
Repeater {
id: categoryRepeater
2019-11-12 01:23:41 +03:00
model: notesApi . categories
2018-12-07 02:30:18 +03:00
BackgroundItem {
id: categoryBackground
width: categoryRectangle . width
height: categoryRectangle . height
Rectangle {
id: categoryRectangle
width: categoryLabel . width + Theme . paddingLarge
height: categoryLabel . height + Theme . paddingSmall
color: "transparent"
border.color: Theme . highlightColor
radius: height / 4
Label {
id: categoryLabel
anchors.centerIn: parent
text: modelData
color: categoryBackground . highlighted ? Theme.highlightColor : Theme . primaryColor
font.pixelSize: Theme . fontSizeSmall
2018-12-06 15:37:29 +03:00
}
}
2018-12-07 02:30:18 +03:00
onClicked: categoryField . text = modelData
2018-12-06 15:37:29 +03:00
}
}
2018-12-07 02:30:18 +03:00
}
}
Row {
x: Theme . horizontalPageMargin
width: parent . width - x
IconButton {
id: favoriteButton
2020-05-03 19:30:39 +03:00
property bool selected: false
2018-12-07 02:30:18 +03:00
width: Theme . iconSizeMedium
icon.source: ( selected ? "image://theme/icon-m-favorite-selected?" : "image://theme/icon-m-favorite?" ) +
( favoriteButton . highlighted ? Theme.secondaryHighlightColor : Theme . secondaryColor )
onClicked: {
2020-05-05 20:44:31 +03:00
notesModel . updateNote ( note [ "id" ] , { 'favorite' : selected , 'modified' : new Date ( ) . valueOf ( ) / 1000 } )
2018-12-03 22:33:37 +03:00
}
2018-12-07 02:30:18 +03:00
}
TextField {
id: categoryField
width: parent . width - favoriteButton . width
placeholderText: qsTr ( "No category" )
label: qsTr ( "Category" )
EnterKey.iconSource: "image://theme/icon-m-enter-accept"
EnterKey.onClicked: {
categoryField . focus = false
}
onFocusChanged: {
2020-05-03 19:30:39 +03:00
if ( focus === false && text !== note [ "category" ] ) {
2020-05-05 20:44:31 +03:00
notesModel . updateNote ( id , { 'content' : note [ "content" ] , 'category' : text , 'modified' : new Date ( ) . valueOf ( ) / 1000 } ) // This does not seem to work without adding the content
2018-12-07 02:30:18 +03:00
}
2018-12-04 17:22:57 +03:00
}
}
2018-10-16 18:50:58 +03:00
}
2018-12-07 02:30:18 +03:00
DetailItem {
id: modifiedDetail
label: qsTr ( "Modified" )
2020-05-03 19:30:39 +03:00
property int modified
onModifiedChanged: value = new Date ( modified * 1000 ) . toLocaleString ( Qt . locale ( ) , Locale . ShortFormat )
2018-12-07 02:30:18 +03:00
}
2018-10-16 18:50:58 +03:00
}
2018-10-21 02:44:23 +03:00
2018-10-16 18:50:58 +03:00
VerticalScrollDecorator { }
}
2018-12-04 19:24:45 +03:00
allowedOrientations: defaultAllowedOrientations
2018-10-16 18:50:58 +03:00
}