diff --git a/src/entities/note.js b/src/entities/note.js
index 2db352ec5..24d86b0d8 100644
--- a/src/entities/note.js
+++ b/src/entities/note.js
@@ -74,7 +74,8 @@ class Note extends Entity {
}
if (this.isStringNote()) {
- this.noteContent.content = this.noteContent.content.toString("UTF-8");
+ this.noteContent.content = this.noteContent.content === null
+ ? "" : this.noteContent.content.toString("UTF-8");
}
}
diff --git a/src/public/javascripts/desktop.js b/src/public/javascripts/desktop.js
index 0f5f55da8..556fe96ec 100644
--- a/src/public/javascripts/desktop.js
+++ b/src/public/javascripts/desktop.js
@@ -122,7 +122,7 @@ if (utils.isElectron()) {
setTimeout(async () => {
const parentNode = treeService.getCurrentNode();
- const {note} = await treeService.createNote(parentNode, parentNode.data.noteId, 'into', parentNode.data.isProtected);
+ const {note} = await treeService.createNote(parentNode, parentNode.data.noteId, 'into', "text", parentNode.data.isProtected);
await treeService.activateNote(note.noteId);
diff --git a/src/public/javascripts/mobile.js b/src/public/javascripts/mobile.js
index b529c64d7..86566ddd8 100644
--- a/src/public/javascripts/mobile.js
+++ b/src/public/javascripts/mobile.js
@@ -93,10 +93,10 @@ $("#note-menu-button").click(async e => {
const parentNoteId = node.data.parentNoteId;
const isProtected = treeUtils.getParentProtectedStatus(node);
- treeService.createNote(node, parentNoteId, 'after', isProtected);
+ treeService.createNote(node, parentNoteId, 'after', null, isProtected);
}
else if (cmd === "insertChildNote") {
- treeService.createNote(node, node.data.noteId, 'into');
+ treeService.createNote(node, node.data.noteId, 'into', null);
}
else if (cmd === "delete") {
treeChangesService.deleteNodes([node]);
diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js
index 42b128848..de7c45f25 100644
--- a/src/public/javascripts/services/tree.js
+++ b/src/public/javascripts/services/tree.js
@@ -551,10 +551,13 @@ async function createNewTopLevelNote() {
const rootNode = getNodesByNoteId(hoistedNoteId)[0];
- await createNote(rootNode, hoistedNoteId, "into", false);
+ await createNote(rootNode, hoistedNoteId, "into", null, false);
}
-async function createNote(node, parentNoteId, target, isProtected, saveSelection = false) {
+/**
+ * @param type - type can be falsy - in that case it will be chosen automatically based on parent note
+ */
+async function createNote(node, parentNoteId, target, type, isProtected, saveSelection = false) {
utils.assertArguments(node, parentNoteId, target);
// if isProtected isn't available (user didn't enter password yet), then note is created as unencrypted
@@ -586,7 +589,8 @@ async function createNote(node, parentNoteId, target, isProtected, saveSelection
content: content,
target: target,
target_branchId: node.data.branchId,
- isProtected: isProtected
+ isProtected: isProtected,
+ type: type
});
if (saveSelection) {
@@ -695,13 +699,13 @@ utils.bindShortcut('ctrl+o', async () => {
return;
}
- createNote(node, parentNoteId, 'after', isProtected, true);
+ createNote(node, parentNoteId, 'after', null, isProtected, true);
});
function createNoteInto() {
const node = getCurrentNode();
- createNote(node, node.data.noteId, 'into', node.data.isProtected, true);
+ createNote(node, node.data.noteId, 'into', null, node.data.isProtected, true);
}
window.glob.createNoteInto = createNoteInto;
diff --git a/src/public/javascripts/services/tree_context_menu.js b/src/public/javascripts/services/tree_context_menu.js
index 90bba0dbd..30b061002 100644
--- a/src/public/javascripts/services/tree_context_menu.js
+++ b/src/public/javascripts/services/tree_context_menu.js
@@ -77,38 +77,42 @@ function cut(nodes) {
infoService.showMessage("Note(s) have been cut into clipboard.");
}
-const noteTypeItems = [
- {title: "Plain text", cmd: "insertNoteAfter", uiIcon: "file"},
- {title: "Terminal", cmd: "insertNoteAfter", uiIcon: "terminal"},
- {title: "Saved search", cmd: "insertNoteAfter", uiIcon: "search-folder"},
- {title: "Relation Map", cmd: "insertNoteAfter", uiIcon: "map"},
- {title: "Render HTML note", cmd: "insertNoteAfter", uiIcon: "play"}
-];
+function getNoteTypeItems(baseCmd) {
+ return [
+ { title: "Text", cmd: baseCmd + "_text", uiIcon: "file" },
+ { title: "Code", cmd: baseCmd + "_code", uiIcon: "terminal" },
+ { title: "Saved search", cmd: baseCmd + "_search", uiIcon: "search-folder" },
+ { title: "Relation Map", cmd: baseCmd + "_relation-map", uiIcon: "map" },
+ { title: "Render HTML note", cmd: baseCmd + "_render", uiIcon: "play" }
+ ];
+}
-const contextMenuItems = [
- {title: "Insert note after Ctrl+O", cmd: "insertNoteAfter", uiIcon: "plus", items: noteTypeItems},
- {title: "Insert child note Ctrl+P", cmd: "insertChildNote", uiIcon: "plus", items: noteTypeItems},
- {title: "Delete Delete", cmd: "delete", uiIcon: "trash"},
- {title: "----"},
- {title: "Hoist note Ctrl-H", cmd: "hoist", uiIcon: "arrow-up"},
- {title: "Unhoist note Ctrl-H", cmd: "unhoist", uiIcon: "arrow-up"},
- {title: "Edit branch prefix F2", cmd: "editBranchPrefix", uiIcon: "pencil"},
- {title: "----"},
- {title: "Protect subtree", cmd: "protectSubtree", uiIcon: "shield-check"},
- {title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield-close"},
- {title: "----"},
- {title: "Copy / clone Ctrl+C", cmd: "copy", uiIcon: "files"},
- {title: "Cut Ctrl+X", cmd: "cut", uiIcon: "scissors"},
- {title: "Paste into Ctrl+V", cmd: "pasteInto", uiIcon: "clipboard"},
- {title: "Paste after", cmd: "pasteAfter", uiIcon: "clipboard"},
- {title: "----"},
- {title: "Export", cmd: "export", uiIcon: "arrow-up-right"},
- {title: "Import into note", cmd: "importIntoNote", uiIcon: "arrow-down-left"},
- {title: "----"},
- {title: "Collapse subtree Alt+-", cmd: "collapseSubtree", uiIcon: "align-justify"},
- {title: "Force note sync", cmd: "forceNoteSync", uiIcon: "refresh"},
- {title: "Sort alphabetically Alt+S", cmd: "sortAlphabetically", uiIcon: "arrows-v"}
-];
+function getTopLevelItems(note) {
+ return [
+ { title: "Insert note after Ctrl+O", cmd: "insertNoteAfter", uiIcon: "plus", items: note.type !== 'search' ? getNoteTypeItems("insertNoteAfter") : null },
+ { title: "Insert child note Ctrl+P", cmd: "insertChildNote", uiIcon: "plus", items: note.type !== 'search' ? getNoteTypeItems("insertChildNote") : null },
+ { title: "Delete Delete", cmd: "delete", uiIcon: "trash" },
+ { title: "----" },
+ { title: "Hoist note Ctrl-H", cmd: "hoist", uiIcon: "arrow-up" },
+ { title: "Unhoist note Ctrl-H", cmd: "unhoist", uiIcon: "arrow-up" },
+ { title: "Edit branch prefix F2", cmd: "editBranchPrefix", uiIcon: "pencil" },
+ { title: "----" },
+ { title: "Protect subtree", cmd: "protectSubtree", uiIcon: "shield-check" },
+ { title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield-close" },
+ { title: "----" },
+ { title: "Copy / clone Ctrl+C", cmd: "copy", uiIcon: "files" },
+ { title: "Cut Ctrl+X", cmd: "cut", uiIcon: "scissors" },
+ { title: "Paste into Ctrl+V", cmd: "pasteInto", uiIcon: "clipboard" },
+ { title: "Paste after", cmd: "pasteAfter", uiIcon: "clipboard" },
+ { title: "----" },
+ { title: "Export", cmd: "export", uiIcon: "arrow-up-right" },
+ { title: "Import into note", cmd: "importIntoNote", uiIcon: "arrow-down-left" },
+ { title: "----" },
+ { title: "Collapse subtree Alt+-", cmd: "collapseSubtree", uiIcon: "align-justify" },
+ { title: "Force note sync", cmd: "forceNoteSync", uiIcon: "refresh" },
+ { title: "Sort alphabetically Alt+S", cmd: "sortAlphabetically", uiIcon: "arrows-v" }
+ ];
+}
async function getContextMenuItems(event) {
const node = $.ui.fancytree.getNode(event);
@@ -118,7 +122,7 @@ async function getContextMenuItems(event) {
const isNotRoot = note.noteId !== 'root';
const isHoisted = note.noteId === await hoistedNoteService.getHoistedNoteId();
- const itemsContainer = new ContextMenuItemsContainer(contextMenuItems);
+ const itemsContainer = new ContextMenuItemsContainer(getTopLevelItems(note));
// Modify menu entries depending on node status
itemsContainer.enableItem("insertNoteAfter", isNotRoot && !isHoisted && parentNote.type !== 'search');
@@ -151,14 +155,17 @@ function selectContextMenuItem(event, cmd) {
// context menu is always triggered on current node
const node = treeService.getCurrentNode();
- if (cmd === "insertNoteAfter") {
+ if (cmd.startsWith("insertNoteAfter")) {
const parentNoteId = node.data.parentNoteId;
const isProtected = treeUtils.getParentProtectedStatus(node);
+ const type = cmd.split("_")[1];
- treeService.createNote(node, parentNoteId, 'after', isProtected);
+ treeService.createNote(node, parentNoteId, 'after', type, isProtected);
}
- else if (cmd === "insertChildNote") {
- treeService.createNote(node, node.data.noteId, 'into');
+ else if (cmd.startsWith("insertChildNote")) {
+ const type = cmd.split("_")[1];
+
+ treeService.createNote(node, node.data.noteId, 'into', type);
}
else if (cmd === "editBranchPrefix") {
branchPrefixDialog.showDialog(node);
diff --git a/src/services/notes.js b/src/services/notes.js
index 00d732af0..49db80439 100644
--- a/src/services/notes.js
+++ b/src/services/notes.js
@@ -81,10 +81,6 @@ async function createNewNote(parentNoteId, noteData) {
noteData.type = noteData.type || parentNote.type;
noteData.mime = noteData.mime || parentNote.mime;
- if (noteData.type === 'text' || noteData.type === 'code') {
- noteData.content = noteData.content || "";
- }
-
const note = await new Note({
noteId: noteData.noteId, // optionally can force specific noteId
title: noteData.title,
@@ -93,6 +89,10 @@ async function createNewNote(parentNoteId, noteData) {
mime: noteData.mime || 'text/html'
}).save();
+ if (note.isStringNote()) {
+ noteData.content = noteData.content || "";
+ }
+
note.noteContent = await new NoteContent({
noteId: note.noteId,
content: noteData.content