keyboard handlers for dialogs

This commit is contained in:
zadam 2020-01-20 22:35:52 +01:00
parent c5eac8f438
commit c83ca78565
9 changed files with 150 additions and 122 deletions

View File

@ -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");

View File

@ -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();

View File

@ -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());
}
}

View File

@ -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();

View File

@ -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,

View File

@ -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;
}
/**

View File

@ -1,4 +1,4 @@
import BasicWidget from "./basic_widget.js";
import TabAwareWidget from "./tab_aware_widget.js";
const TPL = `
<div class="dropdown note-actions">
@ -7,24 +7,53 @@ const TPL = `
<span class="caret"></span>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item show-note-revisions-button" data-bind="css: { disabled: type() == 'file' || type() == 'image' }">Revisions</a>
<a class="dropdown-item show-note-revisions-button">Revisions</a>
<a class="dropdown-item show-attributes-button"><kbd data-kb-action="ShowAttributes"></kbd> Attributes</a>
<a class="dropdown-item show-link-map-button"><kbd data-kb-action="ShowLinkMap"></kbd> Link map</a>
<a class="dropdown-item show-source-button" data-bind="css: { disabled: type() != 'text' && type() != 'code' && type() != 'relation-map' && type() != 'search' }">
<kbd data-kb-action="ShowNoteSource"></kbd>
Note source
</a>
<a class="dropdown-item show-source-button"><kbd data-kb-action="ShowNoteSource"></kbd> Note source</a>
<a class="dropdown-item import-files-button">Import files</a>
<a class="dropdown-item export-note-button" data-bind="css: { disabled: type() != 'text' }">Export note</a>
<a class="dropdown-item export-note-button">Export note</a>
<a class="dropdown-item print-note-button"><kbd data-kb-action="PrintActiveNote"></kbd> Print note</a>
<a class="dropdown-item show-note-info-button"><kbd data-kb-action="ShowNoteInfo"></kbd> Note info</a>
</div>
</div>`;
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);
}
}

View File

@ -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 = `
<div class="standard-top-widget">
<style>
@ -74,15 +71,8 @@ export default class StandardTopWidget extends BasicWidget {
this.$widget.prepend(historyNavigationWidget.render());
const showJumpToNoteDialog = () => import(JUMP_TO_NOTE).then(d => d.showDialog());
this.$widget.find(".jump-to-note-dialog-button").on('click', showJumpToNoteDialog);
const showRecentChanges = () => import(RECENT_CHANGES).then(d => d.showDialog());
this.$widget.find(".recent-changes-button").on('click', showRecentChanges);
// FIXME
keyboardActionService.setGlobalActionHandler("JumpToNote", showJumpToNoteDialog);
keyboardActionService.setGlobalActionHandler("ShowRecentChanges", showRecentChanges);
this.$widget.find(".jump-to-note-dialog-button").on('click', () => this.trigger('jumpToNote'));
this.$widget.find(".recent-changes-button").on('click', () => this.trigger('showRecentChanges'));
this.$widget.find(".enter-protected-session-button").on('click', protectedSessionService.enterProtectedSession);
this.$widget.find(".leave-protected-session-button").on('click', protectedSessionService.leaveProtectedSession);

File diff suppressed because one or more lines are too long