mirror of
https://github.com/zadam/trilium.git
synced 2026-01-18 12:34:24 +01:00
chore(core): integrate options, options_init & keyboard_actions
This commit is contained in:
parent
bd45c32251
commit
26d299aa44
@ -1,21 +1,11 @@
|
||||
import path from "path";
|
||||
import build from "./build.js";
|
||||
import packageJson from "../../package.json" with { type: "json" };
|
||||
import dataDir from "./data_dir.js";
|
||||
import { AppInfo } from "@triliumnext/commons";
|
||||
import { app_info as coreAppInfo } from "@triliumnext/core";
|
||||
import path from "path";
|
||||
|
||||
const APP_DB_VERSION = 233;
|
||||
const SYNC_VERSION = 36;
|
||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
||||
import dataDir from "./data_dir.js";
|
||||
|
||||
export default {
|
||||
appVersion: packageJson.version,
|
||||
dbVersion: APP_DB_VERSION,
|
||||
...coreAppInfo,
|
||||
nodeVersion: process.version,
|
||||
syncVersion: SYNC_VERSION,
|
||||
buildDate: build.buildDate,
|
||||
buildRevision: build.buildRevision,
|
||||
dataDirectory: path.resolve(dataDir.TRILIUM_DATA_DIR),
|
||||
clipperProtocolVersion: CLIPPER_PROTOCOL_VERSION,
|
||||
utcDateTime: new Date().toISOString()
|
||||
} satisfies AppInfo;
|
||||
|
||||
@ -1,882 +1,2 @@
|
||||
"use strict";
|
||||
|
||||
import optionService from "./options.js";
|
||||
import log from "./log.js";
|
||||
import { isElectron, isMac } from "./utils.js";
|
||||
import type { ActionKeyboardShortcut, KeyboardShortcut } from "@triliumnext/commons";
|
||||
import { t } from "i18next";
|
||||
|
||||
function getDefaultKeyboardActions() {
|
||||
if (!t("keyboard_actions.note-navigation")) {
|
||||
throw new Error("Keyboard actions loaded before translations.");
|
||||
}
|
||||
|
||||
const DEFAULT_KEYBOARD_ACTIONS: KeyboardShortcut[] = [
|
||||
{
|
||||
separator: t("keyboard_actions.note-navigation")
|
||||
},
|
||||
{
|
||||
actionName: "backInNoteHistory",
|
||||
friendlyName: t("keyboard_action_names.back-in-note-history"),
|
||||
iconClass: "bx bxs-chevron-left",
|
||||
// Mac has a different history navigation shortcuts - https://github.com/zadam/trilium/issues/376
|
||||
defaultShortcuts: isMac ? ["CommandOrControl+["] : ["Alt+Left"],
|
||||
description: t("keyboard_actions.back-in-note-history"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "forwardInNoteHistory",
|
||||
friendlyName: t("keyboard_action_names.forward-in-note-history"),
|
||||
iconClass: "bx bxs-chevron-right",
|
||||
// Mac has a different history navigation shortcuts - https://github.com/zadam/trilium/issues/376
|
||||
defaultShortcuts: isMac ? ["CommandOrControl+]"] : ["Alt+Right"],
|
||||
description: t("keyboard_actions.forward-in-note-history"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "jumpToNote",
|
||||
friendlyName: t("keyboard_action_names.jump-to-note"),
|
||||
defaultShortcuts: ["CommandOrControl+J"],
|
||||
description: t("keyboard_actions.open-jump-to-note-dialog"),
|
||||
scope: "window",
|
||||
ignoreFromCommandPalette: true
|
||||
},
|
||||
{
|
||||
actionName: "openTodayNote",
|
||||
friendlyName: t("hidden-subtree.open-today-journal-note-title"),
|
||||
iconClass: "bx bx-calendar",
|
||||
defaultShortcuts: [],
|
||||
description: t("hidden-subtree.open-today-journal-note-title"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "commandPalette",
|
||||
friendlyName: t("keyboard_action_names.command-palette"),
|
||||
defaultShortcuts: ["CommandOrControl+Shift+J"],
|
||||
description: t("keyboard_actions.open-command-palette"),
|
||||
scope: "window",
|
||||
ignoreFromCommandPalette: true
|
||||
},
|
||||
{
|
||||
actionName: "scrollToActiveNote",
|
||||
friendlyName: t("keyboard_action_names.scroll-to-active-note"),
|
||||
defaultShortcuts: ["CommandOrControl+."],
|
||||
iconClass: "bx bx-current-location",
|
||||
description: t("keyboard_actions.scroll-to-active-note"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "quickSearch",
|
||||
friendlyName: t("keyboard_action_names.quick-search"),
|
||||
iconClass: "bx bx-search",
|
||||
defaultShortcuts: ["CommandOrControl+S"],
|
||||
description: t("keyboard_actions.quick-search"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "searchInSubtree",
|
||||
friendlyName: t("keyboard_action_names.search-in-subtree"),
|
||||
defaultShortcuts: ["CommandOrControl+Shift+S"],
|
||||
iconClass: "bx bx-search-alt",
|
||||
description: t("keyboard_actions.search-in-subtree"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "expandSubtree",
|
||||
friendlyName: t("keyboard_action_names.expand-subtree"),
|
||||
defaultShortcuts: [],
|
||||
iconClass: "bx bx-layer-plus",
|
||||
description: t("keyboard_actions.expand-subtree"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "collapseTree",
|
||||
friendlyName: t("keyboard_action_names.collapse-tree"),
|
||||
defaultShortcuts: ["Alt+C"],
|
||||
iconClass: "bx bx-layer-minus",
|
||||
description: t("keyboard_actions.collapse-tree"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "collapseSubtree",
|
||||
friendlyName: t("keyboard_action_names.collapse-subtree"),
|
||||
iconClass: "bx bxs-layer-minus",
|
||||
defaultShortcuts: ["Alt+-"],
|
||||
description: t("keyboard_actions.collapse-subtree"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "sortChildNotes",
|
||||
friendlyName: t("keyboard_action_names.sort-child-notes"),
|
||||
iconClass: "bx bx-sort-down",
|
||||
defaultShortcuts: ["Alt+S"],
|
||||
description: t("keyboard_actions.sort-child-notes"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.creating-and-moving-notes")
|
||||
},
|
||||
{
|
||||
actionName: "createNoteAfter",
|
||||
friendlyName: t("keyboard_action_names.create-note-after"),
|
||||
iconClass: "bx bx-plus",
|
||||
defaultShortcuts: ["CommandOrControl+O"],
|
||||
description: t("keyboard_actions.create-note-after"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "createNoteInto",
|
||||
friendlyName: t("keyboard_action_names.create-note-into"),
|
||||
iconClass: "bx bx-plus",
|
||||
defaultShortcuts: ["CommandOrControl+P"],
|
||||
description: t("keyboard_actions.create-note-into"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "createNoteIntoInbox",
|
||||
friendlyName: t("keyboard_action_names.create-note-into-inbox"),
|
||||
iconClass: "bx bxs-inbox",
|
||||
defaultShortcuts: ["global:CommandOrControl+Alt+P"],
|
||||
description: t("keyboard_actions.create-note-into-inbox"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "deleteNotes",
|
||||
friendlyName: t("keyboard_action_names.delete-notes"),
|
||||
iconClass: "bx bx-trash",
|
||||
defaultShortcuts: ["Delete"],
|
||||
description: t("keyboard_actions.delete-note"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "moveNoteUp",
|
||||
friendlyName: t("keyboard_action_names.move-note-up"),
|
||||
iconClass: "bx bx-up-arrow-alt",
|
||||
defaultShortcuts: isMac ? ["Alt+Up"] : ["CommandOrControl+Up"],
|
||||
description: t("keyboard_actions.move-note-up"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "moveNoteDown",
|
||||
friendlyName: t("keyboard_action_names.move-note-down"),
|
||||
iconClass: "bx bx-down-arrow-alt",
|
||||
defaultShortcuts: isMac ? ["Alt+Down"] : ["CommandOrControl+Down"],
|
||||
description: t("keyboard_actions.move-note-down"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "moveNoteUpInHierarchy",
|
||||
friendlyName: t("keyboard_action_names.move-note-up-in-hierarchy"),
|
||||
iconClass: "bx bx-arrow-from-bottom",
|
||||
defaultShortcuts: isMac ? ["Alt+Left"] : ["CommandOrControl+Left"],
|
||||
description: t("keyboard_actions.move-note-up-in-hierarchy"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "moveNoteDownInHierarchy",
|
||||
friendlyName: t("keyboard_action_names.move-note-down-in-hierarchy"),
|
||||
iconClass: "bx bx-arrow-from-top",
|
||||
defaultShortcuts: isMac ? ["Alt+Right"] : ["CommandOrControl+Right"],
|
||||
description: t("keyboard_actions.move-note-down-in-hierarchy"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "editNoteTitle",
|
||||
friendlyName: t("keyboard_action_names.edit-note-title"),
|
||||
iconClass: "bx bx-rename",
|
||||
defaultShortcuts: ["Enter"],
|
||||
description: t("keyboard_actions.edit-note-title"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "editBranchPrefix",
|
||||
friendlyName: t("keyboard_action_names.edit-branch-prefix"),
|
||||
iconClass: "bx bx-rename",
|
||||
defaultShortcuts: ["F2"],
|
||||
description: t("keyboard_actions.edit-branch-prefix"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "cloneNotesTo",
|
||||
friendlyName: t("keyboard_action_names.clone-notes-to"),
|
||||
iconClass: "bx bx-duplicate",
|
||||
defaultShortcuts: ["CommandOrControl+Shift+C"],
|
||||
description: t("keyboard_actions.clone-notes-to"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "moveNotesTo",
|
||||
friendlyName: t("keyboard_action_names.move-notes-to"),
|
||||
iconClass: "bx bx-transfer",
|
||||
defaultShortcuts: ["CommandOrControl+Shift+X"],
|
||||
description: t("keyboard_actions.move-notes-to"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.note-clipboard")
|
||||
},
|
||||
|
||||
{
|
||||
actionName: "copyNotesToClipboard",
|
||||
friendlyName: t("keyboard_action_names.copy-notes-to-clipboard"),
|
||||
iconClass: "bx bx-copy",
|
||||
defaultShortcuts: ["CommandOrControl+C"],
|
||||
description: t("keyboard_actions.copy-notes-to-clipboard"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "pasteNotesFromClipboard",
|
||||
friendlyName: t("keyboard_action_names.paste-notes-from-clipboard"),
|
||||
iconClass: "bx bx-paste",
|
||||
defaultShortcuts: ["CommandOrControl+V"],
|
||||
description: t("keyboard_actions.paste-notes-from-clipboard"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "cutNotesToClipboard",
|
||||
friendlyName: t("keyboard_action_names.cut-notes-to-clipboard"),
|
||||
iconClass: "bx bx-cut",
|
||||
defaultShortcuts: ["CommandOrControl+X"],
|
||||
description: t("keyboard_actions.cut-notes-to-clipboard"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "selectAllNotesInParent",
|
||||
friendlyName: t("keyboard_action_names.select-all-notes-in-parent"),
|
||||
iconClass: "bx bx-select-multiple",
|
||||
defaultShortcuts: ["CommandOrControl+A"],
|
||||
description: t("keyboard_actions.select-all-notes-in-parent"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "addNoteAboveToSelection",
|
||||
friendlyName: t("keyboard_action_names.add-note-above-to-selection"),
|
||||
defaultShortcuts: ["Shift+Up"],
|
||||
description: t("keyboard_actions.add-note-above-to-the-selection"),
|
||||
scope: "note-tree",
|
||||
ignoreFromCommandPalette: true
|
||||
},
|
||||
{
|
||||
actionName: "addNoteBelowToSelection",
|
||||
friendlyName: t("keyboard_action_names.add-note-below-to-selection"),
|
||||
defaultShortcuts: ["Shift+Down"],
|
||||
description: t("keyboard_actions.add-note-below-to-selection"),
|
||||
scope: "note-tree",
|
||||
ignoreFromCommandPalette: true
|
||||
},
|
||||
{
|
||||
actionName: "duplicateSubtree",
|
||||
friendlyName: t("keyboard_action_names.duplicate-subtree"),
|
||||
iconClass: "bx bx-outline",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.duplicate-subtree"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.tabs-and-windows")
|
||||
},
|
||||
{
|
||||
actionName: "openNewTab",
|
||||
friendlyName: t("keyboard_action_names.open-new-tab"),
|
||||
iconClass: "bx bx-plus",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+T"] : [],
|
||||
description: t("keyboard_actions.open-new-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "closeActiveTab",
|
||||
friendlyName: t("keyboard_action_names.close-active-tab"),
|
||||
iconClass: "bx bx-minus",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+W"] : [],
|
||||
description: t("keyboard_actions.close-active-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "reopenLastTab",
|
||||
friendlyName: t("keyboard_action_names.reopen-last-tab"),
|
||||
iconClass: "bx bx-undo",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+Shift+T"] : [],
|
||||
isElectronOnly: true,
|
||||
description: t("keyboard_actions.reopen-last-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "activateNextTab",
|
||||
friendlyName: t("keyboard_action_names.activate-next-tab"),
|
||||
iconClass: "bx bx-skip-next",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+Tab", "CommandOrControl+PageDown"] : [],
|
||||
description: t("keyboard_actions.activate-next-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "activatePreviousTab",
|
||||
friendlyName: t("keyboard_action_names.activate-previous-tab"),
|
||||
iconClass: "bx bx-skip-previous",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+Shift+Tab", "CommandOrControl+PageUp"] : [],
|
||||
description: t("keyboard_actions.activate-previous-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "openNewWindow",
|
||||
friendlyName: t("keyboard_action_names.open-new-window"),
|
||||
iconClass: "bx bx-window-open",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.open-new-window"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleTray",
|
||||
friendlyName: t("keyboard_action_names.toggle-system-tray-icon"),
|
||||
iconClass: "bx bx-show",
|
||||
defaultShortcuts: [],
|
||||
isElectronOnly: true,
|
||||
description: t("keyboard_actions.toggle-tray"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleZenMode",
|
||||
friendlyName: t("keyboard_action_names.toggle-zen-mode"),
|
||||
iconClass: "bx bxs-yin-yang",
|
||||
defaultShortcuts: ["F9"],
|
||||
description: t("keyboard_actions.toggle-zen-mode"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "firstTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-first-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+1"],
|
||||
description: t("keyboard_actions.first-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "secondTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-second-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+2"],
|
||||
description: t("keyboard_actions.second-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "thirdTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-third-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+3"],
|
||||
description: t("keyboard_actions.third-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "fourthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-fourth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+4"],
|
||||
description: t("keyboard_actions.fourth-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "fifthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-fifth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+5"],
|
||||
description: t("keyboard_actions.fifth-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "sixthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-sixth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+6"],
|
||||
description: t("keyboard_actions.sixth-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "seventhTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-seventh-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+7"],
|
||||
description: t("keyboard_actions.seventh-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "eigthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-eighth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+8"],
|
||||
description: t("keyboard_actions.eight-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "ninthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-ninth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+9"],
|
||||
description: t("keyboard_actions.ninth-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "lastTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-last-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+0"],
|
||||
description: t("keyboard_actions.last-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.dialogs")
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-note-source"),
|
||||
actionName: "showNoteSource",
|
||||
iconClass: "bx bx-code",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-note-source"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-options"),
|
||||
actionName: "showOptions",
|
||||
iconClass: "bx bx-cog",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-options"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-revisions"),
|
||||
actionName: "showRevisions",
|
||||
iconClass: "bx bx-history",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-revisions"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-recent-changes"),
|
||||
actionName: "showRecentChanges",
|
||||
iconClass: "bx bx-history",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-recent-changes"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-sql-console"),
|
||||
actionName: "showSQLConsole",
|
||||
iconClass: "bx bx-data",
|
||||
defaultShortcuts: ["Alt+O"],
|
||||
description: t("keyboard_actions.show-sql-console"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-backend-log"),
|
||||
actionName: "showBackendLog",
|
||||
iconClass: "bx bx-detail",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-backend-log"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-help"),
|
||||
actionName: "showHelp",
|
||||
iconClass: "bx bx-help-circle",
|
||||
defaultShortcuts: ["F1"],
|
||||
description: t("keyboard_actions.show-help"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-cheatsheet"),
|
||||
actionName: "showCheatsheet",
|
||||
iconClass: "bx bxs-keyboard",
|
||||
defaultShortcuts: ["Shift+F1"],
|
||||
description: t("keyboard_actions.show-cheatsheet"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.text-note-operations")
|
||||
},
|
||||
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.add-link-to-text"),
|
||||
actionName: "addLinkToText",
|
||||
iconClass: "bx bx-link",
|
||||
defaultShortcuts: ["CommandOrControl+L"],
|
||||
description: t("keyboard_actions.add-link-to-text"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.follow-link-under-cursor"),
|
||||
actionName: "followLinkUnderCursor",
|
||||
iconClass: "bx bx-link-external",
|
||||
defaultShortcuts: ["CommandOrControl+Enter"],
|
||||
description: t("keyboard_actions.follow-link-under-cursor"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.insert-date-and-time-to-text"),
|
||||
actionName: "insertDateTimeToText",
|
||||
iconClass: "bx bx-calendar-event",
|
||||
defaultShortcuts: ["Alt+T"],
|
||||
description: t("keyboard_actions.insert-date-and-time-to-text"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.paste-markdown-into-text"),
|
||||
actionName: "pasteMarkdownIntoText",
|
||||
iconClass: "bx bxl-markdown",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.paste-markdown-into-text"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.cut-into-note"),
|
||||
actionName: "cutIntoNote",
|
||||
iconClass: "bx bx-cut",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.cut-into-note"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.add-include-note-to-text"),
|
||||
actionName: "addIncludeNoteToText",
|
||||
iconClass: "bx bx-note",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.add-include-note-to-text"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.edit-read-only-note"),
|
||||
actionName: "editReadOnlyNote",
|
||||
iconClass: "bx bx-edit-alt",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.edit-readonly-note"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.attributes-labels-and-relations")
|
||||
},
|
||||
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.add-new-label"),
|
||||
actionName: "addNewLabel",
|
||||
iconClass: "bx bx-hash",
|
||||
defaultShortcuts: ["Alt+L"],
|
||||
description: t("keyboard_actions.add-new-label"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.add-new-relation"),
|
||||
actionName: "addNewRelation",
|
||||
iconClass: "bx bx-transfer",
|
||||
defaultShortcuts: ["Alt+R"],
|
||||
description: t("keyboard_actions.create-new-relation"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.ribbon-tabs")
|
||||
},
|
||||
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-classic-editor"),
|
||||
actionName: "toggleRibbonTabClassicEditor",
|
||||
iconClass: "bx bx-text",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-classic-editor-toolbar"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabBasicProperties",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-basic-properties"),
|
||||
iconClass: "bx bx-slider",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-basic-properties"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabBookProperties",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-book-properties"),
|
||||
iconClass: "bx bx-book",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-book-properties"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabFileProperties",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-file-properties"),
|
||||
iconClass: "bx bx-file",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-file-properties"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabImageProperties",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-image-properties"),
|
||||
iconClass: "bx bx-image",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-image-properties"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabOwnedAttributes",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-owned-attributes"),
|
||||
iconClass: "bx bx-list-check",
|
||||
defaultShortcuts: ["Alt+A"],
|
||||
description: t("keyboard_actions.toggle-owned-attributes"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabInheritedAttributes",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-inherited-attributes"),
|
||||
iconClass: "bx bx-list-plus",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-inherited-attributes"),
|
||||
scope: "window"
|
||||
},
|
||||
// TODO: Remove or change since promoted attributes have been changed.
|
||||
{
|
||||
actionName: "toggleRibbonTabPromotedAttributes",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-promoted-attributes"),
|
||||
iconClass: "bx bx-star",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-promoted-attributes"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabNoteMap",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-note-map"),
|
||||
iconClass: "bx bxs-network-chart",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-link-map"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabNoteInfo",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-note-info"),
|
||||
iconClass: "bx bx-info-circle",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-note-info"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabNotePaths",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-note-paths"),
|
||||
iconClass: "bx bx-collection",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-note-paths"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabSimilarNotes",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-similar-notes"),
|
||||
iconClass: "bx bx-bar-chart",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-similar-notes"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.other")
|
||||
},
|
||||
|
||||
{
|
||||
actionName: "toggleRightPane",
|
||||
friendlyName: t("keyboard_action_names.toggle-right-pane"),
|
||||
iconClass: "bx bx-dock-right",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-right-pane"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "printActiveNote",
|
||||
friendlyName: t("keyboard_action_names.print-active-note"),
|
||||
iconClass: "bx bx-printer",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.print-active-note"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "exportAsPdf",
|
||||
friendlyName: t("keyboard_action_names.export-active-note-as-pdf"),
|
||||
iconClass: "bx bxs-file-pdf",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.export-as-pdf"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "openNoteExternally",
|
||||
friendlyName: t("keyboard_action_names.open-note-externally"),
|
||||
iconClass: "bx bx-file-find",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.open-note-externally"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "renderActiveNote",
|
||||
friendlyName: t("keyboard_action_names.render-active-note"),
|
||||
iconClass: "bx bx-refresh",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.render-active-note"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "runActiveNote",
|
||||
friendlyName: t("keyboard_action_names.run-active-note"),
|
||||
iconClass: "bx bx-play",
|
||||
defaultShortcuts: ["CommandOrControl+Enter"],
|
||||
description: t("keyboard_actions.run-active-note"),
|
||||
scope: "code-detail"
|
||||
},
|
||||
{
|
||||
actionName: "toggleNoteHoisting",
|
||||
friendlyName: t("keyboard_action_names.toggle-note-hoisting"),
|
||||
iconClass: "bx bx-chevrons-up",
|
||||
defaultShortcuts: ["Alt+H"],
|
||||
description: t("keyboard_actions.toggle-note-hoisting"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "unhoist",
|
||||
friendlyName: t("keyboard_action_names.unhoist-note"),
|
||||
iconClass: "bx bx-door-open",
|
||||
defaultShortcuts: ["Alt+U"],
|
||||
description: t("keyboard_actions.unhoist"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "reloadFrontendApp",
|
||||
friendlyName: t("keyboard_action_names.reload-frontend-app"),
|
||||
iconClass: "bx bx-refresh",
|
||||
defaultShortcuts: ["F5", "CommandOrControl+R"],
|
||||
description: t("keyboard_actions.reload-frontend-app"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "openDevTools",
|
||||
friendlyName: t("keyboard_action_names.open-developer-tools"),
|
||||
iconClass: "bx bx-bug-alt",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+Shift+I"] : [],
|
||||
isElectronOnly: true,
|
||||
description: t("keyboard_actions.open-dev-tools"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "findInText",
|
||||
friendlyName: t("keyboard_action_names.find-in-text"),
|
||||
iconClass: "bx bx-search",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+F"] : [],
|
||||
description: t("keyboard_actions.find-in-text"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleLeftPane",
|
||||
friendlyName: t("keyboard_action_names.toggle-left-pane"),
|
||||
iconClass: "bx bx-sidebar",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-left-note-tree-panel"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleFullscreen",
|
||||
friendlyName: t("keyboard_action_names.toggle-full-screen"),
|
||||
iconClass: "bx bx-fullscreen",
|
||||
defaultShortcuts: ["F11"],
|
||||
description: t("keyboard_actions.toggle-full-screen"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "zoomOut",
|
||||
friendlyName: t("keyboard_action_names.zoom-out"),
|
||||
iconClass: "bx bx-zoom-out",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+-"] : [],
|
||||
isElectronOnly: true,
|
||||
description: t("keyboard_actions.zoom-out"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "zoomIn",
|
||||
friendlyName: t("keyboard_action_names.zoom-in"),
|
||||
iconClass: "bx bx-zoom-in",
|
||||
description: t("keyboard_actions.zoom-in"),
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+="] : [],
|
||||
isElectronOnly: true,
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "zoomReset",
|
||||
friendlyName: t("keyboard_action_names.reset-zoom-level"),
|
||||
iconClass: "bx bx-search-alt",
|
||||
description: t("keyboard_actions.reset-zoom-level"),
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+0"] : [],
|
||||
isElectronOnly: true,
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "copyWithoutFormatting",
|
||||
friendlyName: t("keyboard_action_names.copy-without-formatting"),
|
||||
iconClass: "bx bx-copy-alt",
|
||||
defaultShortcuts: ["CommandOrControl+Alt+C"],
|
||||
description: t("keyboard_actions.copy-without-formatting"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
actionName: "forceSaveRevision",
|
||||
friendlyName: t("keyboard_action_names.force-save-revision"),
|
||||
iconClass: "bx bx-save",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.force-save-revision"),
|
||||
scope: "window"
|
||||
}
|
||||
];
|
||||
|
||||
/*
|
||||
* Apply macOS-specific tweaks.
|
||||
*/
|
||||
const platformModifier = isMac ? "Meta" : "Ctrl";
|
||||
|
||||
for (const action of DEFAULT_KEYBOARD_ACTIONS) {
|
||||
if ("defaultShortcuts" in action && action.defaultShortcuts) {
|
||||
action.defaultShortcuts = action.defaultShortcuts.map((shortcut) => shortcut.replace("CommandOrControl", platformModifier));
|
||||
}
|
||||
}
|
||||
|
||||
return DEFAULT_KEYBOARD_ACTIONS;
|
||||
}
|
||||
|
||||
function getKeyboardActions() {
|
||||
const actions: KeyboardShortcut[] = JSON.parse(JSON.stringify(getDefaultKeyboardActions()));
|
||||
|
||||
for (const action of actions) {
|
||||
if ("effectiveShortcuts" in action && action.effectiveShortcuts) {
|
||||
action.effectiveShortcuts = action.defaultShortcuts ? action.defaultShortcuts.slice() : [];
|
||||
}
|
||||
}
|
||||
|
||||
for (const option of optionService.getOptions()) {
|
||||
if (option.name.startsWith("keyboardShortcuts")) {
|
||||
let actionName = option.name.substring(17);
|
||||
actionName = actionName.charAt(0).toLowerCase() + actionName.slice(1);
|
||||
|
||||
const action = actions.find((ea) => "actionName" in ea && ea.actionName === actionName) as ActionKeyboardShortcut;
|
||||
|
||||
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} found in database, but not in action definition.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
export default {
|
||||
getDefaultKeyboardActions,
|
||||
getKeyboardActions
|
||||
};
|
||||
import { keyboard_actions } from "@triliumnext/core";
|
||||
export default keyboard_actions;
|
||||
|
||||
@ -1,145 +1,2 @@
|
||||
/**
|
||||
* @module
|
||||
*
|
||||
* Options are key-value pairs that are used to store information such as user preferences (for example
|
||||
* the current theme, sync server information), but also information about the state of the application.
|
||||
*
|
||||
* Although options internally are represented as strings, their value can be interpreted as a number or
|
||||
* boolean by calling the appropriate methods from this service (e.g. {@link #getOptionInt}).\
|
||||
*
|
||||
* Generally options are shared across multiple instances of the application via the sync mechanism,
|
||||
* however it is possible to have options that are local to an instance. For example, the user can select
|
||||
* a theme on a device and it will not affect other devices.
|
||||
*/
|
||||
|
||||
import becca from "../becca/becca.js";
|
||||
import BOption from "../becca/entities/boption.js";
|
||||
import type { OptionRow } from "@triliumnext/commons";
|
||||
import type { FilterOptionsByType, OptionDefinitions, OptionMap, OptionNames } from "@triliumnext/commons";
|
||||
import sql from "./sql.js";
|
||||
|
||||
function getOptionOrNull(name: OptionNames): string | null {
|
||||
let option;
|
||||
|
||||
if (becca.loaded) {
|
||||
option = becca.getOption(name);
|
||||
} else {
|
||||
// e.g. in initial sync becca is not loaded because DB is not initialized
|
||||
try {
|
||||
option = sql.getRow<OptionRow>("SELECT * FROM options WHERE name = ?", [name]);
|
||||
} catch (e: unknown) {
|
||||
// DB is not initialized.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return option ? option.value : null;
|
||||
}
|
||||
|
||||
function getOption(name: OptionNames) {
|
||||
const val = getOptionOrNull(name);
|
||||
|
||||
if (val === null) {
|
||||
throw new Error(`Option '${name}' doesn't exist`);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function getOptionInt(name: FilterOptionsByType<number>, defaultValue?: number): number {
|
||||
const val = getOption(name);
|
||||
|
||||
const intVal = parseInt(val);
|
||||
|
||||
if (isNaN(intVal)) {
|
||||
if (defaultValue === undefined) {
|
||||
throw new Error(`Could not parse '${val}' into integer for option '${name}'`);
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return intVal;
|
||||
}
|
||||
|
||||
function getOptionBool(name: FilterOptionsByType<boolean>): boolean {
|
||||
const val = getOption(name);
|
||||
|
||||
if (typeof val !== "string" || !["true", "false"].includes(val)) {
|
||||
throw new Error(`Could not parse '${val}' into boolean for option '${name}'`);
|
||||
}
|
||||
|
||||
return val === "true";
|
||||
}
|
||||
|
||||
function setOption<T extends OptionNames>(name: T, value: string | OptionDefinitions[T]) {
|
||||
const option = becca.getOption(name);
|
||||
|
||||
if (option) {
|
||||
option.value = value as string;
|
||||
|
||||
option.save();
|
||||
} else {
|
||||
createOption(name, value, false);
|
||||
}
|
||||
|
||||
// Clear current AI provider when AI-related options change
|
||||
const aiOptions = [
|
||||
'aiSelectedProvider', 'openaiApiKey', 'openaiBaseUrl', 'openaiDefaultModel',
|
||||
'anthropicApiKey', 'anthropicBaseUrl', 'anthropicDefaultModel',
|
||||
'ollamaBaseUrl', 'ollamaDefaultModel'
|
||||
];
|
||||
|
||||
if (aiOptions.includes(name)) {
|
||||
// Import dynamically to avoid circular dependencies
|
||||
setImmediate(async () => {
|
||||
try {
|
||||
const aiServiceManager = (await import('./llm/ai_service_manager.js')).default;
|
||||
aiServiceManager.getInstance().clearCurrentProvider();
|
||||
console.log(`Cleared AI provider after ${name} option changed`);
|
||||
} catch (error) {
|
||||
console.log(`Could not clear AI provider: ${error}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new option in the database, with the given name, value and whether it should be synced.
|
||||
*
|
||||
* @param name the name of the option to be created.
|
||||
* @param value the value of the option, as a string. It can then be interpreted as other types such as a number of boolean.
|
||||
* @param isSynced `true` if the value should be synced across multiple instances (e.g. locale) or `false` if it should be local-only (e.g. theme).
|
||||
*/
|
||||
function createOption<T extends OptionNames>(name: T, value: string | OptionDefinitions[T], isSynced: boolean) {
|
||||
new BOption({
|
||||
name: name,
|
||||
value: value as string,
|
||||
isSynced: isSynced
|
||||
}).save();
|
||||
}
|
||||
|
||||
function getOptions() {
|
||||
return Object.values(becca.options);
|
||||
}
|
||||
|
||||
function getOptionMap() {
|
||||
const map: Record<string, string> = {};
|
||||
|
||||
for (const option of Object.values(becca.options)) {
|
||||
map[option.name] = option.value;
|
||||
}
|
||||
|
||||
return map as OptionMap;
|
||||
}
|
||||
|
||||
export default {
|
||||
getOption,
|
||||
getOptionInt,
|
||||
getOptionBool,
|
||||
setOption,
|
||||
createOption,
|
||||
getOptions,
|
||||
getOptionMap,
|
||||
getOptionOrNull
|
||||
};
|
||||
import { options } from "@triliumnext/core";
|
||||
export default options;
|
||||
|
||||
@ -1,280 +1,2 @@
|
||||
import { type KeyboardShortcutWithRequiredActionName, type OptionMap, type OptionNames, SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/commons";
|
||||
|
||||
import appInfo from "./app_info.js";
|
||||
import dateUtils from "./date_utils.js";
|
||||
import keyboardActions from "./keyboard_actions.js";
|
||||
import log from "./log.js";
|
||||
import optionService from "./options.js";
|
||||
import { isWindows, randomSecureToken } from "./utils.js";
|
||||
|
||||
function initDocumentOptions() {
|
||||
optionService.createOption("documentId", randomSecureToken(16), false);
|
||||
optionService.createOption("documentSecret", randomSecureToken(16), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains additional options to be initialized for a new database, containing the information entered by the user.
|
||||
*/
|
||||
interface NotSyncedOpts {
|
||||
syncServerHost?: string;
|
||||
syncProxy?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a correspondence between an option and its default value, to be initialized when the database is missing that particular option (after a migration from an older version, or when creating a new database).
|
||||
*/
|
||||
interface DefaultOption {
|
||||
name: OptionNames;
|
||||
/**
|
||||
* The value to initialize the option with, if the option is not already present in the database.
|
||||
*
|
||||
* If a function is passed Gin instead, the function is called if the option does not exist (with access to the current options) and the return value is used instead. Useful to migrate a new option with a value depending on some other option that might be initialized.
|
||||
*/
|
||||
value: string | ((options: OptionMap) => string);
|
||||
isSynced: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the default options for new databases only.
|
||||
*
|
||||
* @param initialized `true` if the database has been fully initialized (i.e. a new database was created), or `false` if the database is created for sync.
|
||||
* @param opts additional options to be initialized, for example the sync configuration.
|
||||
*/
|
||||
async function initNotSyncedOptions(initialized: boolean, opts: NotSyncedOpts = {}) {
|
||||
optionService.createOption(
|
||||
"openNoteContexts",
|
||||
JSON.stringify([
|
||||
{
|
||||
notePath: "root",
|
||||
active: true
|
||||
}
|
||||
]),
|
||||
false
|
||||
);
|
||||
|
||||
optionService.createOption("lastDailyBackupDate", dateUtils.utcNowDateTime(), false);
|
||||
optionService.createOption("lastWeeklyBackupDate", dateUtils.utcNowDateTime(), false);
|
||||
optionService.createOption("lastMonthlyBackupDate", dateUtils.utcNowDateTime(), false);
|
||||
optionService.createOption("dbVersion", appInfo.dbVersion.toString(), false);
|
||||
|
||||
optionService.createOption("initialized", initialized ? "true" : "false", false);
|
||||
|
||||
optionService.createOption("lastSyncedPull", "0", false);
|
||||
optionService.createOption("lastSyncedPush", "0", false);
|
||||
|
||||
optionService.createOption("theme", "next", false);
|
||||
optionService.createOption("textNoteEditorType", "ckeditor-classic", true);
|
||||
|
||||
optionService.createOption("syncServerHost", opts.syncServerHost || "", false);
|
||||
optionService.createOption("syncServerTimeout", "120000", false);
|
||||
optionService.createOption("syncProxy", opts.syncProxy || "", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains all the default options that must be initialized on new and existing databases (at startup). The value can also be determined based on other options, provided they have already been initialized.
|
||||
*/
|
||||
const defaultOptions: DefaultOption[] = [
|
||||
{ name: "revisionSnapshotTimeInterval", value: "600", isSynced: true },
|
||||
{ name: "revisionSnapshotTimeIntervalTimeScale", value: "60", isSynced: true }, // default to Minutes
|
||||
{ name: "revisionSnapshotNumberLimit", value: "-1", isSynced: true },
|
||||
{ name: "protectedSessionTimeout", value: "600", isSynced: true },
|
||||
{ name: "protectedSessionTimeoutTimeScale", value: "60", isSynced: true },
|
||||
{ name: "zoomFactor", value: isWindows ? "0.9" : "1.0", isSynced: false },
|
||||
{ name: "overrideThemeFonts", value: "false", isSynced: false },
|
||||
{ name: "mainFontFamily", value: "theme", isSynced: false },
|
||||
{ name: "mainFontSize", value: "100", isSynced: false },
|
||||
{ name: "treeFontFamily", value: "theme", isSynced: false },
|
||||
{ name: "treeFontSize", value: "100", isSynced: false },
|
||||
{ name: "detailFontFamily", value: "theme", isSynced: false },
|
||||
{ name: "detailFontSize", value: "110", isSynced: false },
|
||||
{ name: "monospaceFontFamily", value: "theme", isSynced: false },
|
||||
{ name: "monospaceFontSize", value: "110", isSynced: false },
|
||||
{ name: "spellCheckEnabled", value: "true", isSynced: false },
|
||||
{ name: "spellCheckLanguageCode", value: "en-US", isSynced: false },
|
||||
{ name: "imageMaxWidthHeight", value: "2000", isSynced: true },
|
||||
{ name: "imageJpegQuality", value: "75", isSynced: true },
|
||||
{ name: "autoFixConsistencyIssues", value: "true", isSynced: false },
|
||||
{ name: "vimKeymapEnabled", value: "false", isSynced: false },
|
||||
{ name: "codeLineWrapEnabled", value: "true", isSynced: false },
|
||||
{
|
||||
name: "codeNotesMimeTypes",
|
||||
value: '["text/x-csrc","text/x-c++src","text/x-csharp","text/css","text/x-elixir","text/x-go","text/x-groovy","text/x-haskell","text/html","message/http","text/x-java","application/javascript;env=frontend","application/javascript;env=backend","application/json","text/x-kotlin","text/x-markdown","text/x-perl","text/x-php","text/x-python","text/x-ruby",null,"text/x-sql","text/x-sqlite;schema=trilium","text/x-swift","text/xml","text/x-yaml","text/x-sh","application/typescript"]',
|
||||
isSynced: true
|
||||
},
|
||||
{ name: "leftPaneWidth", value: "25", isSynced: false },
|
||||
{ name: "leftPaneVisible", value: "true", isSynced: false },
|
||||
{ name: "rightPaneWidth", value: "25", isSynced: false },
|
||||
{ name: "rightPaneVisible", value: "true", isSynced: false },
|
||||
{ name: "rightPaneCollapsedItems", value: "[]", isSynced: false },
|
||||
{ name: "nativeTitleBarVisible", value: "false", isSynced: false },
|
||||
{ name: "eraseEntitiesAfterTimeInSeconds", value: "604800", isSynced: true }, // default is 7 days
|
||||
{ name: "eraseEntitiesAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day
|
||||
{ name: "hideArchivedNotes_main", value: "false", isSynced: false },
|
||||
{ name: "debugModeEnabled", value: "false", isSynced: false },
|
||||
{ name: "headingStyle", value: "underline", isSynced: true },
|
||||
{ name: "autoCollapseNoteTree", value: "true", isSynced: true },
|
||||
{ name: "autoReadonlySizeText", value: "32000", isSynced: false },
|
||||
{ name: "autoReadonlySizeCode", value: "64000", isSynced: false },
|
||||
{ name: "dailyBackupEnabled", value: "true", isSynced: false },
|
||||
{ name: "weeklyBackupEnabled", value: "true", isSynced: false },
|
||||
{ name: "monthlyBackupEnabled", value: "true", isSynced: false },
|
||||
{ name: "maxContentWidth", value: "1200", isSynced: false },
|
||||
{ name: "centerContent", value: "false", isSynced: false },
|
||||
{ name: "compressImages", value: "true", isSynced: true },
|
||||
{ name: "downloadImagesAutomatically", value: "true", isSynced: true },
|
||||
{ name: "minTocHeadings", value: "5", isSynced: true },
|
||||
{ name: "highlightsList", value: '["underline","color","bgColor"]', isSynced: true },
|
||||
{ name: "checkForUpdates", value: "true", isSynced: true },
|
||||
{ name: "disableTray", value: "false", isSynced: false },
|
||||
{ name: "eraseUnusedAttachmentsAfterSeconds", value: "2592000", isSynced: true }, // default 30 days
|
||||
{ name: "eraseUnusedAttachmentsAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day
|
||||
{ name: "logRetentionDays", value: "90", isSynced: false }, // default 90 days
|
||||
{ name: "customSearchEngineName", value: "DuckDuckGo", isSynced: true },
|
||||
{ name: "customSearchEngineUrl", value: "https://duckduckgo.com/?q={keyword}", isSynced: true },
|
||||
{ name: "editedNotesOpenInRibbon", value: "true", isSynced: true },
|
||||
{ name: "mfaEnabled", value: "false", isSynced: false },
|
||||
{ name: "mfaMethod", value: "totp", isSynced: false },
|
||||
{ name: "encryptedRecoveryCodes", value: "false", isSynced: false },
|
||||
{ name: "userSubjectIdentifierSaved", value: "false", isSynced: false },
|
||||
|
||||
// Appearance
|
||||
{ name: "splitEditorOrientation", value: "horizontal", isSynced: true },
|
||||
{
|
||||
name: "codeNoteTheme",
|
||||
value: (optionsMap) => {
|
||||
switch (optionsMap.theme) {
|
||||
case "light":
|
||||
case "next-light":
|
||||
return "default:vs-code-light";
|
||||
case "dark":
|
||||
case "next-dark":
|
||||
default:
|
||||
return "default:vs-code-dark";
|
||||
}
|
||||
},
|
||||
isSynced: false
|
||||
},
|
||||
{ name: "motionEnabled", value: "true", isSynced: false },
|
||||
{ name: "shadowsEnabled", value: "true", isSynced: false },
|
||||
{ name: "backdropEffectsEnabled", value: "true", isSynced: false },
|
||||
{ name: "smoothScrollEnabled", value: "true", isSynced: false },
|
||||
{ name: "newLayout", value: "true", isSynced: true },
|
||||
|
||||
// Internationalization
|
||||
{ name: "locale", value: "en", isSynced: true },
|
||||
{ name: "formattingLocale", value: "", isSynced: true }, // no value means auto-detect
|
||||
{ name: "firstDayOfWeek", value: "1", isSynced: true },
|
||||
{ name: "firstWeekOfYear", value: "0", isSynced: true },
|
||||
{ name: "minDaysInFirstWeek", value: "4", isSynced: true },
|
||||
{ name: "languages", value: "[]", isSynced: true },
|
||||
|
||||
// Code block configuration
|
||||
{
|
||||
name: "codeBlockTheme",
|
||||
value: (optionsMap) => {
|
||||
if (optionsMap.theme === "light") {
|
||||
return "default:stackoverflow-light";
|
||||
}
|
||||
return "default:stackoverflow-dark";
|
||||
|
||||
},
|
||||
isSynced: false
|
||||
},
|
||||
{ name: "codeBlockWordWrap", value: "false", isSynced: true },
|
||||
|
||||
// Text note configuration
|
||||
{ name: "textNoteEditorType", value: "ckeditor-balloon", isSynced: true },
|
||||
{ name: "textNoteEditorMultilineToolbar", value: "false", isSynced: true },
|
||||
{ name: "textNoteEmojiCompletionEnabled", value: "true", isSynced: true },
|
||||
{ name: "textNoteCompletionEnabled", value: "true", isSynced: true },
|
||||
{ name: "textNoteSlashCommandsEnabled", value: "true", isSynced: true },
|
||||
|
||||
// HTML import configuration
|
||||
{ name: "layoutOrientation", value: "vertical", isSynced: false },
|
||||
{ name: "backgroundEffects", value: "true", isSynced: false },
|
||||
{
|
||||
name: "allowedHtmlTags",
|
||||
value: JSON.stringify(SANITIZER_DEFAULT_ALLOWED_TAGS),
|
||||
isSynced: true
|
||||
},
|
||||
|
||||
// Share settings
|
||||
{ name: "redirectBareDomain", value: "false", isSynced: true },
|
||||
{ name: "showLoginInShareTheme", value: "false", isSynced: true },
|
||||
|
||||
// AI Options
|
||||
{ name: "aiEnabled", value: "false", isSynced: true },
|
||||
{ name: "openaiApiKey", value: "", isSynced: false },
|
||||
{ name: "openaiDefaultModel", value: "", isSynced: true },
|
||||
{ name: "openaiBaseUrl", value: "https://api.openai.com/v1", isSynced: true },
|
||||
{ name: "anthropicApiKey", value: "", isSynced: false },
|
||||
{ name: "anthropicDefaultModel", value: "", isSynced: true },
|
||||
{ name: "voyageApiKey", value: "", isSynced: false },
|
||||
{ name: "anthropicBaseUrl", value: "https://api.anthropic.com/v1", isSynced: true },
|
||||
{ name: "ollamaEnabled", value: "false", isSynced: true },
|
||||
{ name: "ollamaDefaultModel", value: "", isSynced: true },
|
||||
{ name: "ollamaBaseUrl", value: "http://localhost:11434", isSynced: true },
|
||||
{ name: "aiTemperature", value: "0.7", isSynced: true },
|
||||
{ name: "aiSystemPrompt", value: "", isSynced: true },
|
||||
{ name: "aiSelectedProvider", value: "openai", isSynced: true },
|
||||
|
||||
{
|
||||
name: "seenCallToActions",
|
||||
value: JSON.stringify([
|
||||
"new_layout", "background_effects", "next_theme"
|
||||
]),
|
||||
isSynced: true
|
||||
},
|
||||
{ name: "experimentalFeatures", value: "[]", isSynced: true }
|
||||
];
|
||||
|
||||
/**
|
||||
* Initializes the options, by checking which options from {@link #allDefaultOptions()} are missing and registering them. It will also check some environment variables such as safe mode, to make any necessary adjustments.
|
||||
*
|
||||
* This method is called regardless of whether a new database is created, or an existing database is used.
|
||||
*/
|
||||
function initStartupOptions() {
|
||||
const optionsMap = optionService.getOptionMap();
|
||||
|
||||
const allDefaultOptions = defaultOptions.concat(getKeyboardDefaultOptions());
|
||||
|
||||
for (const { name, value, isSynced } of allDefaultOptions) {
|
||||
if (!(name in optionsMap)) {
|
||||
let resolvedValue;
|
||||
if (typeof value === "function") {
|
||||
resolvedValue = value(optionsMap);
|
||||
} else {
|
||||
resolvedValue = value;
|
||||
}
|
||||
|
||||
optionService.createOption(name, resolvedValue, isSynced);
|
||||
log.info(`Created option "${name}" with default value "${resolvedValue}"`);
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.TRILIUM_START_NOTE_ID || process.env.TRILIUM_SAFE_MODE) {
|
||||
optionService.setOption(
|
||||
"openNoteContexts",
|
||||
JSON.stringify([
|
||||
{
|
||||
notePath: process.env.TRILIUM_START_NOTE_ID || "root",
|
||||
active: true
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getKeyboardDefaultOptions() {
|
||||
return (keyboardActions.getDefaultKeyboardActions().filter((ka) => "actionName" in ka) as KeyboardShortcutWithRequiredActionName[]).map((ka) => ({
|
||||
name: `keyboardShortcuts${ka.actionName.charAt(0).toUpperCase()}${ka.actionName.slice(1)}`,
|
||||
value: JSON.stringify(ka.defaultShortcuts),
|
||||
isSynced: false
|
||||
})) as DefaultOption[];
|
||||
}
|
||||
|
||||
export default {
|
||||
initDocumentOptions,
|
||||
initNotSyncedOptions,
|
||||
initStartupOptions
|
||||
};
|
||||
import { options_init } from "@triliumnext/core";
|
||||
export default options_init;
|
||||
|
||||
@ -11,11 +11,11 @@ type Response = {
|
||||
export interface AppInfo {
|
||||
appVersion: string;
|
||||
dbVersion: number;
|
||||
nodeVersion: string;
|
||||
nodeVersion?: string;
|
||||
syncVersion: number;
|
||||
buildDate: string;
|
||||
buildRevision: string;
|
||||
dataDirectory: string;
|
||||
dataDirectory?: string;
|
||||
clipperProtocolVersion: string;
|
||||
/** for timezone inference */
|
||||
utcDateTime: string;
|
||||
|
||||
@ -10,9 +10,14 @@ export * as protected_session from "./services/protected_session";
|
||||
export { default as data_encryption } from "./services/encryption/data_encryption"
|
||||
export * as binary_utils from "./services/utils/binary";
|
||||
export * as utils from "./services/utils/index";
|
||||
export * from "./services/build";
|
||||
export { default as date_utils } from "./services/utils/date";
|
||||
export { default as events } from "./services/events";
|
||||
export { default as blob } from "./services/blob";
|
||||
export { default as options } from "./services/options";
|
||||
export { default as options_init } from "./services/options_init";
|
||||
export { default as app_info } from "./services/app_info";
|
||||
export { default as keyboard_actions } from "./services/keyboard_actions";
|
||||
export { getContext, type ExecutionContext } from "./services/context";
|
||||
export * from "./errors";
|
||||
export type { CryptoProvider } from "./services/encryption/crypto";
|
||||
|
||||
17
packages/trilium-core/src/services/app_info.ts
Normal file
17
packages/trilium-core/src/services/app_info.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import build from "./build.js";
|
||||
import packageJson from "../../package.json" with { type: "json" };
|
||||
import { AppInfo } from "@triliumnext/commons";
|
||||
|
||||
const APP_DB_VERSION = 233;
|
||||
const SYNC_VERSION = 36;
|
||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
||||
|
||||
export default {
|
||||
appVersion: packageJson.version,
|
||||
dbVersion: APP_DB_VERSION,
|
||||
syncVersion: SYNC_VERSION,
|
||||
buildDate: build.buildDate,
|
||||
buildRevision: build.buildRevision,
|
||||
clipperProtocolVersion: CLIPPER_PROTOCOL_VERSION,
|
||||
utcDateTime: new Date().toISOString()
|
||||
} satisfies AppInfo;
|
||||
882
packages/trilium-core/src/services/keyboard_actions.ts
Normal file
882
packages/trilium-core/src/services/keyboard_actions.ts
Normal file
@ -0,0 +1,882 @@
|
||||
"use strict";
|
||||
|
||||
import optionService from "./options.js";
|
||||
import log from "./log.js";
|
||||
import { isElectron, isMac } from "./utils.js";
|
||||
import type { ActionKeyboardShortcut, KeyboardShortcut } from "@triliumnext/commons";
|
||||
import { t } from "i18next";
|
||||
|
||||
function getDefaultKeyboardActions() {
|
||||
if (!t("keyboard_actions.note-navigation")) {
|
||||
throw new Error("Keyboard actions loaded before translations.");
|
||||
}
|
||||
|
||||
const DEFAULT_KEYBOARD_ACTIONS: KeyboardShortcut[] = [
|
||||
{
|
||||
separator: t("keyboard_actions.note-navigation")
|
||||
},
|
||||
{
|
||||
actionName: "backInNoteHistory",
|
||||
friendlyName: t("keyboard_action_names.back-in-note-history"),
|
||||
iconClass: "bx bxs-chevron-left",
|
||||
// Mac has a different history navigation shortcuts - https://github.com/zadam/trilium/issues/376
|
||||
defaultShortcuts: isMac ? ["CommandOrControl+["] : ["Alt+Left"],
|
||||
description: t("keyboard_actions.back-in-note-history"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "forwardInNoteHistory",
|
||||
friendlyName: t("keyboard_action_names.forward-in-note-history"),
|
||||
iconClass: "bx bxs-chevron-right",
|
||||
// Mac has a different history navigation shortcuts - https://github.com/zadam/trilium/issues/376
|
||||
defaultShortcuts: isMac ? ["CommandOrControl+]"] : ["Alt+Right"],
|
||||
description: t("keyboard_actions.forward-in-note-history"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "jumpToNote",
|
||||
friendlyName: t("keyboard_action_names.jump-to-note"),
|
||||
defaultShortcuts: ["CommandOrControl+J"],
|
||||
description: t("keyboard_actions.open-jump-to-note-dialog"),
|
||||
scope: "window",
|
||||
ignoreFromCommandPalette: true
|
||||
},
|
||||
{
|
||||
actionName: "openTodayNote",
|
||||
friendlyName: t("hidden-subtree.open-today-journal-note-title"),
|
||||
iconClass: "bx bx-calendar",
|
||||
defaultShortcuts: [],
|
||||
description: t("hidden-subtree.open-today-journal-note-title"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "commandPalette",
|
||||
friendlyName: t("keyboard_action_names.command-palette"),
|
||||
defaultShortcuts: ["CommandOrControl+Shift+J"],
|
||||
description: t("keyboard_actions.open-command-palette"),
|
||||
scope: "window",
|
||||
ignoreFromCommandPalette: true
|
||||
},
|
||||
{
|
||||
actionName: "scrollToActiveNote",
|
||||
friendlyName: t("keyboard_action_names.scroll-to-active-note"),
|
||||
defaultShortcuts: ["CommandOrControl+."],
|
||||
iconClass: "bx bx-current-location",
|
||||
description: t("keyboard_actions.scroll-to-active-note"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "quickSearch",
|
||||
friendlyName: t("keyboard_action_names.quick-search"),
|
||||
iconClass: "bx bx-search",
|
||||
defaultShortcuts: ["CommandOrControl+S"],
|
||||
description: t("keyboard_actions.quick-search"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "searchInSubtree",
|
||||
friendlyName: t("keyboard_action_names.search-in-subtree"),
|
||||
defaultShortcuts: ["CommandOrControl+Shift+S"],
|
||||
iconClass: "bx bx-search-alt",
|
||||
description: t("keyboard_actions.search-in-subtree"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "expandSubtree",
|
||||
friendlyName: t("keyboard_action_names.expand-subtree"),
|
||||
defaultShortcuts: [],
|
||||
iconClass: "bx bx-layer-plus",
|
||||
description: t("keyboard_actions.expand-subtree"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "collapseTree",
|
||||
friendlyName: t("keyboard_action_names.collapse-tree"),
|
||||
defaultShortcuts: ["Alt+C"],
|
||||
iconClass: "bx bx-layer-minus",
|
||||
description: t("keyboard_actions.collapse-tree"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "collapseSubtree",
|
||||
friendlyName: t("keyboard_action_names.collapse-subtree"),
|
||||
iconClass: "bx bxs-layer-minus",
|
||||
defaultShortcuts: ["Alt+-"],
|
||||
description: t("keyboard_actions.collapse-subtree"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "sortChildNotes",
|
||||
friendlyName: t("keyboard_action_names.sort-child-notes"),
|
||||
iconClass: "bx bx-sort-down",
|
||||
defaultShortcuts: ["Alt+S"],
|
||||
description: t("keyboard_actions.sort-child-notes"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.creating-and-moving-notes")
|
||||
},
|
||||
{
|
||||
actionName: "createNoteAfter",
|
||||
friendlyName: t("keyboard_action_names.create-note-after"),
|
||||
iconClass: "bx bx-plus",
|
||||
defaultShortcuts: ["CommandOrControl+O"],
|
||||
description: t("keyboard_actions.create-note-after"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "createNoteInto",
|
||||
friendlyName: t("keyboard_action_names.create-note-into"),
|
||||
iconClass: "bx bx-plus",
|
||||
defaultShortcuts: ["CommandOrControl+P"],
|
||||
description: t("keyboard_actions.create-note-into"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "createNoteIntoInbox",
|
||||
friendlyName: t("keyboard_action_names.create-note-into-inbox"),
|
||||
iconClass: "bx bxs-inbox",
|
||||
defaultShortcuts: ["global:CommandOrControl+Alt+P"],
|
||||
description: t("keyboard_actions.create-note-into-inbox"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "deleteNotes",
|
||||
friendlyName: t("keyboard_action_names.delete-notes"),
|
||||
iconClass: "bx bx-trash",
|
||||
defaultShortcuts: ["Delete"],
|
||||
description: t("keyboard_actions.delete-note"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "moveNoteUp",
|
||||
friendlyName: t("keyboard_action_names.move-note-up"),
|
||||
iconClass: "bx bx-up-arrow-alt",
|
||||
defaultShortcuts: isMac ? ["Alt+Up"] : ["CommandOrControl+Up"],
|
||||
description: t("keyboard_actions.move-note-up"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "moveNoteDown",
|
||||
friendlyName: t("keyboard_action_names.move-note-down"),
|
||||
iconClass: "bx bx-down-arrow-alt",
|
||||
defaultShortcuts: isMac ? ["Alt+Down"] : ["CommandOrControl+Down"],
|
||||
description: t("keyboard_actions.move-note-down"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "moveNoteUpInHierarchy",
|
||||
friendlyName: t("keyboard_action_names.move-note-up-in-hierarchy"),
|
||||
iconClass: "bx bx-arrow-from-bottom",
|
||||
defaultShortcuts: isMac ? ["Alt+Left"] : ["CommandOrControl+Left"],
|
||||
description: t("keyboard_actions.move-note-up-in-hierarchy"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "moveNoteDownInHierarchy",
|
||||
friendlyName: t("keyboard_action_names.move-note-down-in-hierarchy"),
|
||||
iconClass: "bx bx-arrow-from-top",
|
||||
defaultShortcuts: isMac ? ["Alt+Right"] : ["CommandOrControl+Right"],
|
||||
description: t("keyboard_actions.move-note-down-in-hierarchy"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "editNoteTitle",
|
||||
friendlyName: t("keyboard_action_names.edit-note-title"),
|
||||
iconClass: "bx bx-rename",
|
||||
defaultShortcuts: ["Enter"],
|
||||
description: t("keyboard_actions.edit-note-title"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "editBranchPrefix",
|
||||
friendlyName: t("keyboard_action_names.edit-branch-prefix"),
|
||||
iconClass: "bx bx-rename",
|
||||
defaultShortcuts: ["F2"],
|
||||
description: t("keyboard_actions.edit-branch-prefix"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "cloneNotesTo",
|
||||
friendlyName: t("keyboard_action_names.clone-notes-to"),
|
||||
iconClass: "bx bx-duplicate",
|
||||
defaultShortcuts: ["CommandOrControl+Shift+C"],
|
||||
description: t("keyboard_actions.clone-notes-to"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "moveNotesTo",
|
||||
friendlyName: t("keyboard_action_names.move-notes-to"),
|
||||
iconClass: "bx bx-transfer",
|
||||
defaultShortcuts: ["CommandOrControl+Shift+X"],
|
||||
description: t("keyboard_actions.move-notes-to"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.note-clipboard")
|
||||
},
|
||||
|
||||
{
|
||||
actionName: "copyNotesToClipboard",
|
||||
friendlyName: t("keyboard_action_names.copy-notes-to-clipboard"),
|
||||
iconClass: "bx bx-copy",
|
||||
defaultShortcuts: ["CommandOrControl+C"],
|
||||
description: t("keyboard_actions.copy-notes-to-clipboard"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "pasteNotesFromClipboard",
|
||||
friendlyName: t("keyboard_action_names.paste-notes-from-clipboard"),
|
||||
iconClass: "bx bx-paste",
|
||||
defaultShortcuts: ["CommandOrControl+V"],
|
||||
description: t("keyboard_actions.paste-notes-from-clipboard"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "cutNotesToClipboard",
|
||||
friendlyName: t("keyboard_action_names.cut-notes-to-clipboard"),
|
||||
iconClass: "bx bx-cut",
|
||||
defaultShortcuts: ["CommandOrControl+X"],
|
||||
description: t("keyboard_actions.cut-notes-to-clipboard"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "selectAllNotesInParent",
|
||||
friendlyName: t("keyboard_action_names.select-all-notes-in-parent"),
|
||||
iconClass: "bx bx-select-multiple",
|
||||
defaultShortcuts: ["CommandOrControl+A"],
|
||||
description: t("keyboard_actions.select-all-notes-in-parent"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
{
|
||||
actionName: "addNoteAboveToSelection",
|
||||
friendlyName: t("keyboard_action_names.add-note-above-to-selection"),
|
||||
defaultShortcuts: ["Shift+Up"],
|
||||
description: t("keyboard_actions.add-note-above-to-the-selection"),
|
||||
scope: "note-tree",
|
||||
ignoreFromCommandPalette: true
|
||||
},
|
||||
{
|
||||
actionName: "addNoteBelowToSelection",
|
||||
friendlyName: t("keyboard_action_names.add-note-below-to-selection"),
|
||||
defaultShortcuts: ["Shift+Down"],
|
||||
description: t("keyboard_actions.add-note-below-to-selection"),
|
||||
scope: "note-tree",
|
||||
ignoreFromCommandPalette: true
|
||||
},
|
||||
{
|
||||
actionName: "duplicateSubtree",
|
||||
friendlyName: t("keyboard_action_names.duplicate-subtree"),
|
||||
iconClass: "bx bx-outline",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.duplicate-subtree"),
|
||||
scope: "note-tree"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.tabs-and-windows")
|
||||
},
|
||||
{
|
||||
actionName: "openNewTab",
|
||||
friendlyName: t("keyboard_action_names.open-new-tab"),
|
||||
iconClass: "bx bx-plus",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+T"] : [],
|
||||
description: t("keyboard_actions.open-new-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "closeActiveTab",
|
||||
friendlyName: t("keyboard_action_names.close-active-tab"),
|
||||
iconClass: "bx bx-minus",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+W"] : [],
|
||||
description: t("keyboard_actions.close-active-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "reopenLastTab",
|
||||
friendlyName: t("keyboard_action_names.reopen-last-tab"),
|
||||
iconClass: "bx bx-undo",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+Shift+T"] : [],
|
||||
isElectronOnly: true,
|
||||
description: t("keyboard_actions.reopen-last-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "activateNextTab",
|
||||
friendlyName: t("keyboard_action_names.activate-next-tab"),
|
||||
iconClass: "bx bx-skip-next",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+Tab", "CommandOrControl+PageDown"] : [],
|
||||
description: t("keyboard_actions.activate-next-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "activatePreviousTab",
|
||||
friendlyName: t("keyboard_action_names.activate-previous-tab"),
|
||||
iconClass: "bx bx-skip-previous",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+Shift+Tab", "CommandOrControl+PageUp"] : [],
|
||||
description: t("keyboard_actions.activate-previous-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "openNewWindow",
|
||||
friendlyName: t("keyboard_action_names.open-new-window"),
|
||||
iconClass: "bx bx-window-open",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.open-new-window"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleTray",
|
||||
friendlyName: t("keyboard_action_names.toggle-system-tray-icon"),
|
||||
iconClass: "bx bx-show",
|
||||
defaultShortcuts: [],
|
||||
isElectronOnly: true,
|
||||
description: t("keyboard_actions.toggle-tray"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleZenMode",
|
||||
friendlyName: t("keyboard_action_names.toggle-zen-mode"),
|
||||
iconClass: "bx bxs-yin-yang",
|
||||
defaultShortcuts: ["F9"],
|
||||
description: t("keyboard_actions.toggle-zen-mode"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "firstTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-first-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+1"],
|
||||
description: t("keyboard_actions.first-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "secondTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-second-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+2"],
|
||||
description: t("keyboard_actions.second-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "thirdTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-third-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+3"],
|
||||
description: t("keyboard_actions.third-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "fourthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-fourth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+4"],
|
||||
description: t("keyboard_actions.fourth-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "fifthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-fifth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+5"],
|
||||
description: t("keyboard_actions.fifth-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "sixthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-sixth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+6"],
|
||||
description: t("keyboard_actions.sixth-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "seventhTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-seventh-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+7"],
|
||||
description: t("keyboard_actions.seventh-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "eigthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-eighth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+8"],
|
||||
description: t("keyboard_actions.eight-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "ninthTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-ninth-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+9"],
|
||||
description: t("keyboard_actions.ninth-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "lastTab",
|
||||
friendlyName: t("keyboard_action_names.switch-to-last-tab"),
|
||||
iconClass: "bx bx-rectangle",
|
||||
defaultShortcuts: ["CommandOrControl+0"],
|
||||
description: t("keyboard_actions.last-tab"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.dialogs")
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-note-source"),
|
||||
actionName: "showNoteSource",
|
||||
iconClass: "bx bx-code",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-note-source"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-options"),
|
||||
actionName: "showOptions",
|
||||
iconClass: "bx bx-cog",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-options"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-revisions"),
|
||||
actionName: "showRevisions",
|
||||
iconClass: "bx bx-history",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-revisions"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-recent-changes"),
|
||||
actionName: "showRecentChanges",
|
||||
iconClass: "bx bx-history",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-recent-changes"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-sql-console"),
|
||||
actionName: "showSQLConsole",
|
||||
iconClass: "bx bx-data",
|
||||
defaultShortcuts: ["Alt+O"],
|
||||
description: t("keyboard_actions.show-sql-console"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-backend-log"),
|
||||
actionName: "showBackendLog",
|
||||
iconClass: "bx bx-detail",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.show-backend-log"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-help"),
|
||||
actionName: "showHelp",
|
||||
iconClass: "bx bx-help-circle",
|
||||
defaultShortcuts: ["F1"],
|
||||
description: t("keyboard_actions.show-help"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.show-cheatsheet"),
|
||||
actionName: "showCheatsheet",
|
||||
iconClass: "bx bxs-keyboard",
|
||||
defaultShortcuts: ["Shift+F1"],
|
||||
description: t("keyboard_actions.show-cheatsheet"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.text-note-operations")
|
||||
},
|
||||
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.add-link-to-text"),
|
||||
actionName: "addLinkToText",
|
||||
iconClass: "bx bx-link",
|
||||
defaultShortcuts: ["CommandOrControl+L"],
|
||||
description: t("keyboard_actions.add-link-to-text"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.follow-link-under-cursor"),
|
||||
actionName: "followLinkUnderCursor",
|
||||
iconClass: "bx bx-link-external",
|
||||
defaultShortcuts: ["CommandOrControl+Enter"],
|
||||
description: t("keyboard_actions.follow-link-under-cursor"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.insert-date-and-time-to-text"),
|
||||
actionName: "insertDateTimeToText",
|
||||
iconClass: "bx bx-calendar-event",
|
||||
defaultShortcuts: ["Alt+T"],
|
||||
description: t("keyboard_actions.insert-date-and-time-to-text"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.paste-markdown-into-text"),
|
||||
actionName: "pasteMarkdownIntoText",
|
||||
iconClass: "bx bxl-markdown",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.paste-markdown-into-text"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.cut-into-note"),
|
||||
actionName: "cutIntoNote",
|
||||
iconClass: "bx bx-cut",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.cut-into-note"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.add-include-note-to-text"),
|
||||
actionName: "addIncludeNoteToText",
|
||||
iconClass: "bx bx-note",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.add-include-note-to-text"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.edit-read-only-note"),
|
||||
actionName: "editReadOnlyNote",
|
||||
iconClass: "bx bx-edit-alt",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.edit-readonly-note"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.attributes-labels-and-relations")
|
||||
},
|
||||
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.add-new-label"),
|
||||
actionName: "addNewLabel",
|
||||
iconClass: "bx bx-hash",
|
||||
defaultShortcuts: ["Alt+L"],
|
||||
description: t("keyboard_actions.add-new-label"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.add-new-relation"),
|
||||
actionName: "addNewRelation",
|
||||
iconClass: "bx bx-transfer",
|
||||
defaultShortcuts: ["Alt+R"],
|
||||
description: t("keyboard_actions.create-new-relation"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.ribbon-tabs")
|
||||
},
|
||||
|
||||
{
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-classic-editor"),
|
||||
actionName: "toggleRibbonTabClassicEditor",
|
||||
iconClass: "bx bx-text",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-classic-editor-toolbar"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabBasicProperties",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-basic-properties"),
|
||||
iconClass: "bx bx-slider",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-basic-properties"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabBookProperties",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-book-properties"),
|
||||
iconClass: "bx bx-book",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-book-properties"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabFileProperties",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-file-properties"),
|
||||
iconClass: "bx bx-file",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-file-properties"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabImageProperties",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-image-properties"),
|
||||
iconClass: "bx bx-image",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-image-properties"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabOwnedAttributes",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-owned-attributes"),
|
||||
iconClass: "bx bx-list-check",
|
||||
defaultShortcuts: ["Alt+A"],
|
||||
description: t("keyboard_actions.toggle-owned-attributes"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabInheritedAttributes",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-inherited-attributes"),
|
||||
iconClass: "bx bx-list-plus",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-inherited-attributes"),
|
||||
scope: "window"
|
||||
},
|
||||
// TODO: Remove or change since promoted attributes have been changed.
|
||||
{
|
||||
actionName: "toggleRibbonTabPromotedAttributes",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-promoted-attributes"),
|
||||
iconClass: "bx bx-star",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-promoted-attributes"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabNoteMap",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-note-map"),
|
||||
iconClass: "bx bxs-network-chart",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-link-map"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabNoteInfo",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-note-info"),
|
||||
iconClass: "bx bx-info-circle",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-note-info"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabNotePaths",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-note-paths"),
|
||||
iconClass: "bx bx-collection",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-note-paths"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabSimilarNotes",
|
||||
friendlyName: t("keyboard_action_names.toggle-ribbon-tab-similar-notes"),
|
||||
iconClass: "bx bx-bar-chart",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-similar-notes"),
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: t("keyboard_actions.other")
|
||||
},
|
||||
|
||||
{
|
||||
actionName: "toggleRightPane",
|
||||
friendlyName: t("keyboard_action_names.toggle-right-pane"),
|
||||
iconClass: "bx bx-dock-right",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-right-pane"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "printActiveNote",
|
||||
friendlyName: t("keyboard_action_names.print-active-note"),
|
||||
iconClass: "bx bx-printer",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.print-active-note"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "exportAsPdf",
|
||||
friendlyName: t("keyboard_action_names.export-active-note-as-pdf"),
|
||||
iconClass: "bx bxs-file-pdf",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.export-as-pdf"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "openNoteExternally",
|
||||
friendlyName: t("keyboard_action_names.open-note-externally"),
|
||||
iconClass: "bx bx-file-find",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.open-note-externally"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "renderActiveNote",
|
||||
friendlyName: t("keyboard_action_names.render-active-note"),
|
||||
iconClass: "bx bx-refresh",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.render-active-note"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "runActiveNote",
|
||||
friendlyName: t("keyboard_action_names.run-active-note"),
|
||||
iconClass: "bx bx-play",
|
||||
defaultShortcuts: ["CommandOrControl+Enter"],
|
||||
description: t("keyboard_actions.run-active-note"),
|
||||
scope: "code-detail"
|
||||
},
|
||||
{
|
||||
actionName: "toggleNoteHoisting",
|
||||
friendlyName: t("keyboard_action_names.toggle-note-hoisting"),
|
||||
iconClass: "bx bx-chevrons-up",
|
||||
defaultShortcuts: ["Alt+H"],
|
||||
description: t("keyboard_actions.toggle-note-hoisting"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "unhoist",
|
||||
friendlyName: t("keyboard_action_names.unhoist-note"),
|
||||
iconClass: "bx bx-door-open",
|
||||
defaultShortcuts: ["Alt+U"],
|
||||
description: t("keyboard_actions.unhoist"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "reloadFrontendApp",
|
||||
friendlyName: t("keyboard_action_names.reload-frontend-app"),
|
||||
iconClass: "bx bx-refresh",
|
||||
defaultShortcuts: ["F5", "CommandOrControl+R"],
|
||||
description: t("keyboard_actions.reload-frontend-app"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "openDevTools",
|
||||
friendlyName: t("keyboard_action_names.open-developer-tools"),
|
||||
iconClass: "bx bx-bug-alt",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+Shift+I"] : [],
|
||||
isElectronOnly: true,
|
||||
description: t("keyboard_actions.open-dev-tools"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "findInText",
|
||||
friendlyName: t("keyboard_action_names.find-in-text"),
|
||||
iconClass: "bx bx-search",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+F"] : [],
|
||||
description: t("keyboard_actions.find-in-text"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleLeftPane",
|
||||
friendlyName: t("keyboard_action_names.toggle-left-pane"),
|
||||
iconClass: "bx bx-sidebar",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.toggle-left-note-tree-panel"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleFullscreen",
|
||||
friendlyName: t("keyboard_action_names.toggle-full-screen"),
|
||||
iconClass: "bx bx-fullscreen",
|
||||
defaultShortcuts: ["F11"],
|
||||
description: t("keyboard_actions.toggle-full-screen"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "zoomOut",
|
||||
friendlyName: t("keyboard_action_names.zoom-out"),
|
||||
iconClass: "bx bx-zoom-out",
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+-"] : [],
|
||||
isElectronOnly: true,
|
||||
description: t("keyboard_actions.zoom-out"),
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "zoomIn",
|
||||
friendlyName: t("keyboard_action_names.zoom-in"),
|
||||
iconClass: "bx bx-zoom-in",
|
||||
description: t("keyboard_actions.zoom-in"),
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+="] : [],
|
||||
isElectronOnly: true,
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "zoomReset",
|
||||
friendlyName: t("keyboard_action_names.reset-zoom-level"),
|
||||
iconClass: "bx bx-search-alt",
|
||||
description: t("keyboard_actions.reset-zoom-level"),
|
||||
defaultShortcuts: isElectron ? ["CommandOrControl+0"] : [],
|
||||
isElectronOnly: true,
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "copyWithoutFormatting",
|
||||
friendlyName: t("keyboard_action_names.copy-without-formatting"),
|
||||
iconClass: "bx bx-copy-alt",
|
||||
defaultShortcuts: ["CommandOrControl+Alt+C"],
|
||||
description: t("keyboard_actions.copy-without-formatting"),
|
||||
scope: "text-detail"
|
||||
},
|
||||
{
|
||||
actionName: "forceSaveRevision",
|
||||
friendlyName: t("keyboard_action_names.force-save-revision"),
|
||||
iconClass: "bx bx-save",
|
||||
defaultShortcuts: [],
|
||||
description: t("keyboard_actions.force-save-revision"),
|
||||
scope: "window"
|
||||
}
|
||||
];
|
||||
|
||||
/*
|
||||
* Apply macOS-specific tweaks.
|
||||
*/
|
||||
const platformModifier = isMac ? "Meta" : "Ctrl";
|
||||
|
||||
for (const action of DEFAULT_KEYBOARD_ACTIONS) {
|
||||
if ("defaultShortcuts" in action && action.defaultShortcuts) {
|
||||
action.defaultShortcuts = action.defaultShortcuts.map((shortcut) => shortcut.replace("CommandOrControl", platformModifier));
|
||||
}
|
||||
}
|
||||
|
||||
return DEFAULT_KEYBOARD_ACTIONS;
|
||||
}
|
||||
|
||||
function getKeyboardActions() {
|
||||
const actions: KeyboardShortcut[] = JSON.parse(JSON.stringify(getDefaultKeyboardActions()));
|
||||
|
||||
for (const action of actions) {
|
||||
if ("effectiveShortcuts" in action && action.effectiveShortcuts) {
|
||||
action.effectiveShortcuts = action.defaultShortcuts ? action.defaultShortcuts.slice() : [];
|
||||
}
|
||||
}
|
||||
|
||||
for (const option of optionService.getOptions()) {
|
||||
if (option.name.startsWith("keyboardShortcuts")) {
|
||||
let actionName = option.name.substring(17);
|
||||
actionName = actionName.charAt(0).toLowerCase() + actionName.slice(1);
|
||||
|
||||
const action = actions.find((ea) => "actionName" in ea && ea.actionName === actionName) as ActionKeyboardShortcut;
|
||||
|
||||
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} found in database, but not in action definition.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
export default {
|
||||
getDefaultKeyboardActions,
|
||||
getKeyboardActions
|
||||
};
|
||||
146
packages/trilium-core/src/services/options.ts
Normal file
146
packages/trilium-core/src/services/options.ts
Normal file
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @module
|
||||
*
|
||||
* Options are key-value pairs that are used to store information such as user preferences (for example
|
||||
* the current theme, sync server information), but also information about the state of the application.
|
||||
*
|
||||
* Although options internally are represented as strings, their value can be interpreted as a number or
|
||||
* boolean by calling the appropriate methods from this service (e.g. {@link #getOptionInt}).\
|
||||
*
|
||||
* Generally options are shared across multiple instances of the application via the sync mechanism,
|
||||
* however it is possible to have options that are local to an instance. For example, the user can select
|
||||
* a theme on a device and it will not affect other devices.
|
||||
*/
|
||||
|
||||
import becca from "../becca/becca.js";
|
||||
import BOption from "../becca/entities/boption.js";
|
||||
import type { OptionRow } from "@triliumnext/commons";
|
||||
import type { FilterOptionsByType, OptionDefinitions, OptionMap, OptionNames } from "@triliumnext/commons";
|
||||
import { getSql } from "./sql/index.js";
|
||||
|
||||
function getOptionOrNull(name: OptionNames): string | null {
|
||||
let option;
|
||||
|
||||
if (becca.loaded) {
|
||||
option = becca.getOption(name);
|
||||
} else {
|
||||
// e.g. in initial sync becca is not loaded because DB is not initialized
|
||||
try {
|
||||
option = getSql().getRow<OptionRow>("SELECT * FROM options WHERE name = ?", [name]);
|
||||
} catch (e: unknown) {
|
||||
// DB is not initialized.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return option ? option.value : null;
|
||||
}
|
||||
|
||||
function getOption(name: OptionNames) {
|
||||
const val = getOptionOrNull(name);
|
||||
|
||||
if (val === null) {
|
||||
throw new Error(`Option '${name}' doesn't exist`);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function getOptionInt(name: FilterOptionsByType<number>, defaultValue?: number): number {
|
||||
const val = getOption(name);
|
||||
|
||||
const intVal = parseInt(val);
|
||||
|
||||
if (isNaN(intVal)) {
|
||||
if (defaultValue === undefined) {
|
||||
throw new Error(`Could not parse '${val}' into integer for option '${name}'`);
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return intVal;
|
||||
}
|
||||
|
||||
function getOptionBool(name: FilterOptionsByType<boolean>): boolean {
|
||||
const val = getOption(name);
|
||||
|
||||
if (typeof val !== "string" || !["true", "false"].includes(val)) {
|
||||
throw new Error(`Could not parse '${val}' into boolean for option '${name}'`);
|
||||
}
|
||||
|
||||
return val === "true";
|
||||
}
|
||||
|
||||
function setOption<T extends OptionNames>(name: T, value: string | OptionDefinitions[T]) {
|
||||
const option = becca.getOption(name);
|
||||
|
||||
if (option) {
|
||||
option.value = value as string;
|
||||
|
||||
option.save();
|
||||
} else {
|
||||
createOption(name, value, false);
|
||||
}
|
||||
|
||||
// Clear current AI provider when AI-related options change
|
||||
const aiOptions = [
|
||||
'aiSelectedProvider', 'openaiApiKey', 'openaiBaseUrl', 'openaiDefaultModel',
|
||||
'anthropicApiKey', 'anthropicBaseUrl', 'anthropicDefaultModel',
|
||||
'ollamaBaseUrl', 'ollamaDefaultModel'
|
||||
];
|
||||
|
||||
// TODO: Disabled AI integration.
|
||||
// if (aiOptions.includes(name)) {
|
||||
// // Import dynamically to avoid circular dependencies
|
||||
// setImmediate(async () => {
|
||||
// try {
|
||||
// const aiServiceManager = (await import('./llm/ai_service_manager.js')).default;
|
||||
// aiServiceManager.getInstance().clearCurrentProvider();
|
||||
// console.log(`Cleared AI provider after ${name} option changed`);
|
||||
// } catch (error) {
|
||||
// console.log(`Could not clear AI provider: ${error}`);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new option in the database, with the given name, value and whether it should be synced.
|
||||
*
|
||||
* @param name the name of the option to be created.
|
||||
* @param value the value of the option, as a string. It can then be interpreted as other types such as a number of boolean.
|
||||
* @param isSynced `true` if the value should be synced across multiple instances (e.g. locale) or `false` if it should be local-only (e.g. theme).
|
||||
*/
|
||||
function createOption<T extends OptionNames>(name: T, value: string | OptionDefinitions[T], isSynced: boolean) {
|
||||
new BOption({
|
||||
name: name,
|
||||
value: value as string,
|
||||
isSynced: isSynced
|
||||
}).save();
|
||||
}
|
||||
|
||||
function getOptions() {
|
||||
return Object.values(becca.options);
|
||||
}
|
||||
|
||||
function getOptionMap() {
|
||||
const map: Record<string, string> = {};
|
||||
|
||||
for (const option of Object.values(becca.options)) {
|
||||
map[option.name] = option.value;
|
||||
}
|
||||
|
||||
return map as OptionMap;
|
||||
}
|
||||
|
||||
export default {
|
||||
getOption,
|
||||
getOptionInt,
|
||||
getOptionBool,
|
||||
setOption,
|
||||
createOption,
|
||||
getOptions,
|
||||
getOptionMap,
|
||||
getOptionOrNull
|
||||
};
|
||||
280
packages/trilium-core/src/services/options_init.ts
Normal file
280
packages/trilium-core/src/services/options_init.ts
Normal file
@ -0,0 +1,280 @@
|
||||
import { type KeyboardShortcutWithRequiredActionName, type OptionMap, type OptionNames, SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/commons";
|
||||
|
||||
import appInfo from "./app_info.js";
|
||||
import dateUtils from "./utils/date.js";
|
||||
import keyboardActions from "./keyboard_actions.js";
|
||||
import log from "./log.js";
|
||||
import optionService from "./options.js";
|
||||
import { isWindows, randomSecureToken } from "./utils.js";
|
||||
|
||||
function initDocumentOptions() {
|
||||
optionService.createOption("documentId", randomSecureToken(16), false);
|
||||
optionService.createOption("documentSecret", randomSecureToken(16), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains additional options to be initialized for a new database, containing the information entered by the user.
|
||||
*/
|
||||
interface NotSyncedOpts {
|
||||
syncServerHost?: string;
|
||||
syncProxy?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a correspondence between an option and its default value, to be initialized when the database is missing that particular option (after a migration from an older version, or when creating a new database).
|
||||
*/
|
||||
interface DefaultOption {
|
||||
name: OptionNames;
|
||||
/**
|
||||
* The value to initialize the option with, if the option is not already present in the database.
|
||||
*
|
||||
* If a function is passed Gin instead, the function is called if the option does not exist (with access to the current options) and the return value is used instead. Useful to migrate a new option with a value depending on some other option that might be initialized.
|
||||
*/
|
||||
value: string | ((options: OptionMap) => string);
|
||||
isSynced: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the default options for new databases only.
|
||||
*
|
||||
* @param initialized `true` if the database has been fully initialized (i.e. a new database was created), or `false` if the database is created for sync.
|
||||
* @param opts additional options to be initialized, for example the sync configuration.
|
||||
*/
|
||||
async function initNotSyncedOptions(initialized: boolean, opts: NotSyncedOpts = {}) {
|
||||
optionService.createOption(
|
||||
"openNoteContexts",
|
||||
JSON.stringify([
|
||||
{
|
||||
notePath: "root",
|
||||
active: true
|
||||
}
|
||||
]),
|
||||
false
|
||||
);
|
||||
|
||||
optionService.createOption("lastDailyBackupDate", dateUtils.utcNowDateTime(), false);
|
||||
optionService.createOption("lastWeeklyBackupDate", dateUtils.utcNowDateTime(), false);
|
||||
optionService.createOption("lastMonthlyBackupDate", dateUtils.utcNowDateTime(), false);
|
||||
optionService.createOption("dbVersion", appInfo.dbVersion.toString(), false);
|
||||
|
||||
optionService.createOption("initialized", initialized ? "true" : "false", false);
|
||||
|
||||
optionService.createOption("lastSyncedPull", "0", false);
|
||||
optionService.createOption("lastSyncedPush", "0", false);
|
||||
|
||||
optionService.createOption("theme", "next", false);
|
||||
optionService.createOption("textNoteEditorType", "ckeditor-classic", true);
|
||||
|
||||
optionService.createOption("syncServerHost", opts.syncServerHost || "", false);
|
||||
optionService.createOption("syncServerTimeout", "120000", false);
|
||||
optionService.createOption("syncProxy", opts.syncProxy || "", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains all the default options that must be initialized on new and existing databases (at startup). The value can also be determined based on other options, provided they have already been initialized.
|
||||
*/
|
||||
const defaultOptions: DefaultOption[] = [
|
||||
{ name: "revisionSnapshotTimeInterval", value: "600", isSynced: true },
|
||||
{ name: "revisionSnapshotTimeIntervalTimeScale", value: "60", isSynced: true }, // default to Minutes
|
||||
{ name: "revisionSnapshotNumberLimit", value: "-1", isSynced: true },
|
||||
{ name: "protectedSessionTimeout", value: "600", isSynced: true },
|
||||
{ name: "protectedSessionTimeoutTimeScale", value: "60", isSynced: true },
|
||||
{ name: "zoomFactor", value: isWindows ? "0.9" : "1.0", isSynced: false },
|
||||
{ name: "overrideThemeFonts", value: "false", isSynced: false },
|
||||
{ name: "mainFontFamily", value: "theme", isSynced: false },
|
||||
{ name: "mainFontSize", value: "100", isSynced: false },
|
||||
{ name: "treeFontFamily", value: "theme", isSynced: false },
|
||||
{ name: "treeFontSize", value: "100", isSynced: false },
|
||||
{ name: "detailFontFamily", value: "theme", isSynced: false },
|
||||
{ name: "detailFontSize", value: "110", isSynced: false },
|
||||
{ name: "monospaceFontFamily", value: "theme", isSynced: false },
|
||||
{ name: "monospaceFontSize", value: "110", isSynced: false },
|
||||
{ name: "spellCheckEnabled", value: "true", isSynced: false },
|
||||
{ name: "spellCheckLanguageCode", value: "en-US", isSynced: false },
|
||||
{ name: "imageMaxWidthHeight", value: "2000", isSynced: true },
|
||||
{ name: "imageJpegQuality", value: "75", isSynced: true },
|
||||
{ name: "autoFixConsistencyIssues", value: "true", isSynced: false },
|
||||
{ name: "vimKeymapEnabled", value: "false", isSynced: false },
|
||||
{ name: "codeLineWrapEnabled", value: "true", isSynced: false },
|
||||
{
|
||||
name: "codeNotesMimeTypes",
|
||||
value: '["text/x-csrc","text/x-c++src","text/x-csharp","text/css","text/x-elixir","text/x-go","text/x-groovy","text/x-haskell","text/html","message/http","text/x-java","application/javascript;env=frontend","application/javascript;env=backend","application/json","text/x-kotlin","text/x-markdown","text/x-perl","text/x-php","text/x-python","text/x-ruby",null,"text/x-sql","text/x-sqlite;schema=trilium","text/x-swift","text/xml","text/x-yaml","text/x-sh","application/typescript"]',
|
||||
isSynced: true
|
||||
},
|
||||
{ name: "leftPaneWidth", value: "25", isSynced: false },
|
||||
{ name: "leftPaneVisible", value: "true", isSynced: false },
|
||||
{ name: "rightPaneWidth", value: "25", isSynced: false },
|
||||
{ name: "rightPaneVisible", value: "true", isSynced: false },
|
||||
{ name: "rightPaneCollapsedItems", value: "[]", isSynced: false },
|
||||
{ name: "nativeTitleBarVisible", value: "false", isSynced: false },
|
||||
{ name: "eraseEntitiesAfterTimeInSeconds", value: "604800", isSynced: true }, // default is 7 days
|
||||
{ name: "eraseEntitiesAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day
|
||||
{ name: "hideArchivedNotes_main", value: "false", isSynced: false },
|
||||
{ name: "debugModeEnabled", value: "false", isSynced: false },
|
||||
{ name: "headingStyle", value: "underline", isSynced: true },
|
||||
{ name: "autoCollapseNoteTree", value: "true", isSynced: true },
|
||||
{ name: "autoReadonlySizeText", value: "32000", isSynced: false },
|
||||
{ name: "autoReadonlySizeCode", value: "64000", isSynced: false },
|
||||
{ name: "dailyBackupEnabled", value: "true", isSynced: false },
|
||||
{ name: "weeklyBackupEnabled", value: "true", isSynced: false },
|
||||
{ name: "monthlyBackupEnabled", value: "true", isSynced: false },
|
||||
{ name: "maxContentWidth", value: "1200", isSynced: false },
|
||||
{ name: "centerContent", value: "false", isSynced: false },
|
||||
{ name: "compressImages", value: "true", isSynced: true },
|
||||
{ name: "downloadImagesAutomatically", value: "true", isSynced: true },
|
||||
{ name: "minTocHeadings", value: "5", isSynced: true },
|
||||
{ name: "highlightsList", value: '["underline","color","bgColor"]', isSynced: true },
|
||||
{ name: "checkForUpdates", value: "true", isSynced: true },
|
||||
{ name: "disableTray", value: "false", isSynced: false },
|
||||
{ name: "eraseUnusedAttachmentsAfterSeconds", value: "2592000", isSynced: true }, // default 30 days
|
||||
{ name: "eraseUnusedAttachmentsAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day
|
||||
{ name: "logRetentionDays", value: "90", isSynced: false }, // default 90 days
|
||||
{ name: "customSearchEngineName", value: "DuckDuckGo", isSynced: true },
|
||||
{ name: "customSearchEngineUrl", value: "https://duckduckgo.com/?q={keyword}", isSynced: true },
|
||||
{ name: "editedNotesOpenInRibbon", value: "true", isSynced: true },
|
||||
{ name: "mfaEnabled", value: "false", isSynced: false },
|
||||
{ name: "mfaMethod", value: "totp", isSynced: false },
|
||||
{ name: "encryptedRecoveryCodes", value: "false", isSynced: false },
|
||||
{ name: "userSubjectIdentifierSaved", value: "false", isSynced: false },
|
||||
|
||||
// Appearance
|
||||
{ name: "splitEditorOrientation", value: "horizontal", isSynced: true },
|
||||
{
|
||||
name: "codeNoteTheme",
|
||||
value: (optionsMap) => {
|
||||
switch (optionsMap.theme) {
|
||||
case "light":
|
||||
case "next-light":
|
||||
return "default:vs-code-light";
|
||||
case "dark":
|
||||
case "next-dark":
|
||||
default:
|
||||
return "default:vs-code-dark";
|
||||
}
|
||||
},
|
||||
isSynced: false
|
||||
},
|
||||
{ name: "motionEnabled", value: "true", isSynced: false },
|
||||
{ name: "shadowsEnabled", value: "true", isSynced: false },
|
||||
{ name: "backdropEffectsEnabled", value: "true", isSynced: false },
|
||||
{ name: "smoothScrollEnabled", value: "true", isSynced: false },
|
||||
{ name: "newLayout", value: "true", isSynced: true },
|
||||
|
||||
// Internationalization
|
||||
{ name: "locale", value: "en", isSynced: true },
|
||||
{ name: "formattingLocale", value: "", isSynced: true }, // no value means auto-detect
|
||||
{ name: "firstDayOfWeek", value: "1", isSynced: true },
|
||||
{ name: "firstWeekOfYear", value: "0", isSynced: true },
|
||||
{ name: "minDaysInFirstWeek", value: "4", isSynced: true },
|
||||
{ name: "languages", value: "[]", isSynced: true },
|
||||
|
||||
// Code block configuration
|
||||
{
|
||||
name: "codeBlockTheme",
|
||||
value: (optionsMap) => {
|
||||
if (optionsMap.theme === "light") {
|
||||
return "default:stackoverflow-light";
|
||||
}
|
||||
return "default:stackoverflow-dark";
|
||||
|
||||
},
|
||||
isSynced: false
|
||||
},
|
||||
{ name: "codeBlockWordWrap", value: "false", isSynced: true },
|
||||
|
||||
// Text note configuration
|
||||
{ name: "textNoteEditorType", value: "ckeditor-balloon", isSynced: true },
|
||||
{ name: "textNoteEditorMultilineToolbar", value: "false", isSynced: true },
|
||||
{ name: "textNoteEmojiCompletionEnabled", value: "true", isSynced: true },
|
||||
{ name: "textNoteCompletionEnabled", value: "true", isSynced: true },
|
||||
{ name: "textNoteSlashCommandsEnabled", value: "true", isSynced: true },
|
||||
|
||||
// HTML import configuration
|
||||
{ name: "layoutOrientation", value: "vertical", isSynced: false },
|
||||
{ name: "backgroundEffects", value: "true", isSynced: false },
|
||||
{
|
||||
name: "allowedHtmlTags",
|
||||
value: JSON.stringify(SANITIZER_DEFAULT_ALLOWED_TAGS),
|
||||
isSynced: true
|
||||
},
|
||||
|
||||
// Share settings
|
||||
{ name: "redirectBareDomain", value: "false", isSynced: true },
|
||||
{ name: "showLoginInShareTheme", value: "false", isSynced: true },
|
||||
|
||||
// AI Options
|
||||
{ name: "aiEnabled", value: "false", isSynced: true },
|
||||
{ name: "openaiApiKey", value: "", isSynced: false },
|
||||
{ name: "openaiDefaultModel", value: "", isSynced: true },
|
||||
{ name: "openaiBaseUrl", value: "https://api.openai.com/v1", isSynced: true },
|
||||
{ name: "anthropicApiKey", value: "", isSynced: false },
|
||||
{ name: "anthropicDefaultModel", value: "", isSynced: true },
|
||||
{ name: "voyageApiKey", value: "", isSynced: false },
|
||||
{ name: "anthropicBaseUrl", value: "https://api.anthropic.com/v1", isSynced: true },
|
||||
{ name: "ollamaEnabled", value: "false", isSynced: true },
|
||||
{ name: "ollamaDefaultModel", value: "", isSynced: true },
|
||||
{ name: "ollamaBaseUrl", value: "http://localhost:11434", isSynced: true },
|
||||
{ name: "aiTemperature", value: "0.7", isSynced: true },
|
||||
{ name: "aiSystemPrompt", value: "", isSynced: true },
|
||||
{ name: "aiSelectedProvider", value: "openai", isSynced: true },
|
||||
|
||||
{
|
||||
name: "seenCallToActions",
|
||||
value: JSON.stringify([
|
||||
"new_layout", "background_effects", "next_theme"
|
||||
]),
|
||||
isSynced: true
|
||||
},
|
||||
{ name: "experimentalFeatures", value: "[]", isSynced: true }
|
||||
];
|
||||
|
||||
/**
|
||||
* Initializes the options, by checking which options from {@link #allDefaultOptions()} are missing and registering them. It will also check some environment variables such as safe mode, to make any necessary adjustments.
|
||||
*
|
||||
* This method is called regardless of whether a new database is created, or an existing database is used.
|
||||
*/
|
||||
function initStartupOptions() {
|
||||
const optionsMap = optionService.getOptionMap();
|
||||
|
||||
const allDefaultOptions = defaultOptions.concat(getKeyboardDefaultOptions());
|
||||
|
||||
for (const { name, value, isSynced } of allDefaultOptions) {
|
||||
if (!(name in optionsMap)) {
|
||||
let resolvedValue;
|
||||
if (typeof value === "function") {
|
||||
resolvedValue = value(optionsMap);
|
||||
} else {
|
||||
resolvedValue = value;
|
||||
}
|
||||
|
||||
optionService.createOption(name, resolvedValue, isSynced);
|
||||
log.info(`Created option "${name}" with default value "${resolvedValue}"`);
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.TRILIUM_START_NOTE_ID || process.env.TRILIUM_SAFE_MODE) {
|
||||
optionService.setOption(
|
||||
"openNoteContexts",
|
||||
JSON.stringify([
|
||||
{
|
||||
notePath: process.env.TRILIUM_START_NOTE_ID || "root",
|
||||
active: true
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getKeyboardDefaultOptions() {
|
||||
return (keyboardActions.getDefaultKeyboardActions().filter((ka) => "actionName" in ka) as KeyboardShortcutWithRequiredActionName[]).map((ka) => ({
|
||||
name: `keyboardShortcuts${ka.actionName.charAt(0).toUpperCase()}${ka.actionName.slice(1)}`,
|
||||
value: JSON.stringify(ka.defaultShortcuts),
|
||||
isSynced: false
|
||||
})) as DefaultOption[];
|
||||
}
|
||||
|
||||
export default {
|
||||
initDocumentOptions,
|
||||
initNotSyncedOptions,
|
||||
initStartupOptions
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user