Add ability to preview notes without publishing

Resolves #604
This commit is contained in:
celestora 2022-08-19 20:20:09 +03:00
parent 1a4696da91
commit 6e17c446bf
7 changed files with 100 additions and 1 deletions

View file

@ -75,8 +75,18 @@ class Note extends Postable
"underline", "underline",
]); ]);
$source = NULL;
if(is_null($this->getRecord())) {
if(isset($this->changes["source"]))
$source = $this->changes["source"];
else
throw new \LogicException("Can't render note without content set.");
} else {
$source = $this->getRecord()->source;
}
$purifier = new HTMLPurifier($config); $purifier = new HTMLPurifier($config);
return $purifier->purify($this->getRecord()->source); return $purifier->purify($source);
} }
function getName(): string function getName(): string
@ -91,6 +101,9 @@ class Note extends Postable
function getText(): string function getText(): string
{ {
if(is_null($this->getRecord()))
return $this->renderHTML();
$cached = $this->getRecord()->cached_content; $cached = $this->getRecord()->cached_content;
if(!$cached) { if(!$cached) {
$cached = $this->renderHTML(); $cached = $this->renderHTML();

View file

@ -46,6 +46,29 @@ final class NotesPresenter extends OpenVKPresenter
$this->template->note = $note; $this->template->note = $note;
} }
function renderPreView(): void
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
if($_SERVER["REQUEST_METHOD"] !== "POST") {
header("HTTP/1.1 400 Bad Request");
exit;
}
if(empty($this->postParam("html")) || empty($this->postParam("title"))) {
header("HTTP/1.1 400 Bad Request");
exit(tr("note_preview_empty_err"));
}
$note = new Note;
$note->setSource($this->postParam("html"));
$this->flash("info", tr("note_preview_warn"), tr("note_preview_warn_details"));
$this->template->title = $this->postParam("title");
$this->template->html = $note->getText();
}
function renderCreate(): void function renderCreate(): void
{ {
$this->assertUserLoggedIn(); $this->assertUserLoggedIn();

View file

@ -17,6 +17,7 @@
<input type="hidden" name="hash" value="{$csrfToken}" /> <input type="hidden" name="hash" value="{$csrfToken}" />
<button class="button">{_save}</button> <button class="button">{_save}</button>
<a href="javascript:openPreviewWindow()" style="float: right;">{_note_preview}</a>
</form> </form>
{script "js/node_modules/monaco-editor/min/vs/loader.js"} {script "js/node_modules/monaco-editor/min/vs/loader.js"}
@ -38,5 +39,20 @@
document.querySelector("#noteFactory").addEventListener("submit", function() { document.querySelector("#noteFactory").addEventListener("submit", function() {
document.querySelector("textarea").value = window._editor.getValue(); document.querySelector("textarea").value = window._editor.getValue();
}); });
window._preview = undefined;
function openPreviewWindow() {
if(typeof window._preview != "undefined") {
window._preview.close();
window._preview = undefined;
}
window._preview = window.open("data:text/html,", "_blank", { popup: true });
window._preview.document.write(`<style>form { display: none; }</style><form action="${ location.origin }/notes/prerender" method="POST" enctype="multipart/form-data"><input name="title" /><input name="html" /><input name="hash" /></form>`);
window._preview.document.querySelector("input[name=title]").value = document.querySelector("input[name=name]").value;
window._preview.document.querySelector("input[name=html]").value = window._editor.getValue();
window._preview.document.querySelector("input[name=hash]").value = document.querySelector("meta[name=csrf]").attributes.value.value;
window._preview.document.querySelector("form").submit();
}
</script> </script>
{/block} {/block}

View file

@ -0,0 +1,37 @@
{extends "../@layout.xml"}
{block title}
{$title}
{/block}
{block header}
{$title}
{/block}
{block content}
<style>
.sidebar {
display: none;
}
.page_header {
display: none;
}
.page_content {
display: unset;
width: unset;
}
.page_body {
width: unset;
float: unset;
}
.page_footer {
display: none;
}
</style>
{$html|noescape}
{/block}

View file

@ -241,6 +241,8 @@ routes:
handler: "Notes->list" handler: "Notes->list"
- url: "/note{num}_{num}" - url: "/note{num}_{num}"
handler: "Notes->view" handler: "Notes->view"
- url: "/notes/prerender"
handler: "Notes->preView"
- url: "/notes/create" - url: "/notes/create"
handler: "Notes->create" handler: "Notes->create"
- url: "/note{num}_{num}/edit" - url: "/note{num}_{num}/edit"

View file

@ -357,6 +357,10 @@
"notes_one" = "$1 note"; "notes_one" = "$1 note";
"notes_other" = "$1 notes"; "notes_other" = "$1 notes";
"notes_start_screen" = "With notes, you can share your events with friends and see what's going on with them."; "notes_start_screen" = "With notes, you can share your events with friends and see what's going on with them.";
"note_preview" = "Preview draft";
"note_preview_warn" = "Preview mode active";
"note_preview_warn_details" = "Notes may change their behaviour or looks after being saved. Also, try not to use preview very often.";
"note_preview_empty_err" = "Preview of empty or nameless note? Why, Mr. White?";
"notes_list_zero" = "No notes found"; "notes_list_zero" = "No notes found";
"notes_list_one" = "$1 note found"; "notes_list_one" = "$1 note found";

View file

@ -383,6 +383,10 @@
"edit_note" = "Редактировать заметку"; "edit_note" = "Редактировать заметку";
"actions" = "Действия"; "actions" = "Действия";
"notes_start_screen" = "С помощью заметок Вы можете делиться событиями из жизни с друзьями, а так же быть в курсе того, что происходит у них."; "notes_start_screen" = "С помощью заметок Вы можете делиться событиями из жизни с друзьями, а так же быть в курсе того, что происходит у них.";
"note_preview" = "Предпросмотр";
"note_preview_warn" = "Это всего лишь предпросмотр";
"note_preview_warn_details" = "После сохранения заметки могут выглядеть иначе. К тому же, не вызывайте предпросмотр слишком часто.";
"note_preview_empty_err" = "Зачем вам предпросмотр для заметки без имени или содержания?";
"edited" = "Отредактировано"; "edited" = "Отредактировано";