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