include note feature

This commit is contained in:
zadam 2019-12-30 19:32:45 +01:00
parent 2f711a12f8
commit 0fe91d0184
8 changed files with 137 additions and 100 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -33,6 +33,7 @@ import importService from './services/import.js';
import keyboardActionService from "./services/keyboard_actions.js"; import keyboardActionService from "./services/keyboard_actions.js";
import splitService from "./services/split.js"; import splitService from "./services/split.js";
import optionService from "./services/options.js"; import optionService from "./services/options.js";
import noteContentRenderer from "./services/note_content_renderer.js";
window.glob.isDesktop = utils.isDesktop; window.glob.isDesktop = utils.isDesktop;
window.glob.isMobile = utils.isMobile; window.glob.isMobile = utils.isMobile;
@ -42,6 +43,19 @@ window.glob.getActiveNode = treeService.getActiveNode;
window.glob.getHeaders = server.getHeaders; window.glob.getHeaders = server.getHeaders;
window.glob.showAddLinkDialog = () => import('./dialogs/add_link.js').then(d => d.showDialog()); window.glob.showAddLinkDialog = () => import('./dialogs/add_link.js').then(d => d.showDialog());
window.glob.showIncludeNoteDialog = cb => import('./dialogs/include_note.js').then(d => d.showDialog(cb)); window.glob.showIncludeNoteDialog = cb => import('./dialogs/include_note.js').then(d => d.showDialog(cb));
window.glob.loadIncludedNote = async (noteId, el) => {
const note = await treeCache.getNote(noteId);
if (note) {
$(el).empty().append($("<h3>").append(await linkService.createNoteLink(note.noteId, {
showTooltip: false
})));
const {renderedContent} = await noteContentRenderer.getRenderedContent(note);
$(el).append(renderedContent);
}
};
// this is required by CKEditor when uploading images // this is required by CKEditor when uploading images
window.glob.noteChanged = noteDetailService.noteChanged; window.glob.noteChanged = noteDetailService.noteChanged;
window.glob.refreshTree = treeService.reload; window.glob.refreshTree = treeService.reload;

View File

@ -0,0 +1,107 @@
import server from "./server.js";
import utils from "./utils.js";
import renderService from "./render.js";
import protectedSessionService from "./protected_session.js";
import protectedSessionHolder from "./protected_session_holder.js";
async function getRenderedContent(note) {
const type = getRenderingType(note);
let rendered;
if (type === 'text') {
const fullNote = await server.get('notes/' + note.noteId);
const $content = $("<div>").html(fullNote.content);
if (utils.isHtmlEmpty(fullNote.content)) {
rendered = "";
}
else {
rendered = $content;
}
}
else if (type === 'code') {
const fullNote = await server.get('notes/' + note.noteId);
if (fullNote.content.trim() === "") {
rendered = "";
}
rendered = $("<pre>").text(fullNote.content);
}
else if (type === 'image') {
rendered = $("<img>").attr("src", `api/images/${note.noteId}/${note.title}`);
}
else if (type === 'file') {
function getFileUrl() {
return utils.getUrlForDownload("api/notes/" + note.noteId + "/download");
}
const $downloadButton = $('<button class="file-download btn btn-primary" type="button">Download</button>');
const $openButton = $('<button class="file-open btn btn-primary" type="button">Open</button>');
$downloadButton.on('click', () => utils.download(getFileUrl()));
$openButton.on('click', () => {
if (utils.isElectron()) {
const open = require("open");
open(getFileUrl(), {url: true});
}
else {
window.location.href = getFileUrl();
}
});
// open doesn't work for protected notes since it works through browser which isn't in protected session
$openButton.toggle(!note.isProtected);
rendered = $('<div>')
.append($downloadButton)
.append(' &nbsp; ')
.append($openButton);
}
else if (type === 'render') {
const $el = $('<div>');
await renderService.render(note, $el, this.ctx);
rendered = $el;
}
else if (type === 'protected-session') {
const $button = $(`<button class="btn btn-sm"><span class="bx bx-log-in"></span> Enter protected session</button>`)
.on('click', protectedSessionService.enterProtectedSession);
rendered = $("<div>")
.append("<div>This note is protected and to access it you need to enter password.</div>")
.append("<br/>")
.append($button);
}
else {
rendered = "<em>Content of this note cannot be displayed in the book format</em>";
}
return {
renderedContent: rendered,
type
};
}
function getRenderingType(note) {
let type = note.type;
if (note.isProtected) {
if (protectedSessionHolder.isProtectedSessionAvailable()) {
protectedSessionHolder.touchProtectedSession();
}
else {
type = 'protected-session';
}
}
return type;
}
export default {
getRenderedContent
};

View File

