mirror of
https://github.com/zadam/trilium.git
synced 2025-06-05 01:18:44 +02:00
shortcuts WIP
This commit is contained in:
parent
0ae9c8da17
commit
4bd7438fca
6
package-lock.json
generated
6
package-lock.json
generated
@ -3112,9 +3112,9 @@
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"ejs": {
|
||||
"version": "2.7.2",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.2.tgz",
|
||||
"integrity": "sha512-rHGwtpl67oih3xAHbZlpw5rQAt+YV1mSCu2fUZ9XNrfaGEhom7E+AUiMci+ByP4aSfuAWx7hE0BPuJLMrpXwOw=="
|
||||
"version": "2.7.3",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.3.tgz",
|
||||
"integrity": "sha512-NtMNsdpaCF23gvHItgT37gzrpzckzs7KB7mg+YH1GMSG/5iZRq1BeWzAhEAJVagfM7nCQDnh/C51j/L2qjZmnA=="
|
||||
},
|
||||
"electron": {
|
||||
"version": "6.0.12",
|
||||
|
@ -29,7 +29,7 @@
|
||||
"csurf": "1.10.0",
|
||||
"dayjs": "1.8.17",
|
||||
"debug": "4.1.1",
|
||||
"ejs": "2.7.2",
|
||||
"ejs": "2.7.3",
|
||||
"electron-debug": "3.0.1",
|
||||
"electron-dl": "1.14.0",
|
||||
"electron-find": "1.0.6",
|
||||
|
@ -4,6 +4,7 @@ import zoomService from "./zoom.js";
|
||||
import protectedSessionService from "./protected_session.js";
|
||||
import searchNotesService from "./search_notes.js";
|
||||
import treeService from "./tree.js";
|
||||
import server from "./server.js";
|
||||
|
||||
const NOTE_REVISIONS = "../dialogs/note_revisions.js";
|
||||
const OPTIONS = "../dialogs/options.js";
|
||||
@ -208,6 +209,43 @@ function registerEntrypoints() {
|
||||
|
||||
}
|
||||
|
||||
class KeyboardAction {
|
||||
constructor(params) {
|
||||
/** @property {string} */
|
||||
this.optionName = params.optionName;
|
||||
/** @property {string[]} */
|
||||
this.defaultShortcuts = Array.isArray(params.defaultShortcuts) ? params.defaultShortcuts : [params.defaultShortcuts];
|
||||
/** @property {string[]} */
|
||||
this.activeShortcuts = this.defaultShortcuts.slice();
|
||||
/** @property {string} */
|
||||
this.description = params.description;
|
||||
}
|
||||
|
||||
addShortcut(shortcut) {
|
||||
this.activeShortcuts.push(shortcut);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string|string[]} shortcuts
|
||||
*/
|
||||
replaceShortcuts(shortcuts) {
|
||||
this.activeShortcuts = Array.isArray(shortcuts) ? shortcuts : [shortcuts];
|
||||
}
|
||||
|
||||
/** @return {KeyboardAction[]} */
|
||||
static get allActions() {
|
||||
return Object.keys(KeyboardAction)
|
||||
.map(key => KeyboardAction[key])
|
||||
.filter(obj => obj instanceof KeyboardAction);
|
||||
}
|
||||
}
|
||||
|
||||
server.get('keyboard-actions').then(actions => {
|
||||
for (const action of actions) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
registerEntrypoints
|
||||
}
|
@ -13,6 +13,10 @@ class Options {
|
||||
return this.arr[key];
|
||||
}
|
||||
|
||||
getNames() {
|
||||
return Object.keys(this.arr);
|
||||
}
|
||||
|
||||
getJson(key) {
|
||||
try {
|
||||
return JSON.parse(this.arr[key]);
|
||||
|
@ -58,7 +58,7 @@ class Sidebar {
|
||||
import("../widgets/note_revisions.js"),
|
||||
import("../widgets/attributes.js"),
|
||||
import("../widgets/what_links_here.js"),
|
||||
import("../widgets/similar_notes.js"),
|
||||
import("../widgets/similar-notes.js"),
|
||||
import("../widgets/edited_notes.js"),
|
||||
import("../widgets/calendar.js")
|
||||
])).map(m => m.default);
|
||||
|
@ -18,7 +18,7 @@ class SimilarNotesWidget extends StandardWidget {
|
||||
// remember which title was when we found the similar notes
|
||||
this.title = this.ctx.note.title;
|
||||
|
||||
const similarNotes = await server.get('similar_notes/' + this.ctx.note.noteId);
|
||||
const similarNotes = await server.get('similar-notes/' + this.ctx.note.noteId);
|
||||
|
||||
if (similarNotes.length === 0) {
|
||||
this.$body.text("No similar notes found ...");
|
||||
|
11
src/routes/api/keys.js
Normal file
11
src/routes/api/keys.js
Normal file
@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
const keyboardActions = require('../../services/keyboard_actions');
|
||||
|
||||
async function getKeyboardActions() {
|
||||
return await keyboardActions.getKeyboardActions();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getKeyboardActions
|
||||
};
|
@ -5,7 +5,7 @@ const log = require('../../services/log');
|
||||
const attributes = require('../../services/attributes');
|
||||
|
||||
// options allowed to be updated directly in options dialog
|
||||
const ALLOWED_OPTIONS = [
|
||||
const ALLOWED_OPTIONS = new Set([
|
||||
'protectedSessionTimeout',
|
||||
'noteRevisionSnapshotTimeInterval',
|
||||
'zoomFactor',
|
||||
@ -37,23 +37,32 @@ const ALLOWED_OPTIONS = [
|
||||
'spellCheckLanguageCode',
|
||||
'imageMaxWidthHeight',
|
||||
'imageJpegQuality'
|
||||
];
|
||||
]);
|
||||
|
||||
async function getOptions() {
|
||||
return await optionService.getOptionsMap(ALLOWED_OPTIONS);
|
||||
const optionMap = await optionService.getOptionsMap();
|
||||
const resultMap = {};
|
||||
|
||||
for (const optionName in optionMap) {
|
||||
if (isAllowed(optionName)) {
|
||||
resultMap[optionName] = optionMap[optionName];
|
||||
}
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
async function updateOption(req) {
|
||||
const {name, value} = req.params;
|
||||
|
||||
if (!update(name, value)) {
|
||||
if (!await update(name, value)) {
|
||||
return [400, "not allowed option to change"];
|
||||
}
|
||||
}
|
||||
|
||||
async function updateOptions(req) {
|
||||
for (const optionName in req.body) {
|
||||
if (!update(optionName, req.body[optionName])) {
|
||||
if (!await update(optionName, req.body[optionName])) {
|
||||
// this should be improved
|
||||
// it should return 400 instead of current 500, but at least it now rollbacks transaction
|
||||
throw new Error(`${optionName} is not allowed to change`);
|
||||
@ -62,7 +71,7 @@ async function updateOptions(req) {
|
||||
}
|
||||
|
||||
async function update(name, value) {
|
||||
if (!ALLOWED_OPTIONS.includes(name)) {
|
||||
if (!isAllowed(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -97,6 +106,10 @@ async function getUserThemes() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
function isAllowed(name) {
|
||||
return ALLOWED_OPTIONS.has(name) || name.startsWith("keyboardShortcuts");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getOptions,
|
||||
updateOption,
|
||||
|
@ -33,7 +33,8 @@ const searchRoute = require('./api/search');
|
||||
const dateNotesRoute = require('./api/date_notes');
|
||||
const linkMapRoute = require('./api/link_map');
|
||||
const clipperRoute = require('./api/clipper');
|
||||
const similarNotesRoute = require('./api/similar_notes');
|
||||
const similarNotesRoute = require('./api/similar-notes');
|
||||
const keysRoute = require('./api/keys');
|
||||
|
||||
const log = require('../services/log');
|
||||
const express = require('express');
|
||||
@ -242,7 +243,9 @@ function register(app) {
|
||||
route(POST, '/api/clipper/notes', clipperMiddleware, clipperRoute.createNote, apiResultHandler);
|
||||
route(POST, '/api/clipper/open/:noteId', clipperMiddleware, clipperRoute.openNote, apiResultHandler);
|
||||
|
||||
apiRoute(GET, '/api/similar_notes/:noteId', similarNotesRoute.getSimilarNotes);
|
||||
apiRoute(GET, '/api/similar-notes/:noteId', similarNotesRoute.getSimilarNotes);
|
||||
|
||||
apiRoute(GET, '/api/keyboard-actions', keysRoute.getKeyboardActions);
|
||||
|
||||
app.use('', router);
|
||||
}
|
||||
|
@ -1,157 +1,191 @@
|
||||
"use strict";
|
||||
|
||||
const optionService = require('./options');
|
||||
const log = require('./log');
|
||||
|
||||
const ELECTRON = "electron";
|
||||
|
||||
const KEYBOARD_ACTIONS = [
|
||||
const DEFAULT_KEYBOARD_ACTIONS = [
|
||||
{
|
||||
optionName: "JumpToNote",
|
||||
actionName: "JumpToNote",
|
||||
defaultShortcuts: ["mod+j"],
|
||||
description: 'Open "Jump to note" dialog'
|
||||
},
|
||||
{
|
||||
optionName: "MarkdownToHTML",
|
||||
actionName: "MarkdownToHTML",
|
||||
defaultShortcuts: ["mod+return"]
|
||||
},
|
||||
{
|
||||
optionName: "NewTab",
|
||||
actionName: "NewTab",
|
||||
defaultShortcuts: ["mod+t"],
|
||||
only: ELECTRON
|
||||
},
|
||||
{
|
||||
optionName: "CloseTab",
|
||||
actionName: "CloseTab",
|
||||
defaultShortcuts: ["mod+w"],
|
||||
only: ELECTRON
|
||||
},
|
||||
{
|
||||
optionName: "NextTab",
|
||||
actionName: "NextTab",
|
||||
defaultShortcuts: ["mod+tab"],
|
||||
only: ELECTRON
|
||||
},
|
||||
{
|
||||
optionName: "PreviousTab",
|
||||
actionName: "PreviousTab",
|
||||
defaultShortcuts: ["mod+shift+tab"],
|
||||
only: ELECTRON
|
||||
},
|
||||
{
|
||||
optionName: "CreateNoteAfter",
|
||||
actionName: "CreateNoteAfter",
|
||||
defaultShortcuts: ["mod+o"]
|
||||
},
|
||||
{
|
||||
optionName: "CreateNoteInto",
|
||||
actionName: "CreateNoteInto",
|
||||
defaultShortcuts: ["mod+p"]
|
||||
},
|
||||
{
|
||||
optionName: "ScrollToActiveNote",
|
||||
actionName: "ScrollToActiveNote",
|
||||
defaultShortcuts: ["mod+."]
|
||||
},
|
||||
{
|
||||
optionName: "CollapseTree",
|
||||
actionName: "CollapseTree",
|
||||
defaultShortcuts: ["alt+c"]
|
||||
},
|
||||
{
|
||||
optionName: "RunSQL",
|
||||
actionName: "RunSQL",
|
||||
defaultShortcuts: ["mod+return"]
|
||||
},
|
||||
{
|
||||
optionName: "FocusNote",
|
||||
actionName: "FocusNote",
|
||||
defaultShortcuts: ["return"]
|
||||
},
|
||||
{
|
||||
optionName: "RunCurrentNote",
|
||||
actionName: "RunCurrentNote",
|
||||
defaultShortcuts: ["mod+return"]
|
||||
},
|
||||
{
|
||||
optionName: "ClipboardCopy",
|
||||
actionName: "ClipboardCopy",
|
||||
defaultShortcuts: ["mod+c"]
|
||||
},
|
||||
{
|
||||
optionName: "ClipboardPaste",
|
||||
actionName: "ClipboardPaste",
|
||||
defaultShortcuts: ["mod+v"]
|
||||
},
|
||||
{
|
||||
optionName: "ClipboardCut",
|
||||
actionName: "ClipboardCut",
|
||||
defaultShortcuts: ["mod+x"]
|
||||
},
|
||||
{
|
||||
optionName: "SelectAllNotesInParent",
|
||||
actionName: "SelectAllNotesInParent",
|
||||
defaultShortcuts: ["mod+a"]
|
||||
},
|
||||
{
|
||||
optionName: "Undo",
|
||||
actionName: "Undo",
|
||||
defaultShortcuts: ["mod+z"]
|
||||
},
|
||||
{
|
||||
optionName: "Redo",
|
||||
actionName: "Redo",
|
||||
defaultShortcuts: ["mod+y"]
|
||||
},
|
||||
{
|
||||
optionName: "AddLinkToText",
|
||||
actionName: "AddLinkToText",
|
||||
defaultShortcuts: ["mod+l"]
|
||||
},
|
||||
{
|
||||
optionName: "CloneNotesTo",
|
||||
actionName: "CloneNotesTo",
|
||||
defaultShortcuts: ["mod+shift+c"]
|
||||
},
|
||||
{
|
||||
optionName: "MoveNotesTo",
|
||||
actionName: "MoveNotesTo",
|
||||
defaultShortcuts: ["mod+shift+c"]
|
||||
},
|
||||
{
|
||||
optionName: "SearchNotes",
|
||||
actionName: "SearchNotes",
|
||||
defaultShortcuts: ["mod+s"]
|
||||
},
|
||||
{
|
||||
optionName: "ShowAttributes",
|
||||
actionName: "ShowAttributes",
|
||||
defaultShortcuts: ["alt+a"]
|
||||
},
|
||||
{
|
||||
optionName: "ShowHelp",
|
||||
actionName: "ShowHelp",
|
||||
defaultShortcuts: ["f1"]
|
||||
},
|
||||
{
|
||||
optionName: "OpenSQLConsole",
|
||||
actionName: "OpenSQLConsole",
|
||||
defaultShortcuts: ["alt+o"]
|
||||
},
|
||||
{
|
||||
optionName: "BackInNoteHistory",
|
||||
actionName: "BackInNoteHistory",
|
||||
defaultShortcuts: ["alt+left"]
|
||||
},
|
||||
{
|
||||
optionName: "ForwardInNoteHistory",
|
||||
actionName: "ForwardInNoteHistory",
|
||||
defaultShortcuts: ["alt+right"]
|
||||
},
|
||||
{
|
||||
optionName: "ToggleZenMode",
|
||||
actionName: "ToggleZenMode",
|
||||
defaultShortcuts: ["alt+m"]
|
||||
},
|
||||
{
|
||||
optionName: "InsertDateTime",
|
||||
actionName: "InsertDateTime",
|
||||
defaultShortcuts: ["alt+t"]
|
||||
},
|
||||
{
|
||||
optionName: "ReloadApp",
|
||||
actionName: "ReloadApp",
|
||||
defaultShortcuts: ["f5", "mod+r"]
|
||||
},
|
||||
{
|
||||
optionName: "OpenDevTools",
|
||||
actionName: "OpenDevTools",
|
||||
defaultShortcuts: ["mod+shift+i"]
|
||||
},
|
||||
{
|
||||
optionName: "FindInText",
|
||||
actionName: "FindInText",
|
||||
defaultShortcuts: ["mod+f"]
|
||||
},
|
||||
{
|
||||
optionName: "ToggleFullscreen",
|
||||
actionName: "ToggleFullscreen",
|
||||
defaultShortcuts: ["f11"]
|
||||
},
|
||||
{
|
||||
optionName: "ZoomOut",
|
||||
actionName: "ZoomOut",
|
||||
defaultShortcuts: ["mod+-"]
|
||||
},
|
||||
{
|
||||
optionName: "ZoomIn",
|
||||
actionName: "ZoomIn",
|
||||
defaultShortcuts: ["mod+="]
|
||||
}
|
||||
];
|
||||
|
||||
async function getKeyboardActions() {
|
||||
const actions = JSON.parse(JSON.stringify(DEFAULT_KEYBOARD_ACTIONS));
|
||||
|
||||
for (const action of actions) {
|
||||
action.effectiveShortcuts = action.defaultShortcuts.slice();
|
||||
}
|
||||
|
||||
for (const option of await optionService.getOptions()) {
|
||||
if (option.name.startsWith('keyboardShortcuts')) {
|
||||
const actionName = option.name.substr(17);
|
||||
|
||||
const action = actions.find(ea => ea.actionName === actionName);
|
||||
|
||||
if (action) {
|
||||
try {
|
||||
action.effectiveShortcuts = JSON.parse(option.value);
|
||||
}
|
||||
catch (e) {
|
||||
log.error(`Could not parse shortcuts for action ${actionName}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.info(`Keyboard action ${actionName} not found.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
KEYBOARD_ACTIONS
|
||||
DEFAULT_KEYBOARD_ACTIONS,
|
||||
getKeyboardActions
|
||||
};
|
@ -61,18 +61,12 @@ async function createOption(name, value, isSynced) {
|
||||
}).save();
|
||||
}
|
||||
|
||||
async function getOptions(allowedOptions) {
|
||||
let options = await require('./repository').getEntities("SELECT * FROM options ORDER BY name");
|
||||
|
||||
if (allowedOptions) {
|
||||
options = options.filter(opt => allowedOptions.includes(opt.name));
|
||||
}
|
||||
|
||||
return options;
|
||||
async function getOptions() {
|
||||
return await require('./repository').getEntities("SELECT * FROM options ORDER BY name");
|
||||
}
|
||||
|
||||
async function getOptionsMap(allowedOptions) {
|
||||
const options = await getOptions(allowedOptions);
|
||||
async function getOptionsMap() {
|
||||
const options = await getOptions();
|
||||
|
||||
return utils.toObject(options, opt => [opt.name, opt.value]);
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ async function initStartupOptions() {
|
||||
}
|
||||
|
||||
function getKeyboardDefaultOptions() {
|
||||
return keyboardActions.KEYBOARD_ACTIONS.map(ka => {
|
||||
return keyboardActions.DEFAULT_KEYBOARD_ACTIONS.map(ka => {
|
||||
return {
|
||||
name: "keyboardShortcuts" + ka.optionName,
|
||||
value: JSON.stringify(ka.defaultShortcuts),
|
||||
|
Loading…
x
Reference in New Issue
Block a user