keyboard shortcuts options pane

This commit is contained in:
zadam 2019-11-20 21:35:18 +01:00
parent bcdfb47939
commit 08a518479b
11 changed files with 175 additions and 85 deletions

71
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "trilium",
"version": "0.37.2",
"version": "0.37.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -3112,9 +3112,9 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"ejs": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.3.tgz",
"integrity": "sha512-NtMNsdpaCF23gvHItgT37gzrpzckzs7KB7mg+YH1GMSG/5iZRq1BeWzAhEAJVagfM7nCQDnh/C51j/L2qjZmnA=="
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz",
"integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA=="
},
"electron": {
"version": "6.0.12",
@ -3799,17 +3799,17 @@
}
},
"electron-rebuild": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-1.8.6.tgz",
"integrity": "sha512-4BAPcNG0XP6stByqvFXggrjmf/C47P2L6HFFrWdR2ako1VLiTDIeZAOmU4WEBuWdaXYNqstleszVmcNHdRDojA==",
"version": "1.8.8",
"resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-1.8.8.tgz",
"integrity": "sha512-9a/VGbVpTJcuBaZa8yMcegqJ5flGPYDo363AxXDMxY4ZHPtFMLedGzQW9+720SIS1cvjX8B0zC+vMHO75ncOiA==",
"dev": true,
"requires": {
"colors": "^1.3.3",
"debug": "^4.1.1",
"detect-libc": "^1.0.3",
"fs-extra": "^7.0.1",
"node-abi": "^2.9.0",
"node-gyp": "^5.0.1",
"node-abi": "^2.11.0",
"node-gyp": "^6.0.1",
"ora": "^3.4.0",
"spawn-rx": "^3.0.0",
"yargs": "^13.2.4"
@ -8989,28 +8989,34 @@
}
},
"node-gyp": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.5.tgz",
"integrity": "sha512-WABl9s4/mqQdZneZHVWVG4TVr6QQJZUC6PAx47ITSk9lreZ1n+7Z9mMAIbA3vnO4J9W20P7LhCxtzfWsAD/KDw==",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-6.0.1.tgz",
"integrity": "sha512-udHG4hGe3Ji97AYJbJhaRwuSOuQO7KHnE4ZPH3Sox3tjRZ+bkBsDvfZ7eYA1qwD8eLWr//193x806ss3HFTPRw==",
"dev": true,
"requires": {
"env-paths": "^1.0.0",
"glob": "^7.0.3",
"graceful-fs": "^4.1.2",
"mkdirp": "^0.5.0",
"nopt": "2 || 3",
"npmlog": "0 || 1 || 2 || 3 || 4",
"request": "^2.87.0",
"rimraf": "2",
"semver": "~5.3.0",
"env-paths": "^2.2.0",
"glob": "^7.1.4",
"graceful-fs": "^4.2.2",
"mkdirp": "^0.5.1",
"nopt": "^4.0.1",
"npmlog": "^4.1.2",
"request": "^2.88.0",
"rimraf": "^2.6.3",
"semver": "^5.7.1",
"tar": "^4.4.12",
"which": "1"
"which": "^1.3.1"
},
"dependencies": {
"env-paths": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
"integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
"dev": true
},
"glob": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@ -9021,15 +9027,6 @@
"path-is-absolute": "^1.0.0"
}
},
"nopt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
"dev": true,
"requires": {
"abbrev": "1"
}
},
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@ -9040,9 +9037,9 @@
}
},
"semver": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}

View file

@ -29,7 +29,7 @@
"csurf": "1.10.0",
"dayjs": "1.8.17",
"debug": "4.1.1",
"ejs": "2.7.3",
"ejs": "2.7.4",
"electron-debug": "3.0.1",
"electron-dl": "1.14.0",
"electron-find": "1.0.6",
@ -82,7 +82,7 @@
"electron-compile": "6.4.4",
"electron-installer-debian": "2.0.1",
"electron-packager": "14.1.0",
"electron-rebuild": "1.8.6",
"electron-rebuild": "1.8.8",
"jsdoc": "3.6.3",
"lorem-ipsum": "2.0.3",
"xo": "0.25.3"

View file