@ -1,10 +1,6 @@
import server from "./server.js";
import linkService from "./link.js"; import linkService from "./link.js";
import utils from "./utils.js";
import treeCache from "./tree_cache.js"; import treeCache from "./tree_cache.js";
import renderService from "./render.js"; import noteContentRenderer from "./note_content_renderer.js";
import protectedSessionHolder from "./protected_session_holder.js";
import protectedSessionService from "./protected_session.js";
const MIN_ZOOM_LEVEL = 1; const MIN_ZOOM_LEVEL = 1;
const MAX_ZOOM_LEVEL = 6; const MAX_ZOOM_LEVEL = 6;
@ -129,10 +125,10 @@ class NoteDetailBook {
async renderIntoElement(note, $container) { async renderIntoElement(note, $container) {
for (const childNote of await note.getChildNotes()) { for (const childNote of await note.getChildNotes()) {
const type = this.getRenderingType(childNote);
const childNotePath = this.ctx.notePath + '/' + childNote.noteId; const childNotePath = this.ctx.notePath + '/' + childNote.noteId;
const {type, renderedContent} = await noteContentRenderer.getRenderedContent(childNote);
const $card = $('<div class="note-book-card">') const $card = $('<div class="note-book-card">')
.attr('data-note-id', childNote.noteId) .attr('data-note-id', childNote.noteId)
.css("flex-basis", ZOOMS[this.zoomLevel].width) .css("flex-basis", ZOOMS[this.zoomLevel].width)
@ -140,7 +136,7 @@ class NoteDetailBook {
.append($('<h5 class="note-book-title">').append(await linkService.createNoteLink(childNotePath, {showTooltip: false}))) .append($('<h5 class="note-book-title">').append(await linkService.createNoteLink(childNotePath, {showTooltip: false})))
.append($('<div class="note-book-content">') .append($('<div class="note-book-content">')
.css("max-height", ZOOMS[this.zoomLevel].height) .css("max-height", ZOOMS[this.zoomLevel].height)
.append(await this.getNoteContent(type, childNote))); .append(renderedContent));
const childCount = childNote.getChildNoteIds().length; const childCount = childNote.getChildNoteIds().length;
@ -158,80 +154,6 @@ class NoteDetailBook {
} }
} }
async getNoteContent(type, note) {
if (type === 'text') {
const fullNote = await server.get('notes/' + note.noteId);
const $content = $("<div>").html(fullNote.content);
if (utils.isHtmlEmpty(fullNote.content)) {
return "";
}
else {
return $content;
}
}
else if (type === 'code') {
const fullNote = await server.get('notes/' + note.noteId);
if (fullNote.content.trim() === "") {
return "";
}
return $("<pre>").text(fullNote.content);
}
else if (type === 'image') {
return $("<img>").attr("src", `api/images/${note.noteId}/${note.title}`);
}
else if (type === 'file') {
function getFileUrl() {
return utils.getUrlForDownload("api/notes/" + note.noteId + "/download");
}
const $downloadButton = $('<button class="file-download btn btn-primary" type="button">Download</button>');
const $openButton = $('<button class="file-open btn btn-primary" type="button">Open</button>');
$downloadButton.on('click', () => utils.download(getFileUrl()));
$openButton.on('click', () => {
if (utils.isElectron()) {
const open = require("open");
open(getFileUrl(), {url: true});
}
else {
window.location.href = getFileUrl();
}
});
// open doesn't work for protected notes since it works through browser which isn't in protected session
$openButton.toggle(!note.isProtected);
return $('<div>')
.append($downloadButton)
.append(' &nbsp; ')
.append($openButton);
}
else if (type === 'render') {
const $el = $('<div>');
await renderService.render(note, $el, this.ctx);
return $el;
}
else if (type === 'protected-session') {
const $button = $(`<button class="btn btn-sm"><span class="bx bx-log-in"></span> Enter protected session</button>`)
.on('click', protectedSessionService.enterProtectedSession);
return $("<div>")
.append("<div>This note is protected and to access it you need to enter password.</div>")
.append("<br/>")
.append($button);
}
else {
return "<em>Content of this note cannot be displayed in the book format</em>";
}
}
/** @return {boolean} true if this is "auto book" activated (empty text note) and not explicit book note */ /** @return {boolean} true if this is "auto book" activated (empty text note) and not explicit book note */
isAutoBook() { isAutoBook() {
return this.ctx.note.type !== 'book'; return this.ctx.note.type !== 'book';
@ -256,21 +178,6 @@ class NoteDetailBook {
} }
} }
getRenderingType(childNote) {
let type = childNote.type;
if (childNote.isProtected) {
if (protectedSessionHolder.isProtectedSessionAvailable()) {
protectedSessionHolder.touchProtectedSession();
}
else {
type = 'protected-session';
}
}
return type;
}
getContent() { getContent() {
// for auto-book cases when renaming title there should be content // for auto-book cases when renaming title there should be content
return ""; return "";

View File

@ -2,6 +2,7 @@ import libraryLoader from "./library_loader.js";
import treeService from './tree.js'; import treeService from './tree.js';
import noteAutocompleteService from './note_autocomplete.js'; import noteAutocompleteService from './note_autocomplete.js';
import mimeTypesService from './mime_types.js'; import mimeTypesService from './mime_types.js';
import treeCache from "./tree_cache.js";
const mentionSetup = { const mentionSetup = {
feeds: [ feeds: [

View File

@ -960,4 +960,11 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
.ck-link-actions .ck-tooltip { .ck-link-actions .ck-tooltip {
/* force hide the tooltip since it shows misleading "open link in new tab */ /* force hide the tooltip since it shows misleading "open link in new tab */
display: none !important; display: none !important;
}
.include-note {
margin: 20px;
padding: 20px;
border-radius: 10px;
background-color: var(--accented-background-color);
} }

View File

@ -63,7 +63,8 @@ async function getNotes(noteIds) {
SELECT SELECT
noteId, noteId,
title, title,
isProtected, contentLength,
isProtected,
type, type,
mime, mime,
isDeleted isDeleted