converted more keyboard actions

This commit is contained in:
zadam 2020-01-21 22:54:16 +01:00
parent af5c623671
commit c63bb7ce8a
9 changed files with 136 additions and 156 deletions

View File

@ -15,7 +15,7 @@ import treeChanges from './services/branches.js';
import treeUtils from './services/tree_utils.js';
import utils from './services/utils.js';
import server from './services/server.js';
import entrypoints from './services/entrypoints.js';
import Entrypoints from './services/entrypoints.js';
import noteTooltipService from './services/note_tooltip.js';
import bundle from "./services/bundle.js";
import treeCache from "./services/tree_cache.js";
@ -133,8 +133,6 @@ searchNotesService.init(); // should be in front of treeService since that one m
appContext.showWidgets();
entrypoints.registerEntrypoints();
noteTooltipService.setupGlobalTooltip();
noteAutocompleteService.init();

View File

@ -31,6 +31,7 @@ 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";
import Entrypoints from "./entrypoints.js";
class AppContext {
constructor() {
@ -112,6 +113,7 @@ class AppContext {
}
this.components = [
new Entrypoints(),
this.tabRow,
new DialogEventComponent(this),
...leftPaneWidgets,
@ -123,8 +125,8 @@ class AppContext {
trigger(name, data, sync = false) {
this.eventReceived(name, data);
for (const tabContext of this.components) {
tabContext.eventReceived(name, data, sync);
for (const component of this.components) {
component.eventReceived(name, data, sync);
}
}

View File

@ -11,95 +11,72 @@ import hoistedNoteService from "./hoisted_note.js";
import treeCache from "./tree_cache.js";
import server from "./server.js";
import appContext from "./app_context.js";
import Component from "../widgets/component.js";
const NOTE_REVISIONS = "../dialogs/note_revisions.js";
const OPTIONS = "../dialogs/options.js";
const ADD_LINK = "../dialogs/add_link.js";
const JUMP_TO_NOTE = "../dialogs/jump_to_note.js";
const NOTE_SOURCE = "../dialogs/note_source.js";
const RECENT_CHANGES = "../dialogs/recent_changes.js";
const SQL_CONSOLE = "../dialogs/sql_console.js";
const BACKEND_LOG = "../dialogs/backend_log.js";
const ATTRIBUTES = "../dialogs/attributes.js";
const HELP = "../dialogs/help.js";
const NOTE_INFO = "../dialogs/note_info.js";
const ABOUT = "../dialogs/about.js";
const LINK_MAP = "../dialogs/link_map.js";
const CLONE_TO = "../dialogs/clone_to.js";
const MOVE_TO = "../dialogs/move_to.js";
export default class Entrypoints extends Component {
constructor(appContext) {
super(appContext);
function registerEntrypoints() {
// hot keys are active also inside inputs and content editables
jQuery.hotkeys.options.filterInputAcceptingElements = false;
jQuery.hotkeys.options.filterContentEditable = false;
jQuery.hotkeys.options.filterTextInputs = false;
// hot keys are active also inside inputs and content editables
jQuery.hotkeys.options.filterInputAcceptingElements = false;
jQuery.hotkeys.options.filterContentEditable = false;
jQuery.hotkeys.options.filterTextInputs = false;
keyboardActionService.setGlobalActionHandler('SearchNotes', searchNotesService.toggleSearch);
$(document).on('click', "a[data-action='note-revision']", async event => {
const linkEl = $(event.target);
const noteId = linkEl.attr('data-note-path');
const noteRevisionId = linkEl.attr('data-note-revision-id');
const $noteTabContainer = $("#note-tab-container");
const attributesDialog = await import("../dialogs/note_revisions.js");
keyboardActionService.setGlobalActionHandler("InsertDateTimeToText", () => {
const date = new Date();
const dateString = utils.formatDateTime(date);
linkService.addTextToEditor(dateString);
});
if (utils.isElectron()) {
const openDevTools = () => {
require('electron').remote.getCurrentWindow().toggleDevTools();
attributesDialog.showNoteRevisionsDialog(noteId, noteRevisionId);
return false;
};
$("#open-dev-tools-button").on('click', openDevTools);
keyboardActionService.setGlobalActionHandler("OpenDevTools", openDevTools);
}
let findInPage;
if (utils.isElectron()) {
const { remote } = require('electron');
const { FindInPage } = require('electron-find');
findInPage = new FindInPage(remote.getCurrentWebContents(), {
offsetTop: 10,
offsetRight: 10,
boxBgColor: 'var(--main-background-color)',
boxShadowColor: '#000',
inputColor: 'var(--input-text-color)',
inputBgColor: 'var(--input-background-color)',
inputFocusColor: '#555',
textColor: 'var(--main-text-color)',
textHoverBgColor: '#555',
caseSelectedColor: 'var(--main-border-color)'
});
keyboardActionService.setGlobalActionHandler("FindInText", () => {
if (!glob.activeDialog || !glob.activeDialog.is(":visible")) {
findInPage.openFindWindow();
}
});
}
if (utils.isElectron()) {
keyboardActionService.setGlobalActionHandler("ZoomOut", zoomService.decreaseZoomFactor);
keyboardActionService.setGlobalActionHandler("ZoomIn", zoomService.increaseZoomFactor);
openDevToolsListener() {
if (utils.isElectron()) {
require('electron').remote.getCurrentWindow().toggleDevTools();
}
}
$(document).on('click', "a[data-action='note-revision']", async event => {
const linkEl = $(event.target);
const noteId = linkEl.attr('data-note-path');
const noteRevisionId = linkEl.attr('data-note-revision-id');
const attributesDialog = await import("../dialogs/note_revisions.js");
findInTextListener() {
if (utils.isElectron()) {
const {remote} = require('electron');
const {FindInPage} = require('electron-find');
attributesDialog.showNoteRevisionsDialog(noteId, noteRevisionId);
const findInPage = new FindInPage(remote.getCurrentWebContents(), {
offsetTop: 10,
offsetRight: 10,
boxBgColor: 'var(--main-background-color)',
boxShadowColor: '#000',
inputColor: 'var(--input-text-color)',
inputBgColor: 'var(--input-background-color)',
inputFocusColor: '#555',
textColor: 'var(--main-text-color)',
textHoverBgColor: '#555',
caseSelectedColor: 'var(--main-border-color)'
});
return false;
});
keyboardActionService.setGlobalActionHandler("FindInText", () => {
if (!glob.activeDialog || !glob.activeDialog.is(":visible")) {
findInPage.openFindWindow();
}
});
}
}
keyboardActionService.setGlobalActionHandler("CreateNoteIntoDayNote", async () => {
zoomOutListener() {
zoomService.decreaseZoomFactor();
}
zoomInListener() {
zoomService.increaseZoomFactor();
}
async createNoteIntoDayNoteListener() {
const todayNote = await dateNoteService.getTodayNote();
const {note} = await server.post(`notes/${todayNote.noteId}/children?target=into`, {
@ -114,9 +91,9 @@ function registerEntrypoints() {
await noteDetailService.openInTab(note.noteId, true);
noteDetailService.focusAndSelectTitle();
});
}
keyboardActionService.setGlobalActionHandler("ToggleNoteHoisting", async () => {
toggleNoteHoistingListener() {
const node = appContext.getMainNoteTree().getActiveNode();
hoistedNoteService.getHoistedNoteId().then(async hoistedNoteId => {
@ -131,19 +108,9 @@ function registerEntrypoints() {
}
}
});
});
}
keyboardActionService.setGlobalActionHandler("SearchInSubtree", () => {
const node = appContext.getMainNoteTree().getActiveNode();
searchNotesService.searchInSubtree(node.data.noteId);
});
keyboardActionService.setGlobalActionHandler('CollapseTree', () => appContext.getMainNoteTree().collapseTree());
keyboardActionService.setGlobalActionHandler("CopyWithoutFormatting", utils.copySelectionToClipboard);
}
export default {
registerEntrypoints
copyWithoutFormattingListener() {
utils.copySelectionToClipboard();
}
}

View File

@ -12,7 +12,8 @@ const keyboardActionsLoaded = server.get('keyboard-actions').then(actions => {
if (shortcut && !shortcut.startsWith("global:")) { // global shortcuts should be handled in the electron code
const eventName = action.actionName.charAt(0).toLowerCase() + action.actionName.slice(1);
utils.bindGlobalShortcut(shortcut, () => appContext.trigger(eventName));
// empty object param so that destructuring with optional params work
utils.bindGlobalShortcut(shortcut, () => appContext.trigger(eventName, {}));
}
}
}

View File

@ -2,6 +2,7 @@ import treeService from './tree.js';
import treeUtils from './tree_utils.js';
import contextMenuService from "./context_menu.js";
import noteDetailService from "./note_detail.js";
import appContext from "./app_context.js";
function getNotePathFromUrl(url) {
const notePathMatch = /#(root[A-Za-z0-9/]*)$/.exec(url);
@ -98,28 +99,6 @@ function goToLink(e) {
return true;
}
function addLinkToEditor(linkTitle, linkHref) {
const editor = noteDetailService.getActiveEditor();
if (editor) {
editor.model.change(writer => {
const insertPosition = editor.model.document.selection.getFirstPosition();
writer.insertText(linkTitle, {linkHref: linkHref}, insertPosition);
});
}
}
function addTextToEditor(text) {
const editor = noteDetailService.getActiveEditor();
if (editor) {
editor.model.change(writer => {
const insertPosition = editor.model.document.selection.getFirstPosition();
writer.insertText(text, insertPosition);
});
}
}
function newTabContextMenu(e) {
const $link = $(e.target).closest("a");
@ -188,7 +167,5 @@ $(document).on('contextmenu', ".note-detail-render a", newTabContextMenu);
export default {
getNotePathFromUrl,
createNoteLink,
addLinkToEditor,
addTextToEditor,
goToLink
};

View File

@ -13,12 +13,6 @@ async function refreshSearch() {
toastService.showMessage("Saved search note refreshed.");
}
function searchInSubtree(noteId) {
showSearch();
$searchInput.val(`@in=${noteId} @text*=*`);
}
function init() {
const hashValue = document.location.hash ? document.location.hash.substr(1) : ""; // strip initial #
@ -35,6 +29,5 @@ export default {
// doSearch,
refreshSearch,
init,
searchInSubtree,
getHelpText: () => helpText
};

View File

@ -10,6 +10,7 @@ import noteDetailService from './note_detail.js';
import clipboard from './clipboard.js';
import protectedSessionHolder from "./protected_session_holder.js";
import searchNotesService from "./search_notes.js";
import appContext from "./app_context.js";
class TreeContextMenu {
/**
@ -99,6 +100,7 @@ class TreeContextMenu {
}
async selectContextMenuItem(event, cmd) {
const noteId = this.node.data.noteId;
const notePath = await treeUtils.getNotePath(this.node);
if (cmd === 'openInTab') {
@ -127,10 +129,10 @@ class TreeContextMenu {
branchPrefixDialog.showDialog(this.node);
}
else if (cmd === "protectSubtree") {
protectedSessionService.protectSubtree(this.node.data.noteId, true);
protectedSessionService.protectSubtree(noteId, true);
}
else if (cmd === "unprotectSubtree") {
protectedSessionService.protectSubtree(this.node.data.noteId, false);
protectedSessionService.protectSubtree(noteId, false);
}
else if (cmd === "copy") {
clipboard.copy(this.getSelectedOrActiveBranchIds());
@ -153,7 +155,7 @@ class TreeContextMenu {
clipboard.pasteAfter(this.node.data.branchId);
}
else if (cmd === "pasteInto") {
clipboard.pasteInto(this.node.data.noteId);
clipboard.pasteInto(noteId);
}
else if (cmd === "delete") {
treeChangesService.deleteNodes(this.getSelectedOrActiveBranchIds());
@ -164,19 +166,19 @@ class TreeContextMenu {
}
else if (cmd === "importIntoNote") {
const importDialog = await import('../dialogs/import.js');
importDialog.showDialog(this.node.data.noteId);
importDialog.showDialog(noteId);
}
else if (cmd === "collapseSubtree") {
this.treeWidget.collapseTree(this.node);
}
else if (cmd === "forceNoteSync") {
syncService.forceNoteSync(this.node.data.noteId);
syncService.forceNoteSync(noteId);
}
else if (cmd === "sortAlphabetically") {
treeService.sortAlphabetically(this.node.data.noteId);
treeService.sortAlphabetically(noteId);
}
else if (cmd === "hoist") {
hoistedNoteService.setHoistedNoteId(this.node.data.noteId);
hoistedNoteService.setHoistedNoteId(noteId);
}
else if (cmd === "unhoist") {
hoistedNoteService.unhoist();
@ -184,10 +186,10 @@ class TreeContextMenu {
else if (cmd === "duplicateNote") {
const branch = treeCache.getBranch(this.node.data.branchId);
treeService.duplicateNote(this.node.data.noteId, branch.parentNoteId);
treeService.duplicateNote(noteId, branch.parentNoteId);
}
else if (cmd === "searchInSubtree") {
searchNotesService.searchInSubtree(this.node.data.noteId);
appContext.trigger("searchInSubtree", {noteId});
}
else {
ws.logError("Unknown command: " + cmd);

View File

@ -20,19 +20,19 @@ const helpText = `
</p>`;
const TPL = `
<style>
.search-box {
display: none;
padding: 10px;
margin-top: 10px;
}
.search-text {
border: 1px solid var(--main-border-color);
}
</style>
<div class="search-box">
<style>
.search-box {
display: none;
padding: 10px;
margin-top: 10px;
}
.search-text {
border: 1px solid var(--main-border-color);
}
</style>
<div class="form-group">
<div class="input-group">
<input name="search-text" class="search-text form-control"
@ -58,14 +58,14 @@ const TPL = `
export default class SearchBoxWidget extends BasicWidget {
doRender() {
const $widget = $(TPL);
this.$widget = $(TPL);
this.$searchBox = $widget.find(".search-box");
this.$closeSearchButton = $widget.find(".close-search-button");
this.$searchInput = $widget.find("input[name='search-text']");
this.$resetSearchButton = $widget.find(".reset-search-button");
this.$doSearchButton = $widget.find(".do-search-button");
this.$saveSearchButton = $widget.find(".save-search-button");
this.$searchBox = this.$widget;
this.$closeSearchButton = this.$widget.find(".close-search-button");
this.$searchInput = this.$widget.find("input[name='search-text']");
this.$resetSearchButton = this.$widget.find(".reset-search-button");
this.$doSearchButton = this.$widget.find(".do-search-button");
this.$saveSearchButton = this.$widget.find(".save-search-button");
this.$searchInput.on('keyup',e => {
const searchText = this.$searchInput.val();
@ -87,7 +87,7 @@ export default class SearchBoxWidget extends BasicWidget {
this.$closeSearchButton.on('click', () => this.hideSearchListener());
return $widget;
return this.$widget;
}
doSearch(searchText) {
@ -171,7 +171,19 @@ export default class SearchBoxWidget extends BasicWidget {
}
}
searchNotesListener() {
this.toggleSearchListener();
}
resetSearchListener() {
this.$searchInput.val("");
}
searchInSubtreeListener({noteId}) {
noteId = noteId || appContext.getActiveTabNoteId();
this.toggle(true);
this.$searchInput.val(`@in=${noteId} @text*=*`);
}
}

View File

@ -2,8 +2,11 @@ import libraryLoader from "../../services/library_loader.js";
import treeService from '../../services/tree.js';
import noteAutocompleteService from '../../services/note_autocomplete.js';
import mimeTypesService from '../../services/mime_types.js';
import TabAwareWidget from "../tab_aware_widget.js";
import TypeWidget from "./type_widget.js";
import utils from "../../services/utils.js";
import linkService from "../../services/link.js";
import appContext from "../../services/app_context.js";
import noteDetailService from "../../services/note_detail.js";
const ENABLE_INSPECTOR = false;
@ -189,6 +192,31 @@ class TextTypeWidget extends TypeWidget {
scrollToTop() {
this.$widget.scrollTop(0);
}
insertDateTimeToTextListener() {
const date = new Date();
const dateString = utils.formatDateTime(date);
this.addTextToEditor(dateString);
}
async addLinkToEditor(linkTitle, linkHref) {
await this.initialized;
this.textEditor.model.change(writer => {
const insertPosition = this.textEditor.model.document.selection.getFirstPosition();
writer.insertText(linkTitle, {linkHref: linkHref}, insertPosition);
});
}
async addTextToEditor(text) {
await this.initialized;
this.textEditor.model.change(writer => {
const insertPosition = this.textEditor.model.document.selection.getFirstPosition();
writer.insertText(text, insertPosition);
});
}
}
export default TextTypeWidget;