@ -22,6 +22,7 @@ export async function showDialog() {
import('./options/other.js'),
import('./options/sidebar.js'),
import('./options/sync.js'),
import('./options/keyboard_shortcuts.js'),
]))
.map(m => new m.default)
.forEach(tab => {

View file

@ -3,19 +3,19 @@ import toastService from "../../services/toast.js";
const TPL = `
<h4 style="margin-top: 0;">Sync</h4>
<button id="force-full-sync-button" class="btn btn-secondary">Force full sync</button>
<button id="force-full-sync-button" class="btn">Force full sync</button>
<br/>
<br/>
<button id="fill-sync-rows-button" class="btn btn-secondary">Fill sync rows</button>
<button id="fill-sync-rows-button" class="btn">Fill sync rows</button>
<br/>
<br/>
<h4>Debugging</h4>
<button id="anonymize-button" class="btn btn-secondary">Save anonymized database</button><br/><br/>
<button id="anonymize-button" class="btn">Save anonymized database</button><br/><br/>
<p>This action will create a new copy of the database and anonymise it (remove all note content and leave only structure and metadata)
for sharing online for debugging purposes without fear of leaking your personal data.</p>
@ -24,7 +24,7 @@ const TPL = `
<p>This will rebuild database which will typically result in smaller database file. No data will be actually changed.</p>
<button id="vacuum-database-button" class="btn btn-secondary">Vacuum database</button>`;
<button id="vacuum-database-button" class="btn">Vacuum database</button>`;
export default class AdvancedOptions {
constructor() {

View file

@ -0,0 +1,61 @@
import server from "../../services/server.js";
import optionsService from "../../services/options.js";
const TPL = `
<h4>Keyboard shortcuts</h4>
<div style="overflow: auto; height: 500px;">
<table id="keyboard-shortcut-table" cellpadding="10">
<thead>
<tr>
<th>Action name</th>
<th>Shortcuts</th>
<th>Default shortcuts</th>
<th>Description</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div style="display: flex; justify-content: space-between">
<button class="btn btn-primary">Reload app to apply changes</button>
<button class="btn">Set all shortcuts to the default</button>
</div>
`;
export default class KeyboardShortcutsOptions {
constructor() {
$("#options-keyboard-shortcuts").html(TPL);
const $table = $("#keyboard-shortcut-table tbody");
server.get('keyboard-actions').then(actions => {
for (const action of actions) {
const $tr = $("<tr>")
.append($("<td>").text(action.actionName))
.append($("<td>").append(
$(`<input type="text" class="form-control">`).val(action.effectiveShortcuts.join(", ")))
)
.append($("<td>").text(action.defaultShortcuts.join(", ")))
.append($("<td>").text(action.description));
$table.append($tr);
}
});
}
async save() {
const enabledMimeTypes = [];
this.$mimeTypes.find("input:checked").each(
(i, el) => enabledMimeTypes.push($(el).attr("data-mime-type")));
const opts = { codeNotesMimeTypes: JSON.stringify(enabledMimeTypes) };
await server.put('options', opts);
await optionsService.reloadOptions();
}
}

View file

@ -25,7 +25,7 @@ const TPL = `
<div style="display: flex; justify-content: space-between;">
<button class="btn btn-primary">Save</button>
<button class="btn btn-secondary" type="button" data-help-page="Synchronization">Help</button>
<button class="btn" type="button" data-help-page="Synchronization">Help</button>
</div>
</form>
@ -35,7 +35,7 @@ const TPL = `
<p>This will test connection and handshake to the sync server. If sync server isn't initialized, this will set it up to sync with local document.</p>
<button id="test-sync-button" class="btn btn-secondary">Test sync</button>`;
<button id="test-sync-button" class="btn">Test sync</button>`;
export default class SyncOptions {
constructor() {

View file

@ -419,7 +419,17 @@ div.ui-tooltip {
border-radius: var(--button-border-radius);
}
.btn:not(.btn-primary):not(.btn-secondary):not(.btn-danger) {
.btn.btn-primary {
border-color: var(--primary-button-border-color);
background-color: var(--primary-button-background-color);
color: var(--primary-button-text-color);
}
.btn.btn-primary kbd {
color: var(--primary-button-text-color);
}
.btn:not(.btn-primary) {
border-color: var(--button-border-color);
background-color: var(--button-background-color);
color: var(--button-text-color);

View file

@ -17,6 +17,9 @@
--button-border-color: #ddd;
--button-text-color: black;
--button-border-radius: 5px;
--primary-button-background-color: #6c757d;
--primary-button-text-color: white;
--primary-button-border-color: #6c757d;
--muted-text-color: #666;
--input-text-color: black;
--input-background-color: white;
@ -44,6 +47,9 @@ body.theme-black {
--button-border-color: #444;
--button-text-color: white;
--button-border-radius: 5px;
--primary-button-background-color: #888;
--primary-button-text-color: white;
--primary-button-border-color: #999;
--muted-text-color: #ccc;
--input-text-color: white;
--input-background-color: black;
@ -75,6 +81,9 @@ body.theme-dark {
--button-border-color: #444;
--button-text-color: white;
--button-border-radius: 5px;
--primary-button-background-color: #888;
--primary-button-text-color: white;
--primary-button-border-color: #999;
--muted-text-color: #ccc;
--input-text-color: white;
--input-background-color: #333;

View file

@ -1,7 +1,6 @@
"use strict";
const optionService = require('./options');
const utils = require('./utils');
const log = require('./log');
const ELECTRON = "electron";
@ -9,52 +8,52 @@ const ELECTRON = "electron";
const DEFAULT_KEYBOARD_ACTIONS = [
{
actionName: "JumpToNote",
defaultShortcuts: ["mod+j"],
defaultShortcuts: ["Mod+J"],
description: 'Open "Jump to note" dialog'
},
{
actionName: "MarkdownToHTML",
defaultShortcuts: ["mod+return"]
defaultShortcuts: ["Mod+Return"]
},
{
actionName: "NewTab",
defaultShortcuts: ["mod+t"],
defaultShortcuts: ["Mod+T"],
only: ELECTRON
},
{
actionName: "CloseTab",
defaultShortcuts: ["mod+w"],
defaultShortcuts: ["Mod+W"],
only: ELECTRON
},
{
actionName: "NextTab",
defaultShortcuts: ["mod+tab"],
defaultShortcuts: ["Mod+Tab"],
only: ELECTRON
},
{
actionName: "PreviousTab",
defaultShortcuts: ["mod+shift+tab"],
defaultShortcuts: ["Mod+SHIFT+Tab"],
only: ELECTRON
},
{
actionName: "CreateNoteAfter",
defaultShortcuts: ["mod+o"]
defaultShortcuts: ["Mod+O"]
},
{
actionName: "CreateNoteInto",
defaultShortcuts: ["mod+p"]
defaultShortcuts: ["Mod+P"]
},
{
actionName: "ScrollToActiveNote",
defaultShortcuts: ["mod+."]
defaultShortcuts: ["Mod+."]
},
{
actionName: "CollapseTree",
defaultShortcuts: ["alt+c"]
defaultShortcuts: ["Alt+C"]
},
{
actionName: "RunSQL",
defaultShortcuts: ["mod+return"]
defaultShortcuts: ["Mod+return"]
},
{
actionName: "FocusNote",
@ -62,51 +61,51 @@ const DEFAULT_KEYBOARD_ACTIONS = [
},
{
actionName: "RunCurrentNote",
defaultShortcuts: ["mod+return"]
defaultShortcuts: ["Mod+return"]
},
{
actionName: "ClipboardCopy",
defaultShortcuts: ["mod+c"]
defaultShortcuts: ["Mod+C"]
},
{
actionName: "ClipboardPaste",
defaultShortcuts: ["mod+v"]
defaultShortcuts: ["Mod+V"]
},
{
actionName: "ClipboardCut",
defaultShortcuts: ["mod+x"]
defaultShortcuts: ["Mod+X"]
},
{
actionName: "SelectAllNotesInParent",
defaultShortcuts: ["mod+a"]
defaultShortcuts: ["Mod+A"]
},
{
actionName: "Undo",
defaultShortcuts: ["mod+z"]
defaultShortcuts: ["Mod+Z"]
},
{
actionName: "Redo",
defaultShortcuts: ["mod+y"]
defaultShortcuts: ["Mod+Y"]
},
{
actionName: "AddLinkToText",
defaultShortcuts: ["mod+l"]
defaultShortcuts: ["Mod+L"]
},
{
actionName: "CloneNotesTo",
defaultShortcuts: ["mod+shift+c"]
defaultShortcuts: ["Mod+Shift+C"]
},
{
actionName: "MoveNotesTo",
defaultShortcuts: ["mod+shift+c"]
defaultShortcuts: ["Mod+Shift+C"]
},
{
actionName: "SearchNotes",
defaultShortcuts: ["mod+s"]
defaultShortcuts: ["Mod+S"]
},
{
actionName: "ShowAttributes",
defaultShortcuts: ["alt+a"]
defaultShortcuts: ["Alt+A"]
},
{
actionName: "ShowNoteInfo",
@ -134,58 +133,67 @@ const DEFAULT_KEYBOARD_ACTIONS = [
},
{
actionName: "ShowHelp",
defaultShortcuts: ["f1"]
defaultShortcuts: ["F1"]
},
{
actionName: "ShowSQLConsole",
defaultShortcuts: ["alt+o"]
defaultShortcuts: ["Alt+O"]
},
{
actionName: "BackInNoteHistory",
defaultShortcuts: ["alt+left"]
defaultShortcuts: ["Alt+Left"]
},
{
actionName: "ForwardInNoteHistory",
defaultShortcuts: ["alt+right"]
defaultShortcuts: ["Alt+Right"]
},
{
actionName: "ToggleZenMode",
defaultShortcuts: ["alt+m"]
defaultShortcuts: ["Alt+M"]
},
{
actionName: "InsertDateTime",
defaultShortcuts: ["alt+t"]
defaultShortcuts: ["Alt+T"]
},
{
actionName: "ReloadApp",
defaultShortcuts: ["f5", "mod+r"]
defaultShortcuts: ["F5", "Mod+R"]
},
{
actionName: "OpenDevTools",
defaultShortcuts: ["mod+shift+i"]
defaultShortcuts: ["Mod+SHIFT+I"]
},
{
actionName: "FindInText",
defaultShortcuts: ["mod+f"]
defaultShortcuts: ["Mod+F"]
},
{
actionName: "ToggleFullscreen",
defaultShortcuts: ["f11"]
defaultShortcuts: ["F11"]
},
{
actionName: "ZoomOut",
defaultShortcuts: ["mod+-"]
defaultShortcuts: ["Mod+-"]
},
{
actionName: "ZoomIn",
defaultShortcuts: ["mod+="]
defaultShortcuts: ["Mod+="]
}
];
if (process.platform === "darwin") {
for (const action of DEFAULT_KEYBOARD_ACTIONS) {
action.defaultShortcuts = action.defaultShortcuts.map(shortcut => shortcut.replace("Mod", "Meta"));
}
// Mac has a different history navigation shortcuts - https://github.com/zadam/trilium/issues/376
DEFAULT_KEYBOARD_ACTIONS.find(ka => ka.actionName === 'BackInNoteHistory').defaultShortcuts = ["meta+left"];
DEFAULT_KEYBOARD_ACTIONS.find(ka => ka.actionName === 'ForwardInNoteHistory').defaultShortcuts = ["meta+right"];
DEFAULT_KEYBOARD_ACTIONS.find(ka => ka.actionName === 'BackInNoteHistory').defaultShortcuts = ["Meta+Left"];
DEFAULT_KEYBOARD_ACTIONS.find(ka => ka.actionName === 'ForwardInNoteHistory').defaultShortcuts = ["Meta+Right"];
}
else {
for (const action of DEFAULT_KEYBOARD_ACTIONS) {
action.defaultShortcuts = action.defaultShortcuts.map(shortcut => shortcut.replace("Mod", "Ctrl"));
}
}
async function getKeyboardActions() {

View file

@ -14,7 +14,7 @@
<div id="confirm-dialog-custom"></div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary btn-sm" id="confirm-dialog-cancel-button">Cancel</button>
<button class="btn btn-sm" id="confirm-dialog-cancel-button">Cancel</button>
&nbsp;

View file

@ -16,6 +16,9 @@
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-sidebar">Sidebar</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-keyboard-shortcuts">Keyboard shortcuts</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-code-notes">Code notes</a>
</li>
@ -36,6 +39,7 @@
<div class="tab-content">
<div id="options-appearance" class="tab-pane active"></div>
<div id="options-sidebar" class="tab-pane"></div>
<div id="options-keyboard-shortcuts" class="tab-pane"></div>
<div id="options-code-notes" class="tab-pane"></div>
<div id="options-change-password" class="tab-pane"></div>
<div id="options-other" class="tab-pane"></div>