From c83ca78565e33ca40d626574e745f779d973e7c1 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 20 Jan 2020 22:35:52 +0100 Subject: [PATCH] keyboard handlers for dialogs --- .../javascripts/dialogs/note_revisions.js | 2 +- .../javascripts/services/app_context.js | 27 +++++--- .../javascripts/services/dialog_events.js | 63 +++++++++++++++++++ .../javascripts/services/entrypoints.js | 63 ------------------- .../javascripts/services/keyboard_actions.js | 4 +- .../javascripts/widgets/basic_widget.js | 7 ++- .../javascripts/widgets/note_actions.js | 45 ++++++++++--- .../widgets/standard_top_widget.js | 14 +---- src/public/javascripts/widgets/tab_row.js | 47 +++++++------- 9 files changed, 150 insertions(+), 122 deletions(-) create mode 100644 src/public/javascripts/services/dialog_events.js diff --git a/src/public/javascripts/dialogs/note_revisions.js b/src/public/javascripts/dialogs/note_revisions.js index 06cfc926e..4799a0374 100644 --- a/src/public/javascripts/dialogs/note_revisions.js +++ b/src/public/javascripts/dialogs/note_revisions.js @@ -1,7 +1,7 @@ -import noteDetailService from '../services/note_detail.js'; import utils from '../services/utils.js'; import server from '../services/server.js'; import toastService from "../services/toast.js"; +import appContext from "../services/app_context.js"; const $dialog = $("#note-revisions-dialog"); const $list = $("#note-revision-list"); diff --git a/src/public/javascripts/services/app_context.js b/src/public/javascripts/services/app_context.js index b47809e6b..84f10f24b 100644 --- a/src/public/javascripts/services/app_context.js +++ b/src/public/javascripts/services/app_context.js @@ -6,7 +6,6 @@ import treeService from "./tree.js"; import noteDetailService from "./note_detail.js"; import TabContext from "./tab_context.js"; import server from "./server.js"; -import keyboardActionService from "./keyboard_actions.js"; import TabRowWidget from "../widgets/tab_row.js"; import NoteTitleWidget from "../widgets/note_title.js"; import PromotedAttributesWidget from "../widgets/promoted_attributes.js"; @@ -31,10 +30,11 @@ import NoteTypeWidget from "../widgets/note_type.js"; import NoteActionsWidget from "../widgets/note_actions.js"; import protectedSessionHolder from "./protected_session_holder.js"; import bundleService from "./bundle.js"; +import DialogEventComponent from "./dialog_events.js"; class AppContext { constructor() { - this.widgets = []; + this.components = []; /** @type {TabContext[]} */ this.tabContexts = []; this.tabsChangedTaskId = null; @@ -111,8 +111,9 @@ class AppContext { $rightPane.append(widget.render()); } - this.widgets = [ + this.components = [ this.tabRow, + new DialogEventComponent(this), ...leftPaneWidgets, ...centerPaneWidgets, ...rightPaneWidgets @@ -122,13 +123,9 @@ class AppContext { trigger(name, data, sync = false) { this.eventReceived(name, data); - for (const tabContext of this.tabContexts) { + for (const tabContext of this.components) { tabContext.eventReceived(name, data, sync); } - - for (const widget of this.widgets) { - widget.eventReceived(name, data, sync); - } } async eventReceived(name, data, sync) { @@ -225,10 +222,10 @@ class AppContext { activate: true }); } else { - await tabContext.activate(); + await this.activateTab(tabContext.tabId); if (notePath && tabContext.notePath !== notePath) { - await treeService.activateNote(notePath); + await tabContext.setNote(notePath); } } } @@ -245,6 +242,7 @@ class AppContext { // if it's a new tab explicitly by user then it's in background const ctx = new TabContext(this, this.tabRow, state); this.tabContexts.push(ctx); + this.components.push(ctx); return ctx; } else { @@ -273,6 +271,7 @@ class AppContext { openEmptyTab() { const tabContext = new TabContext(this, this.tabRow); this.tabContexts.push(tabContext); + this.components.push(tabContext); return tabContext; } @@ -408,6 +407,14 @@ class AppContext { openNewTabListener() { this.openAndActivateEmptyTab(); } + + removeAllTabsListener() { + // TODO + } + + removeAllTabsExceptForThis() { + // TODO + } } const appContext = new AppContext(); diff --git a/src/public/javascripts/services/dialog_events.js b/src/public/javascripts/services/dialog_events.js new file mode 100644 index 000000000..51f484bf7 --- /dev/null +++ b/src/public/javascripts/services/dialog_events.js @@ -0,0 +1,63 @@ +import Component from "../widgets/component.js"; + +export default class DialogEventComponent extends Component { + jumpToNoteListener() { + import("../dialogs/jump_to_note.js").then(d => d.showDialog()); + } + + showRecentChangesListener() { + import("../dialogs/recent_changes.js").then(d => d.showDialog()); + } + + showAttributesListener() { + import("../dialogs/attributes.js").then(d => d.showDialog()); + } + + showNoteInfoListener() { + import("../dialogs/note_info.js").then(d => d.showDialog()); + } + + showNoteRevisionsListener() { + import("../dialogs/note_revisions.js").then(d => d.showCurrentNoteRevisions()); + } + + showNoteSourceListener() { + import("../dialogs/note_source.js").then(d => d.showDialog()); + } + + showLinkMapListener() { + import("../dialogs/link_map.js").then(d => d.showDialog()); + } + + pasteMarkdownIntoTextListener() { + import("../dialogs/markdown_import.js").then(d => d.importMarkdownInline()); + } + + async cloneNotesToListener() { + // probably should not happen here + const selectedOrActiveNodes = this.appContext.getMainNoteTree().getSelectedOrActiveNodes(); + + const noteIds = selectedOrActiveNodes.map(node => node.data.noteId); + + const d = await import("../dialogs/clone_to.js"); + d.showDialog(noteIds); + } + + async moveNotesToListener() { + const selectedOrActiveNodes = this.appContext.getMainNoteTree().getSelectedOrActiveNodes(); + + const d = await import("../dialogs/move_to.js"); + d.showDialog(selectedOrActiveNodes); + } + + async editBranchPrefixListener() { + const node = this.appContext.getMainNoteTree().getActiveNode(); + + const editBranchPrefixDialog = await import("../dialogs/branch_prefix.js"); + editBranchPrefixDialog.showDialog(node); + } + + addLinkToTextListener() { + import("../dialogs/add_link.js").then(d => d.showDialog()); + } +} \ No newline at end of file diff --git a/src/public/javascripts/services/entrypoints.js b/src/public/javascripts/services/entrypoints.js index 6ab62328a..8e9fb9ef3 100644 --- a/src/public/javascripts/services/entrypoints.js +++ b/src/public/javascripts/services/entrypoints.js @@ -34,46 +34,10 @@ function registerEntrypoints() { jQuery.hotkeys.options.filterContentEditable = false; jQuery.hotkeys.options.filterTextInputs = false; - keyboardActionService.setGlobalActionHandler("AddLinkToText", () => import(ADD_LINK).then(d => d.showDialog())); - keyboardActionService.setGlobalActionHandler('SearchNotes', searchNotesService.toggleSearch); const $noteTabContainer = $("#note-tab-container"); - const showAttributesDialog = () => import(ATTRIBUTES).then(d => d.showDialog()); - $noteTabContainer.on("click", ".show-attributes-button", showAttributesDialog); - keyboardActionService.setGlobalActionHandler("ShowAttributes", showAttributesDialog); - - const showNoteInfoDialog = () => import(NOTE_INFO).then(d => d.showDialog()); - $noteTabContainer.on("click", ".show-note-info-button", showNoteInfoDialog); - keyboardActionService.setGlobalActionHandler("ShowNoteInfo", showNoteInfoDialog); - - const showNoteRevisionsDialog = function() { - if ($(this).hasClass("disabled")) { - return; - } - - import(NOTE_REVISIONS).then(d => d.showCurrentNoteRevisions()); - }; - - $noteTabContainer.on("click", ".show-note-revisions-button", showNoteRevisionsDialog); - keyboardActionService.setGlobalActionHandler("ShowNoteRevisions", showNoteRevisionsDialog); - - const showNoteSourceDialog = function() { - if ($(this).hasClass("disabled")) { - return; - } - - import(NOTE_SOURCE).then(d => d.showDialog()); - }; - - $noteTabContainer.on("click", ".show-source-button", showNoteSourceDialog); - keyboardActionService.setGlobalActionHandler("ShowNoteSource", showNoteSourceDialog); - - const showLinkMapDialog = () => import(LINK_MAP).then(d => d.showDialog()); - $noteTabContainer.on("click", ".show-link-map-button", showLinkMapDialog); - keyboardActionService.setGlobalActionHandler("ShowLinkMap", showLinkMapDialog); - keyboardActionService.setGlobalActionHandler("InsertDateTimeToText", () => { const date = new Date(); const dateString = utils.formatDateTime(date); @@ -81,12 +45,6 @@ function registerEntrypoints() { linkService.addTextToEditor(dateString); }); - keyboardActionService.setGlobalActionHandler("PasteMarkdownIntoText", async () => { - const dialog = await import("../dialogs/markdown_import.js"); - - dialog.importMarkdownInline(); - }); - if (utils.isElectron()) { const openDevTools = () => { require('electron').remote.getCurrentWindow().toggleDevTools(); @@ -141,20 +99,6 @@ function registerEntrypoints() { return false; }); - keyboardActionService.setGlobalActionHandler("CloneNotesTo", () => import(CLONE_TO).then(d => { - const selectedOrActiveNodes = appContext.getMainNoteTree().getSelectedOrActiveNodes(); - - const noteIds = selectedOrActiveNodes.map(node => node.data.noteId); - - d.showDialog(noteIds); - })); - - keyboardActionService.setGlobalActionHandler("MoveNotesTo", () => import(MOVE_TO).then(d => { - const selectedOrActiveNodes = appContext.getMainNoteTree().getSelectedOrActiveNodes(); - - d.showDialog(selectedOrActiveNodes); - })); - keyboardActionService.setGlobalActionHandler("CreateNoteIntoDayNote", async () => { const todayNote = await dateNoteService.getTodayNote(); @@ -172,13 +116,6 @@ function registerEntrypoints() { noteDetailService.focusAndSelectTitle(); }); - keyboardActionService.setGlobalActionHandler("EditBranchPrefix", async () => { - const node = appContext.getMainNoteTree().getActiveNode(); - - const editBranchPrefixDialog = await import("../dialogs/branch_prefix.js"); - editBranchPrefixDialog.showDialog(node); - }); - keyboardActionService.setGlobalActionHandler("ToggleNoteHoisting", async () => { const node = appContext.getMainNoteTree().getActiveNode(); diff --git a/src/public/javascripts/services/keyboard_actions.js b/src/public/javascripts/services/keyboard_actions.js index f641c88ce..d30f687ed 100644 --- a/src/public/javascripts/services/keyboard_actions.js +++ b/src/public/javascripts/services/keyboard_actions.js @@ -87,7 +87,7 @@ function updateDisplayedShortcuts($container) { } }); - $container.find('button[data-kb-action],a.icon-action[data-kb-action]').each(async (i, el) => { + $container.find('button[data-kb-action],a.icon-action[data-kb-action],.kb-in-title').each(async (i, el) => { const actionName = $(el).attr('data-kb-action'); const action = await getAction(actionName, true); @@ -101,8 +101,6 @@ function updateDisplayedShortcuts($container) { }); } -$(() => updateDisplayedShortcuts($(document))); - export default { setGlobalActionHandler, setElementActionHandler, diff --git a/src/public/javascripts/widgets/basic_widget.js b/src/public/javascripts/widgets/basic_widget.js index ce55fe607..2105aac8d 100644 --- a/src/public/javascripts/widgets/basic_widget.js +++ b/src/public/javascripts/widgets/basic_widget.js @@ -1,8 +1,13 @@ import Component from "./component.js"; +import keyboardActionsService from "../services/keyboard_actions.js"; class BasicWidget extends Component { render() { - return this.doRender(); + const $widget = this.doRender(); + + keyboardActionsService.updateDisplayedShortcuts($widget); + + return $widget; } /** diff --git a/src/public/javascripts/widgets/note_actions.js b/src/public/javascripts/widgets/note_actions.js index 8fa255bbd..c8a892b8d 100644 --- a/src/public/javascripts/widgets/note_actions.js +++ b/src/public/javascripts/widgets/note_actions.js @@ -1,4 +1,4 @@ -import BasicWidget from "./basic_widget.js"; +import TabAwareWidget from "./tab_aware_widget.js"; const TPL = ` `; -export default class NoteActionsWidget extends BasicWidget { +export default class NoteActionsWidget extends TabAwareWidget { doRender() { this.$widget = $(TPL); + this.$showRevisionsButton = this.$widget.find('.show-note-revisions-button'); + this.$showRevisionsButton.on('click', e => this.triggerEvent(e, 'showNoteRevisions')); + + this.$showAttributesButton = this.$widget.find('.show-attributes-button'); + this.$showAttributesButton.on('click', e => this.triggerEvent(e, 'showAttributes')); + + this.$showLinkMapButton = this.$widget.find('.show-link-map-button'); + this.$showLinkMapButton.on('click', e => this.triggerEvent(e, 'showLinkMap')); + + this.$showSourceButton = this.$widget.find('.show-source-button'); + this.$showSourceButton.on('click', e => this.triggerEvent(e, 'showSource')); + + this.$showNoteInfoButton = this.$widget.find('.show-note-info-button'); + this.$showNoteInfoButton.on('click', e => this.triggerEvent(e, 'showNoteInfo')); + + this.$exportNoteButton = this.$widget.find('.export-note-button'); + return this.$widget; } + + refreshWithNote(note) { + this.$showSourceButton.prop('disabled', !['text', 'relation-map', 'search', 'code'].includes(note.type)); + this.$exportNoteButton.prop('disabled', note.type !== 'text'); + } + + triggerEvent(e, eventName) { + const $item = $(e.target).closest('dropdown-item'); + + if ($item.is('[disabled]')) { + return; + } + + this.trigger(eventName); + } } \ No newline at end of file diff --git a/src/public/javascripts/widgets/standard_top_widget.js b/src/public/javascripts/widgets/standard_top_widget.js index 2ac4bebec..d682751d7 100644 --- a/src/public/javascripts/widgets/standard_top_widget.js +++ b/src/public/javascripts/widgets/standard_top_widget.js @@ -3,9 +3,6 @@ import HistoryNavigationWidget from "./history_navigation.js"; import keyboardActionService from "../services/keyboard_actions.js"; import protectedSessionService from "../services/protected_session.js"; -const JUMP_TO_NOTE = "../dialogs/jump_to_note.js"; -const RECENT_CHANGES = "../dialogs/recent_changes.js"; - const TPL = `