diff --git a/src/public/javascripts/dialogs/move_to.js b/src/public/javascripts/dialogs/move_to.js index d2561f618..aedadbe52 100644 --- a/src/public/javascripts/dialogs/move_to.js +++ b/src/public/javascripts/dialogs/move_to.js @@ -4,16 +4,17 @@ import toastService from "../services/toast.js"; import treeCache from "../services/tree_cache.js"; import treeChangesService from "../services/branches.js"; import appContext from "../services/app_context.js"; +import treeService from "../services/tree.js"; const $dialog = $("#move-to-dialog"); const $form = $("#move-to-form"); const $noteAutoComplete = $("#move-to-note-autocomplete"); const $noteList = $("#move-to-note-list"); -let movedNodes; +let movedBranchIds; -export async function showDialog(nodes) { - movedNodes = nodes; +export async function showDialog(branchIds) { + movedBranchIds = branchIds; utils.openDialog($dialog); @@ -21,8 +22,9 @@ export async function showDialog(nodes) { $noteList.empty(); - for (const node of movedNodes) { - const note = await treeCache.getNote(node.data.noteId); + for (const branchId of movedBranchIds) { + const branch = treeCache.getBranch(branchId); + const note = await treeCache.getNote(branch.noteId); $noteList.append($("
  • ").text(note.title)); } @@ -31,13 +33,12 @@ export async function showDialog(nodes) { noteAutocompleteService.showRecentNotes($noteAutoComplete); } -async function moveNotesTo(notePath) { - // FIXME - const targetNode = await appContext.getMainNoteTree().getNodeFromPath(notePath); +async function moveNotesTo(parentNoteId) { + await treeChangesService.moveToParentNote(movedBranchIds, parentNoteId); - await treeChangesService.moveToParentNote(movedNodes, targetNode); + const parentNote = await treeCache.getNote(parentNoteId); - toastService.showMessage(`Selected notes have been moved into ${targetNode.title}`); + toastService.showMessage(`Selected notes have been moved into ${parentNote.title}`); } $form.on('submit', () => { @@ -46,7 +47,9 @@ $form.on('submit', () => { if (notePath) { $dialog.modal('hide'); - moveNotesTo(notePath); + const noteId = treeService.getNoteIdFromNotePath(notePath); + + moveNotesTo(noteId); } else { console.error("No path to move to."); diff --git a/src/public/javascripts/services/app_context.js b/src/public/javascripts/services/app_context.js index 4f66cf9e6..dcdca2652 100644 --- a/src/public/javascripts/services/app_context.js +++ b/src/public/javascripts/services/app_context.js @@ -1,7 +1,7 @@ import server from "./server.js"; import treeCache from "./tree_cache.js"; import bundleService from "./bundle.js"; -import DialogEventComponent from "./dialog_events.js"; +import DialogCommandExecutor from "./dialog_command_executor.js"; import Entrypoints from "./entrypoints.js"; import options from "./options.js"; import utils from "./utils.js"; @@ -15,6 +15,7 @@ class AppContext { this.layout = layout; this.tabManager = new TabManager(this); this.components = []; + this.executors = []; } async start() { @@ -42,8 +43,11 @@ class AppContext { this.components = [ this.tabManager, rootContainer, - new Entrypoints(this), - new DialogEventComponent(this) + new Entrypoints(this) + ]; + + this.executors = [ + new DialogCommandExecutor(this, this) ]; if (utils.isElectron()) { @@ -80,6 +84,30 @@ class AppContext { this.trigger('treeCacheReloaded'); } + + async triggerCommand(name, data) { + for (const executor of this.executors) { + const fun = executor[name + 'Command']; + + const called = await this.callMethod(executor, fun, data); + + if (called) { + return; + } + } + + console.error(`Unhandled command ${name}`); + } + + async callMethod(thiz, fun, data) { + if (typeof fun !== 'function') { + return false; + } + + await fun.call(thiz, data); + + return true; + } } const layout = new Layout(); diff --git a/src/public/javascripts/services/dialog_events.js b/src/public/javascripts/services/dialog_command_executor.js similarity index 69% rename from src/public/javascripts/services/dialog_events.js rename to src/public/javascripts/services/dialog_command_executor.js index ba7b50cae..6d5a7e132 100644 --- a/src/public/javascripts/services/dialog_events.js +++ b/src/public/javascripts/services/dialog_command_executor.js @@ -1,39 +1,39 @@ import Component from "../widgets/component.js"; -export default class DialogEventComponent extends Component { - jumpToNoteListener() { +export default class DialogCommandExecutor extends Component { + jumpToNoteCommand() { import("../dialogs/jump_to_note.js").then(d => d.showDialog()); } - showRecentChangesListener() { + showRecentChangesCommand() { import("../dialogs/recent_changes.js").then(d => d.showDialog()); } - showAttributesListener() { + showAttributesCommand() { import("../dialogs/attributes.js").then(d => d.showDialog()); } - showNoteInfoListener() { + showNoteInfoCommand() { import("../dialogs/note_info.js").then(d => d.showDialog()); } - showNoteRevisionsListener() { + showNoteRevisionsCommand() { import("../dialogs/note_revisions.js").then(d => d.showCurrentNoteRevisions()); } - showNoteSourceListener() { + showNoteSourceCommand() { import("../dialogs/note_source.js").then(d => d.showDialog()); } - showLinkMapListener() { + showLinkMapCommand() { import("../dialogs/link_map.js").then(d => d.showDialog()); } - pasteMarkdownIntoTextListener() { + pasteMarkdownIntoTextCommand() { import("../dialogs/markdown_import.js").then(d => d.importMarkdownInline()); } - async cloneNotesToListener() { + async cloneNotesToCommand() { // FIXME const selectedOrActiveNodes = this.appContext.getMainNoteTree().getSelectedOrActiveNodes(); @@ -43,15 +43,7 @@ export default class DialogEventComponent extends Component { d.showDialog(noteIds); } - async moveNotesToListener() { - // FIXME - const selectedOrActiveNodes = this.appContext.getMainNoteTree().getSelectedOrActiveNodes(); - - const d = await import("../dialogs/move_to.js"); - d.showDialog(selectedOrActiveNodes); - } - - async editBranchPrefixListener() { + async editBranchPrefixCommand() { const notePath = this.appContext.tabManager.getActiveTabNotePath(); if (notePath) { @@ -60,7 +52,12 @@ export default class DialogEventComponent extends Component { } } - addLinkToTextListener() { + addLinkToTextCommand() { import("../dialogs/add_link.js").then(d => d.showDialog()); } + + async moveBranchIdsToCommand({branchIds}) { + const d = await import("../dialogs/move_to.js"); + d.showDialog(branchIds); + } } \ No newline at end of file diff --git a/src/public/javascripts/services/tree_context_menu.js b/src/public/javascripts/services/tree_context_menu.js index 1993a6a0d..83b70689c 100644 --- a/src/public/javascripts/services/tree_context_menu.js +++ b/src/public/javascripts/services/tree_context_menu.js @@ -149,9 +149,7 @@ class TreeContextMenu { clipboard.cut(this.getSelectedOrActiveBranchIds()); } else if (cmd === "moveTo") { - const nodes = this.treeWidget.getSelectedOrActiveNodes(this.node); - - import("../dialogs/move_to.js").then(d => d.showDialog(nodes)); + this.treeWidget.triggerCommand('moveNotesTo'); } else if (cmd === "pasteAfter") { clipboard.pasteAfter(this.node.data.branchId); diff --git a/src/public/javascripts/widgets/component.js b/src/public/javascripts/widgets/component.js index b7148bd4e..c8294cfd5 100644 --- a/src/public/javascripts/widgets/component.js +++ b/src/public/javascripts/widgets/component.js @@ -27,20 +27,7 @@ export default class Component { const start = Date.now(); - if (typeof fun === 'function') { - let release; - - try { - release = await this.mutex.acquire(); - - await fun.call(this, data); - } - finally { - if (release) { - release(); - } - } - } + await this.callMethod(fun, data); const end = Date.now(); @@ -65,7 +52,33 @@ export default class Component { await Promise.all(promises); } - triggerCommand(name, data) { + async triggerCommand(name, data) { + const fun = this[name + 'Command']; + const called = await this.callMethod(fun, data); + + if (!called) { + await this.parent.triggerCommand(name, data); + } + } + + async callMethod(fun, data) { + if (typeof fun !== 'function') { + return false; + } + + let release; + + try { + release = await this.mutex.acquire(); + + await fun.call(this, data); + + return true; + } finally { + if (release) { + release(); + } + } } } \ No newline at end of file diff --git a/src/public/javascripts/widgets/note_tree.js b/src/public/javascripts/widgets/note_tree.js index d81ca9d88..496f723da 100644 --- a/src/public/javascripts/widgets/note_tree.js +++ b/src/public/javascripts/widgets/note_tree.js @@ -616,4 +616,10 @@ export default class NoteTreeWidget extends TabAwareWidget { treeCacheReloadedListener() { this.reloadTreeFromCache(); } + + async moveNotesToCommand() { + const selectedOrActiveBranchIds = this.getSelectedOrActiveNodes().map(node => node.data.branchId); + + this.triggerCommand('moveBranchIdsTo', {branchIds: selectedOrActiveBranchIds}); + } } \ No newline at end of file