Add to-do list support (close #5), add overflow menu for action buttons

master
Skylar Ittner 5 years ago
parent f4d7915fbc
commit 061834572a

@ -106,4 +106,36 @@ switch ($VARS['action']) {
$note->saveNote();
returnToSender("");
break;
case "maketodolist":
if (empty($VARS['noteid'])) {
die($Strings->get("invalid parameters"));
}
$note = Note::loadNote($VARS['noteid']);
if (!$note->hasWriteAccess(new User($_SESSION['uid']))) {
die($Strings->get("invalid parameters"));
}
$note->toChecklist();
$note->saveNote();
returnToSender("");
break;
case "togglecheckitem":
if (empty($VARS['noteid'])) {
die($Strings->get("invalid parameters"));
}
$note = Note::loadNote($VARS['noteid']);
if (!$note->hasWriteAccess(new User($_SESSION['uid']))) {
die($Strings->get("invalid parameters"));
}
if (!empty($VARS['text'])) {
$note->toggleChecklistItem($VARS['text']);
$note->saveNote();
}
if (isset($VARS['reload'])) {
returnToSender("");
} else {
http_response_code(204);
}
break;
}

@ -5,7 +5,10 @@
"require": {
"catfan/medoo": "^1.5",
"guzzlehttp/guzzle": "^6.2",
"erusev/parsedown": "^1.7"
"erusev/parsedown": "^1.7",
"leblanc-simon/parsedown-checkbox": "^0.0.2",
"erusev/parsedown-extra": "^0.7.1",
"vanilla/htmlawed": "v2.2.4.1"
},
"license": "MPL-2.0",
"authors": [

130
composer.lock generated

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "1aea304797149ba2b5bccc0f6d82c060",
"content-hash": "b50c578394552657e0fcab936a4b1a01",
"packages": [
{
"name": "catfan/medoo",
@ -111,6 +111,50 @@
],
"time": "2018-03-08T01:11:30+00:00"
},
{
"name": "erusev/parsedown-extra",
"version": "0.7.1",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown-extra.git",
"reference": "0db5cce7354e4b76f155d092ab5eb3981c21258c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/0db5cce7354e4b76f155d092ab5eb3981c21258c",
"reference": "0db5cce7354e4b76f155d092ab5eb3981c21258c",
"shasum": ""
},
"require": {
"erusev/parsedown": "~1.4"
},
"type": "library",
"autoload": {
"psr-0": {
"ParsedownExtra": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "An extension of Parsedown that adds support for Markdown Extra.",
"homepage": "https://github.com/erusev/parsedown-extra",
"keywords": [
"markdown",
"markdown extra",
"parsedown",
"parser"
],
"time": "2015-11-01T10:19:22+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "6.3.3",
@ -292,6 +336,51 @@
],
"time": "2017-03-20T17:10:46+00:00"
},
{
"name": "leblanc-simon/parsedown-checkbox",
"version": "0.0.2",
"source": {
"type": "git",
"url": "https://github.com/leblanc-simon/parsedown-checkbox.git",
"reference": "abd857aafc890f55421c87cb9b3cfe9b2791f23f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/leblanc-simon/parsedown-checkbox/zipball/abd857aafc890f55421c87cb9b3cfe9b2791f23f",
"reference": "abd857aafc890f55421c87cb9b3cfe9b2791f23f",
"shasum": ""
},
"require": {
"erusev/parsedown-extra": "^0.7.1"
},
"type": "library",
"autoload": {
"files": [
"ParsedownCheckbox.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Simon Leblanc",
"email": "contact@leblanc-simon.eu",
"homepage": "https://www.leblanc-simon.fr"
}
],
"description": "An extension of Parsedown and ParsedownExtra that adds support for checkbox",
"homepage": "https://github.com/leblanc-simon/parsedown-checkbox",
"keywords": [
"checkbox",
"markdown",
"markdown extra",
"parsedown",
"parser"
],
"time": "2017-05-10T03:43:13+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
@ -341,6 +430,45 @@
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "vanilla/htmlawed",
"version": "v2.2.4.1",
"source": {
"type": "git",
"url": "https://github.com/vanilla/htmlawed.git",
"reference": "58651edbc4c45a2d6b5254b8a9a69dc63ff1457b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vanilla/htmlawed/zipball/58651edbc4c45a2d6b5254b8a9a69dc63ff1457b",
"reference": "58651edbc4c45a2d6b5254b8a9a69dc63ff1457b",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"tburry/pquery": "~1.0.1"
},
"type": "library",
"autoload": {
"classmap": [
"src/Htmlawed.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Todd Burry",
"email": "todd@vanillaforums.com"
}
],
"description": "A composer wrapper for the htmLawed library to purify & filter HTML. Tested with PHPUnit and PhantomJS!",
"time": "2017-09-13T19:20:25+00:00"
}
],
"packages-dev": [],

@ -12,5 +12,7 @@
"Cancel": "Cancel",
"Save": "Save",
"Close": "Close",
"Refresh": "Refresh"
"Refresh": "Refresh",
"Make a List": "Make a List",
"More": "More"
}

