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 treeUtils from './services/tree_utils.js';
import utils from './services/utils.js'; import utils from './services/utils.js';
import server from './services/server.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 noteTooltipService from './services/note_tooltip.js';
import bundle from "./services/bundle.js"; import bundle from "./services/bundle.js";
import treeCache from "./services/tree_cache.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(); appContext.showWidgets();
entrypoints.registerEntrypoints();
noteTooltipService.setupGlobalTooltip(); noteTooltipService.setupGlobalTooltip();
noteAutocompleteService.init(); noteAutocompleteService.init();

View File

@ -31,6 +31,7 @@ import NoteActionsWidget from "../widgets/note_actions.js";
import protectedSessionHolder from "./protected_session_holder.js"; import protectedSessionHolder from "./protected_session_holder.js";
import bundleService from "./bundle.js"; import bundleService from "./bundle.js";
import DialogEventComponent from "./dialog_events.js"; import DialogEventComponent from "./dialog_events.js";
import Entrypoints from "./entrypoints.js";
class AppContext { class AppContext {
constructor() { constructor() {
@ -112,6 +113,7 @@ class AppContext {
} }
this.components = [ this.components = [
new Entrypoints(),
this.tabRow, this.tabRow,
new DialogEventComponent(this), new DialogEventComponent(this),
...leftPaneWidgets, ...leftPaneWidgets,
@ -123,8 +125,8 @@ class AppContext {
trigger(name, data, sync = false) { trigger(name, data, sync = false) {
this.eventReceived(name, data); this.eventReceived(name, data);
for (const tabContext of this.components) { for (const component of this.components) {
tabContext.eventReceived(name, data, sync); component.eventReceived(name, data, sync);
} }
} }

View File

@ -11,58 +11,43 @@ import hoistedNoteService from "./hoisted_note.js";
import treeCache from "./tree_cache.js"; import treeCache from "./tree_cache.js";
import server from "./server.js"; import server from "./server.js";
import appContext from "./app_context.js"; import appContext from "./app_context.js";
import Component from "../widgets/component.js";
const NOTE_REVISIONS = "../dialogs/note_revisions.js"; export default class Entrypoints extends Component {
const OPTIONS = "../dialogs/options.js"; constructor(appContext) {
const ADD_LINK = "../dialogs/add_link.js"; super(appContext);
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";
function registerEntrypoints() {
// hot keys are active also inside inputs and content editables // hot keys are active also inside inputs and content editables
jQuery.hotkeys.options.filterInputAcceptingElements = false; jQuery.hotkeys.options.filterInputAcceptingElements = false;
jQuery.hotkeys.options.filterContentEditable = false; jQuery.hotkeys.options.filterContentEditable = false;
jQuery.hotkeys.options.filterTextInputs = 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", () => { attributesDialog.showNoteRevisionsDialog(noteId, noteRevisionId);
const date = new Date();
const dateString = utils.formatDateTime(date);
linkService.addTextToEditor(dateString);
});
if (utils.isElectron()) {
const openDevTools = () => {
require('electron').remote.getCurrentWindow().toggleDevTools();
return false; return false;
}; });
$("#open-dev-tools-button").on('click', openDevTools);
keyboardActionService.setGlobalActionHandler("OpenDevTools", openDevTools);
} }
let findInPage; openDevToolsListener() {
if (utils.isElectron()) { if (utils.isElectron()) {
const { remote } = require('electron'); require('electron').remote.getCurrentWindow().toggleDevTools();
const { FindInPage } = require('electron-find'); }
}
findInPage = new FindInPage(remote.getCurrentWebContents(), {
findInTextListener() {
if (utils.isElectron()) {
const {remote} = require('electron');
const {FindInPage} = require('electron-find');
const findInPage = new FindInPage(remote.getCurrentWebContents(), {
offsetTop: 10, offsetTop: 10,
offsetRight: 10, offsetRight: 10,
boxBgColor: 'var(--main-background-color)', boxBgColor: 'var(--main-background-color)',
@ -81,25 +66,17 @@ function registerEntrypoints() {
} }
}); });
} }
if (utils.isElectron()) {
keyboardActionService.setGlobalActionHandler("ZoomOut", zoomService.decreaseZoomFactor);
keyboardActionService.setGlobalActionHandler("ZoomIn", zoomService.increaseZoomFactor);
} }
$(document).on('click', "a[data-action='note-revision']", async event => { zoomOutListener() {
const linkEl = $(event.target); zoomService.decreaseZoomFactor();
const noteId = linkEl.attr('data-note-path'); }
const noteRevisionId = linkEl.attr('data-note-revision-id');
const attributesDialog = await import("../dialogs/note_revisions.js"); zoomInListener() {
zoomService.increaseZoomFactor();
}
attributesDialog.showNoteRevisionsDialog(noteId, noteRevisionId); async createNoteIntoDayNoteListener() {
return false;
});
keyboardActionService.setGlobalActionHandler("CreateNoteIntoDayNote", async () => {
const todayNote = await dateNoteService.getTodayNote(); const todayNote = await dateNoteService.getTodayNote();
const {note} = await server.post(`notes/${todayNote.noteId}/children?target=into`, { const {note} = await server.post(`notes/${todayNote.noteId}/children?target=into`, {
@ -114,9 +91,9 @@ function registerEntrypoints() {
await noteDetailService.openInTab(note.noteId, true); await noteDetailService.openInTab(note.noteId, true);
noteDetailService.focusAndSelectTitle(); noteDetailService.focusAndSelectTitle();
}); }
keyboardActionService.setGlobalActionHandler("ToggleNoteHoisting", async () => { toggleNoteHoistingListener() {
const node = appContext.getMainNoteTree().getActiveNode(); const node = appContext.getMainNoteTree().getActiveNode();
hoistedNoteService.getHoistedNoteId().then(async hoistedNoteId => { hoistedNoteService.getHoistedNoteId().then(async hoistedNoteId => {
@ -131,19 +108,9 @@ function registerEntrypoints() {
} }
} }
}); });
}); }
keyboardActionService.setGlobalActionHandler("SearchInSubtree", () => { copyWithoutFormattingListener() {
const node = appContext.getMainNoteTree().getActiveNode(); utils.copySelectionToClipboard();
}
searchNotesService.searchInSubtree(node.data.noteId);
});
keyboardActionService.setGlobalActionHandler('CollapseTree', () => appContext.getMainNoteTree().collapseTree());
keyboardActionService.setGlobalActionHandler("CopyWithoutFormatting", utils.copySelectionToClipboard);
}
export default {
registerEntrypoints
} }

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 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); 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 treeUtils from './tree_utils.js';
import contextMenuService from "./context_menu.js"; import contextMenuService from "./context_menu.js";
import noteDetailService from "./note_detail.js"; import noteDetailService from "./note_detail.js";
import appContext from "./app_context.js";
function getNotePathFromUrl(url) { function getNotePathFromUrl(url) {
const notePathMatch = /#(root[A-Za-z0-9/]*)$/.exec(url); const notePathMatch = /#(root[A-Za-z0-9/]*)$/.exec(url);
@ -98,28 +99,6 @@ function goToLink(e) {
return true; 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) { function newTabContextMenu(e) {
const $link = $(e.target).closest("a"); const $link = $(e.target).closest("a");
@ -188,7 +167,5 @@ $(document).on('contextmenu', ".note-detail-render a", newTabContextMenu);
export default { export default {
getNotePathFromUrl, getNotePathFromUrl,
createNoteLink, createNoteLink,
addLinkToEditor,
addTextToEditor,
goToLink goToLink
}; };

View File

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

View File

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

View File

@ -20,19 +20,19 @@ const helpText = `
</p>`; </p>`;
const TPL = ` const TPL = `
<style> <div class="search-box">
.search-box { <style>
.search-box {
display: none; display: none;
padding: 10px; padding: 10px;
margin-top: 10px; margin-top: 10px;
} }
.search-text { .search-text {
border: 1px solid var(--main-border-color); border: 1px solid var(--main-border-color);
} }
</style> </style>
<div class="search-box">
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<input name="search-text" class="search-text form-control" <input name="search-text" class="search-text form-control"
@ -58,14 +58,14 @@ const TPL = `
export default class SearchBoxWidget extends BasicWidget { export default class SearchBoxWidget extends BasicWidget {
doRender() { doRender() {
const $widget = $(TPL); this.$widget = $(TPL);
this.$searchBox = $widget.find(".search-box"); this.$searchBox = this.$widget;
this.$closeSearchButton = $widget.find(".close-search-button"); this.$closeSearchButton = this.$widget.find(".close-search-button");
this.$searchInput = $widget.find("input[name='search-text']"); this.$searchInput = this.$widget.find("input[name='search-text']");
this.$resetSearchButton = $widget.find(".reset-search-button"); this.$resetSearchButton = this.$widget.find(".reset-search-button");
this.$doSearchButton = $widget.find(".do-search-button"); this.$doSearchButton = this.$widget.find(".do-search-button");
this.$saveSearchButton = $widget.find(".save-search-button"); this.$saveSearchButton = this.$widget.find(".save-search-button");
this.$searchInput.on('keyup',e => { this.$searchInput.on('keyup',e => {
const searchText = this.$searchInput.val(); const searchText = this.$searchInput.val();
@ -87,7 +87,7 @@ export default class SearchBoxWidget extends BasicWidget {
this.$closeSearchButton.on('click', () => this.hideSearchListener()); this.$closeSearchButton.on('click', () => this.hideSearchListener());
return $widget; return this.$widget;
} }
doSearch(searchText) { doSearch(searchText) {
@ -171,7 +171,19 @@ export default class SearchBoxWidget extends BasicWidget {
} }
} }
searchNotesListener() {
this.toggleSearchListener();
}
resetSearchListener() { resetSearchListener() {
this.$searchInput.val(""); 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 treeService from '../../services/tree.js';
import noteAutocompleteService from '../../services/note_autocomplete.js'; import noteAutocompleteService from '../../services/note_autocomplete.js';
import mimeTypesService from '../../services/mime_types.js'; import mimeTypesService from '../../services/mime_types.js';
import TabAwareWidget from "../tab_aware_widget.js";
import TypeWidget from "./type_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; const ENABLE_INSPECTOR = false;
@ -189,6 +192,31 @@ class TextTypeWidget extends TypeWidget {
scrollToTop() { scrollToTop() {
this.$widget.scrollTop(0); 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; export default TextTypeWidget;