@ -116,9 +116,19 @@ class Note {
* @return string
*/
public function getHTML(bool $fragment = true): string {
$parsedown = new Parsedown;
$parsedown->setSafeMode(true);
return $parsedown->text($this->content);
$parsedown = new ParsedownCheckbox();
$html = $parsedown->text($this->content);
$safehtml = Htmlawed::filter($html, ['safe' => 1]);
if ($fragment) {
return $safehtml;
}
$document = "<!DOCTYPE html>\n"
. "<meta charset=\"UTF-8\">\n"
. "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"
. "<title>" . $this->getCleanTitle() . " (" . $note->getModified() . ")</title>\n"
. "\n"
. $safehtml;
return $document;
}
/**
@ -293,6 +303,47 @@ class Note {
$this->favorite = $favorite;
}
/**
* Convert normal lines of text to checklist items.
*/
public function toChecklist() {
$text = explode("\n", $this->getText());
for ($i = 0; $i < count($text); $i++) {
if (preg_match("/^[^\s\=\#\-<](.+)/", $text[$i])) {
if (count($text) > $i && preg_match("/^[\=-](.+)/", $text[$i + 1])) {
// Don't do it if the next line makes this one a heading
continue;
}
$text[$i] = "- [ ] " . $text[$i];
}
}
$this->setText(implode("\n", $text));
}
/**
* Toggle the checked status of a checklist item.
* @param string $item The text of the item to toggle.
*/
public function toggleChecklistItem(string $item) {
$text = explode("\n", $this->getText());
$item = trim(str_replace("\n", "", $item));
for ($i = 0; $i < count($text); $i++) {
if (!preg_match("/^- \[[Xx ]\] .*/", $text[$i])) {
continue;
}
$linecleaned = trim(preg_replace("/^- \[[Xx ]\] /", "", $text[$i]));
if ($item != $linecleaned) {
continue;
}
if (preg_match("/^- \[[Xx]\] .*/", $text[$i])) {
$text[$i] = preg_replace("/^- \[[Xx]\] /", "- [ ] ", $text[$i]);
} else if (preg_match("/^- \[ \] .*/", $text[$i])) {
$text[$i] = preg_replace("/^- \[ \] /", "- [x] ", $text[$i]);
}
}
$this->setText(implode("\n", $text));
}
/**
* Get this note as an array.
* @return string

@ -107,19 +107,41 @@ foreach ($colors as $c) {
</a>
</div>
<div class="d-none yesscript">
<a class="px-2 py-2 color-btn" href="#" data-toggle="tooltip" title="<?php $Strings->get("Set color"); ?>" data-color="<?php echo $note->getColor(); ?>" data-noteid="<?php echo $note->getID(); ?>">
<i class="fas fa-palette"></i>
<a class="px-2 py-2" href="./action.php?action=maketodolist&noteid=<?php echo $note->getID(); ?>" data-toggle="tooltip" title="<?php $Strings->get("Make a List"); ?>" data-noteid="<?php echo $note->getID(); ?>">
<i class="fas fa-tasks"></i>
</a>
</div>
<div>
<a class="px-2 py-2" href="./action.php?action=downloadnote&noteid=<?php echo $note->getID(); ?>" data-toggle="tooltip" title="<?php $Strings->get('Download'); ?>">
<i class="fas fa-download"></i> <noscript><?php $Strings->get('Download'); ?></noscript>
<div class="d-none yesscript">
<a class="px-2 py-2 color-btn" href="#" data-toggle="tooltip" title="<?php $Strings->get("Set color"); ?>" data-color="<?php echo $note->getColor(); ?>" data-noteid="<?php echo $note->getID(); ?>">
<i class="fas fa-palette"></i>
</a>
</div>
<div>
<a class="px-2 py-2" href="./action.php?action=deletenote&noteid=<?php echo $note->getID(); ?>" data-toggle="tooltip" title="<?php $Strings->get('Delete'); ?>">
<i class="fas fa-trash"></i> <noscript><?php $Strings->get('Delete'); ?></noscript>
</a>
<noscript>
<div>
<a class="px-2 py-2" href="./action.php?action=downloadnote&noteid=<?php echo $note->getID(); ?>" data-toggle="tooltip" title="<?php $Strings->get('Download'); ?>">
<i class="fas fa-download"></i> <?php $Strings->get('Download'); ?>
</a>
</div>
<div>
<a class="px-2 py-2" href="./action.php?action=deletenote&noteid=<?php echo $note->getID(); ?>" data-toggle="tooltip" title="<?php $Strings->get('Delete'); ?>">
<i class="fas fa-trash"></i> <?php $Strings->get('Delete'); ?>
</a>
</div>
</noscript>
<div class="dropdown">
<span data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-offset="0,-70">
<a class="p-2" href="#" id="moreoptionsbtn_<?php echo $note->getID(); ?>" data-tooltip="tooltip" title="<?php $Strings->get('More'); ?>">
<i class="fas fa-ellipsis-v"></i>
</a>
</span>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="moreoptionsbtn_<?php echo $note->getID(); ?>">
<a class="dropdown-item" href="./action.php?action=deletenote&noteid=<?php echo $note->getID(); ?>">
<i class="fas fa-trash"></i> <?php $Strings->get('Delete'); ?>
</a>
<a class="dropdown-item" href="./action.php?action=downloadnote&noteid=<?php echo $note->getID(); ?>">
<i class="fas fa-download"></i> <?php $Strings->get('Download'); ?>
</a>
</div>
</div>
</div>
</div>

@ -24,4 +24,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
.note-text table tbody tr:nth-child(odd) {
background-color: rgba(255,255,255,0.15);
}
.dropdown-menu {
z-index: 9999999;
transform: translate3d(-100px, -85px, 0px) !important;
}
.dropdown-item {
color: #212121 !important;
}
.parsedown-task-list-close {
text-decoration: line-through;
}

@ -22,6 +22,7 @@ setInterval(function () {
var favbtn = notecard.find(".favorite-btn");
notecard.find(".note-text").html(n['html']);
$(".parsedown-task-list input[type=checkbox]").removeAttr("disabled");
if (n.favorite) {
favbtn.addClass("text-warning");
favbtn.html('<i class="fas fa-star"></i>');
@ -43,7 +44,11 @@ $(".notecard").on("click", ".notecard-click2open", function () {
document.location.href = "./app.php?page=editnote&note=" + $(this).parent().data("note");
});
$('[data-toggle="tooltip"]').tooltip();
var tooltipoptions = {
placement: 'bottom'
};
$('[data-toggle="tooltip"]').tooltip(tooltipoptions);
$('[data-tooltip="tooltip"]').tooltip(tooltipoptions);
window.shuffleInstance = new window.Shuffle(document.getElementById('grid'), {
itemSelector: '.grid__brick',
@ -51,4 +56,35 @@ window.shuffleInstance = new window.Shuffle(document.getElementById('grid'), {
});
// Do the opposite of <noscript>
$(".yesscript").removeClass("d-none");
$(".yesscript").removeClass("d-none");
$(".parsedown-task-list input[type=checkbox]").removeAttr("disabled");
$(".note-text").on("click", ".parsedown-task-list", function (e) {
var checkbox = $(this).find("input[type=checkbox]");
var line = $(this);
// The checkbox has already changed by itself if it was clicked directly
var checked = checkbox.prop("checked");
if (e.target.nodeName != "INPUT") {
checked = !checked;
}
console.log(checkbox);
console.log(line);
console.log(checked);
$.post("action.php", {
action: "togglecheckitem",
noteid: $(this).closest(".notecard").data("note"),
text: line.text()
}, function () {
if (checked) {
line.addClass("parsedown-task-list-close");
line.removeClass("parsedown-task-list-open");
checkbox.prop("checked", true);
} else {
line.addClass("parsedown-task-list-open");
line.removeClass("parsedown-task-list-close");
checkbox.prop("checked", false);
}
});
return false;
});
Loading…
Cancel
Save