mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
Merge remote-tracking branch 'origin/next58' into next58
This commit is contained in:
commit
0d50cdb0f5
@ -1,24 +1,26 @@
|
||||
import froca from "./froca.js";
|
||||
import bundleService from "./bundle.js";
|
||||
import froca from "../services/froca.js";
|
||||
import bundleService from "../services/bundle.js";
|
||||
import RootCommandExecutor from "./root_command_executor.js";
|
||||
import Entrypoints from "./entrypoints.js";
|
||||
import options from "./options.js";
|
||||
import utils from "./utils.js";
|
||||
import zoomService from "./zoom.js";
|
||||
import options from "../services/options.js";
|
||||
import utils from "../services/utils.js";
|
||||
import zoomComponent from "./zoom.js";
|
||||
import TabManager from "./tab_manager.js";
|
||||
import treeService from "./tree.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import keyboardActionsService from "./keyboard_actions.js";
|
||||
import MobileScreenSwitcherExecutor from "../widgets/mobile_widgets/mobile_screen_switcher.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import Component from "./component.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import MobileScreenSwitcherExecutor from "./mobile_screen_switcher.js";
|
||||
import MainTreeExecutors from "./main_tree_executors.js";
|
||||
import toast from "./toast.js";
|
||||
import toast from "../services/toast.js";
|
||||
import ShortcutComponent from "./shortcut_component.js";
|
||||
|
||||
class AppContext extends Component {
|
||||
constructor(isMainWindow) {
|
||||
super();
|
||||
|
||||
this.isMainWindow = isMainWindow;
|
||||
this.executors = [];
|
||||
// non-widget/layout components needed for the application
|
||||
this.components = [];
|
||||
this.beforeUnloadListeners = [];
|
||||
}
|
||||
|
||||
@ -27,7 +29,9 @@ class AppContext extends Component {
|
||||
}
|
||||
|
||||
async start() {
|
||||
this.showWidgets();
|
||||
this.initComponents();
|
||||
|
||||
this.renderWidgets();
|
||||
|
||||
await Promise.all([froca.initializedPromise, options.initializedPromise]);
|
||||
|
||||
@ -36,7 +40,31 @@ class AppContext extends Component {
|
||||
setTimeout(() => bundleService.executeStartupBundles(), 2000);
|
||||
}
|
||||
|
||||
showWidgets() {
|
||||
initComponents() {
|
||||
this.tabManager = new TabManager();
|
||||
|
||||
this.components = [
|
||||
this.tabManager,
|
||||
new RootCommandExecutor(),
|
||||
new Entrypoints(),
|
||||
new MainTreeExecutors(),
|
||||
new ShortcutComponent()
|
||||
];
|
||||
|
||||
if (utils.isMobile()) {
|
||||
this.components.push(new MobileScreenSwitcherExecutor());
|
||||
}
|
||||
|
||||
for (const component of this.components) {
|
||||
this.child(component);
|
||||
}
|
||||
|
||||
if (utils.isElectron()) {
|
||||
this.child(zoomComponent);
|
||||
}
|
||||
}
|
||||
|
||||
renderWidgets() {
|
||||
const rootWidget = this.layout.getRootWidget(this);
|
||||
const $renderedWidget = rootWidget.render();
|
||||
|
||||
@ -52,29 +80,8 @@ class AppContext extends Component {
|
||||
component.triggerCommand(commandName, {$el: $(this)});
|
||||
});
|
||||
|
||||
this.tabManager = new TabManager();
|
||||
|
||||
this.executors = [
|
||||
this.tabManager,
|
||||
new RootCommandExecutor(),
|
||||
new Entrypoints(),
|
||||
new MainTreeExecutors()
|
||||
];
|
||||
|
||||
if (utils.isMobile()) {
|
||||
this.executors.push(new MobileScreenSwitcherExecutor());
|
||||
}
|
||||
|
||||
this.child(rootWidget);
|
||||
|
||||
for (const executor of this.executors) {
|
||||
this.child(executor);
|
||||
}
|
||||
|
||||
if (utils.isElectron()) {
|
||||
this.child(zoomService);
|
||||
}
|
||||
|
||||
this.triggerEvent('initialRenderComplete');
|
||||
}
|
||||
|
||||
@ -85,7 +92,7 @@ class AppContext extends Component {
|
||||
|
||||
/** @returns {Promise} */
|
||||
triggerCommand(name, data = {}) {
|
||||
for (const executor of this.executors) {
|
||||
for (const executor of this.components) {
|
||||
const fun = executor[name + "Command"];
|
||||
|
||||
if (fun) {
|
@ -1,13 +1,13 @@
|
||||
import utils from "./utils.js";
|
||||
import dateNoteService from "./date_notes.js";
|
||||
import protectedSessionHolder from './protected_session_holder.js';
|
||||
import server from "./server.js";
|
||||
import utils from "../services/utils.js";
|
||||
import dateNoteService from "../services/date_notes.js";
|
||||
import protectedSessionHolder from '../services/protected_session_holder.js';
|
||||
import server from "../services/server.js";
|
||||
import appContext from "./app_context.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import toastService from "./toast.js";
|
||||
import ws from "./ws.js";
|
||||
import bundleService from "./bundle.js";
|
||||
import froca from "./froca.js";
|
||||
import Component from "./component.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import ws from "../services/ws.js";
|
||||
import bundleService from "../services/bundle.js";
|
||||
import froca from "../services/froca.js";
|
||||
|
||||
export default class Entrypoints extends Component {
|
||||
constructor() {
|
@ -1,8 +1,8 @@
|
||||
import appContext from "./app_context.js";
|
||||
import noteCreateService from "./note_create.js";
|
||||
import treeService from "./tree.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import Component from "./component.js";
|
||||
|
||||
/**
|
||||
* This class contains command executors which logically belong to the NoteTree widget, but for better user experience
|
@ -1,4 +1,4 @@
|
||||
import Component from "../component.js";
|
||||
import Component from "./component.js";
|
||||
|
||||
export default class MobileScreenSwitcherExecutor extends Component {
|
||||
setActiveScreenCommand({screen}) {
|
||||
@ -12,4 +12,4 @@ export default class MobileScreenSwitcherExecutor extends Component {
|
||||
initialRenderCompleteEvent() {
|
||||
this.setActiveScreenCommand({screen: 'tree'});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
import protectedSessionHolder from "./protected_session_holder.js";
|
||||
import server from "./server.js";
|
||||
import utils from "./utils.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import server from "../services/server.js";
|
||||
import utils from "../services/utils.js";
|
||||
import appContext from "./app_context.js";
|
||||
import treeService from "./tree.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import froca from "./froca.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import options from "./options.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import Component from "./component.js";
|
||||
import froca from "../services/froca.js";
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import options from "../services/options.js";
|
||||
|
||||
class NoteContext extends Component {
|
||||
/**
|
@ -1,11 +1,11 @@
|
||||
import Component from "../widgets/component.js";
|
||||
import Component from "./component.js";
|
||||
import appContext from "./app_context.js";
|
||||
import dateNoteService from "../services/date_notes.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import openService from "./open.js";
|
||||
import protectedSessionService from "./protected_session.js";
|
||||
import options from "./options.js";
|
||||
import froca from "./froca.js";
|
||||
import openService from "../services/open.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import options from "../services/options.js";
|
||||
import froca from "../services/froca.js";
|
||||
|
||||
export default class RootCommandExecutor extends Component {
|
||||
editReadOnlyNoteCommand() {
|
||||
@ -46,7 +46,7 @@ export default class RootCommandExecutor extends Component {
|
||||
openNoteExternallyCommand() {
|
||||
const noteId = appContext.tabManager.getActiveContextNoteId();
|
||||
const mime = appContext.tabManager.getActiveContextNoteMime()
|
||||
|
||||
|
||||
if (noteId) {
|
||||
openService.openNoteExternally(noteId, mime);
|
||||
}
|
||||
@ -72,7 +72,7 @@ export default class RootCommandExecutor extends Component {
|
||||
options.toggle('leftPaneVisible');
|
||||
}
|
||||
|
||||
async showLaunchBarShortcutsCommand() {
|
||||
async showLaunchBarSubtreeCommand() {
|
||||
await appContext.tabManager.openContextWithNote('lb_root', true, null, 'lb_root');
|
||||
}
|
||||
|
40
src/public/app/components/shortcut_component.js
Normal file
40
src/public/app/components/shortcut_component.js
Normal file
@ -0,0 +1,40 @@
|
||||
import appContext from "./app_context.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
import server from "../services/server.js";
|
||||
import Component from "./component.js";
|
||||
import froca from "../services/froca.js";
|
||||
|
||||
export default class ShortcutComponent extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
server.get('keyboard-shortcuts-for-notes').then(shortcutAttributes => {
|
||||
for (const attr of shortcutAttributes) {
|
||||
this.bindNoteShortcutHandler(attr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bindNoteShortcutHandler(label) {
|
||||
const handler = () => appContext.tabManager.getActiveContext().setNote(label.noteId);
|
||||
const namespace = label.attributeId;
|
||||
|
||||
if (label.isDeleted) {
|
||||
shortcutService.removeGlobalShortcut(namespace);
|
||||
} else {
|
||||
shortcutService.bindGlobalShortcut(label.value, handler, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({loadResults}) {
|
||||
for (const attr of loadResults.getAttributes()) {
|
||||
if (attr.type === 'label' && attr.name === 'keyboardShortcut') {
|
||||
const note = await froca.getNote(attr.noteId);
|
||||
// launcher shortcuts are handled specifically
|
||||
if (note && note.type !== 'launcher') {
|
||||
this.bindNoteShortcutHandler(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import Component from "../widgets/component.js";
|
||||
import SpacedUpdate from "./spaced_update.js";
|
||||
import server from "./server.js";
|
||||
import options from "./options.js";
|
||||
import froca from "./froca.js";
|
||||
import treeService from "./tree.js";
|
||||
import utils from "./utils.js";
|
||||
import Component from "./component.js";
|
||||
import SpacedUpdate from "../services/spaced_update.js";
|
||||
import server from "../services/server.js";
|
||||
import options from "../services/options.js";
|
||||
import froca from "../services/froca.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import utils from "../services/utils.js";
|
||||
import NoteContext from "./note_context.js";
|
||||
import appContext from "./app_context.js";
|
||||
import Mutex from "../utils/mutex.js";
|
@ -1,11 +1,11 @@
|
||||
import options from "./options.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import options from "../services/options.js";
|
||||
import Component from "./component.js";
|
||||
import utils from "../services/utils.js";
|
||||
|
||||
const MIN_ZOOM = 0.5;
|
||||
const MAX_ZOOM = 2.0;
|
||||
|
||||
class ZoomService extends Component {
|
||||
class ZoomComponent extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@ -59,6 +59,6 @@ class ZoomService extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const zoomService = new ZoomService();
|
||||
const zoomService = new ZoomComponent();
|
||||
|
||||
export default zoomService;
|
@ -1,4 +1,4 @@
|
||||
import appContext from "./services/app_context.js";
|
||||
import appContext from "./components/app_context.js";
|
||||
import utils from './services/utils.js';
|
||||
import noteTooltipService from './services/note_tooltip.js';
|
||||
import bundleService from "./services/bundle.js";
|
||||
@ -7,7 +7,7 @@ import macInit from './services/mac_init.js';
|
||||
import contextMenu from "./menus/context_menu.js";
|
||||
import DesktopLayout from "./layouts/desktop_layout.js";
|
||||
import glob from "./services/glob.js";
|
||||
import zoomService from './services/zoom.js';
|
||||
import zoomService from './components/zoom.js';
|
||||
|
||||
bundleService.getWidgetBundlesByParent().then(widgetBundles => {
|
||||
appContext.setLayout(new DesktopLayout(widgetBundles));
|
||||
|
1
src/public/app/doc_notes/launchbar_command_launcher.html
Normal file
1
src/public/app/doc_notes/launchbar_command_launcher.html
Normal file
@ -0,0 +1 @@
|
||||
<p>Keyboard shortcut for this launcher action can be configured in Options -> Shortcuts.</p>
|
@ -21,7 +21,7 @@ const NOTE_TYPE_ICONS = {
|
||||
"mermaid": "bx bx-selection",
|
||||
"canvas": "bx bx-pen",
|
||||
"web-view": "bx bx-globe-alt",
|
||||
"shortcut": "bx bx-link",
|
||||
"launcher": "bx bx-link",
|
||||
"doc": "bx bxs-file-doc"
|
||||
};
|
||||
|
||||
@ -827,7 +827,7 @@ class NoteShort {
|
||||
}
|
||||
|
||||
isLaunchBarConfig() {
|
||||
return this.type === 'shortcut' || this.noteId.startsWith("lb_");
|
||||
return this.type === 'launcher' || this.noteId.startsWith("lb_");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ import OptionsDialog from "../widgets/dialogs/options.js";
|
||||
import FloatingButtons from "../widgets/floating_buttons/floating_buttons.js";
|
||||
import RelationMapButtons from "../widgets/floating_buttons/relation_map_buttons.js";
|
||||
import MermaidExportButton from "../widgets/floating_buttons/mermaid_export_button.js";
|
||||
import ShortcutContainer from "../widgets/containers/shortcut_container.js";
|
||||
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
||||
import NoteRevisionsButton from "../widgets/buttons/note_revisions_button.js";
|
||||
import EditableCodeButtonsWidget from "../widgets/type_widgets/editable_code_buttons.js";
|
||||
import ApiLogWidget from "../widgets/api_log.js";
|
||||
@ -104,7 +104,7 @@ export default class DesktopLayout {
|
||||
.id("launcher-pane")
|
||||
.css("width", "53px")
|
||||
.child(new GlobalMenuWidget())
|
||||
.child(new ShortcutContainer())
|
||||
.child(new LauncherContainer())
|
||||
.child(new LeftPaneToggleWidget())
|
||||
)
|
||||
.child(new LeftPaneContainer()
|
||||
|
@ -4,7 +4,7 @@ import contextMenu from "./context_menu.js";
|
||||
import dialogService from "../services/dialog.js";
|
||||
import server from "../services/server.js";
|
||||
|
||||
export default class ShortcutContextMenu {
|
||||
export default class LauncherContextMenu {
|
||||
/**
|
||||
* @param {NoteTreeWidget} treeWidget
|
||||
* @param {FancytreeNode} node
|
||||
@ -27,38 +27,38 @@ export default class ShortcutContextMenu {
|
||||
const note = await froca.getNote(this.node.data.noteId);
|
||||
const parentNoteId = this.node.getParent().data.noteId;
|
||||
|
||||
const isVisibleRoot = note.noteId === 'lb_visibleshortcuts';
|
||||
const isAvailableRoot = note.noteId === 'lb_availableshortcuts';
|
||||
const isVisibleItem = parentNoteId === 'lb_visibleshortcuts';
|
||||
const isAvailableItem = parentNoteId === 'lb_availableshortcuts';
|
||||
const isVisibleRoot = note.noteId === 'lb_visiblelaunchers';
|
||||
const isAvailableRoot = note.noteId === 'lb_availablelaunchers';
|
||||
const isVisibleItem = parentNoteId === 'lb_visiblelaunchers';
|
||||
const isAvailableItem = parentNoteId === 'lb_availablelaunchers';
|
||||
const isItem = isVisibleItem || isAvailableItem;
|
||||
const canBeDeleted = !note.noteId.startsWith("lb_");
|
||||
const canBeReset = note.noteId.startsWith("lb_");
|
||||
|
||||
return [
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add note shortcut', command: 'addNoteShortcut', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add script shortcut', command: 'addScriptShortcut', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add widget shortcut', command: 'addWidgetShortcut', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add spacer', command: 'addSpacerShortcut', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a note launcher', command: 'addNoteLauncher', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a script launcher', command: 'addScriptLauncher', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a custom widget', command: 'addWidgetLauncher', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add spacer', command: 'addSpacerLauncher', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: "----" } : null,
|
||||
{ title: 'Delete <kbd data-command="deleteNotes"></kbd>', command: "deleteNotes", uiIcon: "bx bx-trash", enabled: canBeDeleted },
|
||||
{ title: 'Reset', command: "resetShortcut", uiIcon: "bx bx-empty", enabled: canBeReset},
|
||||
{ title: 'Reset', command: "resetLauncher", uiIcon: "bx bx-empty", enabled: canBeReset},
|
||||
{ title: "----" },
|
||||
isAvailableItem ? { title: 'Move to visible shortcuts', command: "moveShortcutToVisible", uiIcon: "bx bx-show", enabled: true } : null,
|
||||
isVisibleItem ? { title: 'Move to available shortcuts', command: "moveShortcutToAvailable", uiIcon: "bx bx-hide", enabled: true } : null,
|
||||
{ title: `Duplicate shortcut <kbd data-command="duplicateSubtree">`, command: "duplicateSubtree", uiIcon: "bx bx-empty",
|
||||
isAvailableItem ? { title: 'Move to visible launchers', command: "moveLauncherToVisible", uiIcon: "bx bx-show", enabled: true } : null,
|
||||
isVisibleItem ? { title: 'Move to available launchers', command: "moveLauncherToAvailable", uiIcon: "bx bx-hide", enabled: true } : null,
|
||||
{ title: `Duplicate launcher <kbd data-command="duplicateSubtree">`, command: "duplicateSubtree", uiIcon: "bx bx-empty",
|
||||
enabled: isItem }
|
||||
].filter(row => row !== null);
|
||||
}
|
||||
|
||||
async selectMenuItemHandler({command}) {
|
||||
if (command === 'resetShortcut') {
|
||||
if (command === 'resetLauncher') {
|
||||
const confirmed = await dialogService.confirm(`Do you really want to reset "${this.node.title}"?
|
||||
All data / settings in this shortcut (and its children) will be lost
|
||||
and the shortcut will be returned to its original location.`);
|
||||
All data / settings in this note (and its children) will be lost
|
||||
and the launcher will be returned to its original location.`);
|
||||
|
||||
if (confirmed) {
|
||||
await server.post(`special-notes/shortcuts/${this.node.data.noteId}/reset`);
|
||||
await server.post(`special-notes/launchers/${this.node.data.noteId}/reset`);
|
||||
}
|
||||
|
||||
return;
|
@ -1,5 +1,5 @@
|
||||
import contextMenu from "./context_menu.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
function openContextMenu(notePath, e) {
|
||||
contextMenu.show({
|
||||
|
@ -3,7 +3,7 @@ import froca from "../services/froca.js";
|
||||
import clipboard from '../services/clipboard.js';
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import contextMenu from "./context_menu.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import noteTypesService from "../services/note_types.js";
|
||||
|
||||
export default class TreeContextMenu {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import appContext from "./services/app_context.js";
|
||||
import appContext from "./components/app_context.js";
|
||||
import MobileLayout from "./layouts/mobile_layout.js";
|
||||
import glob from "./services/glob.js";
|
||||
|
||||
glob.setupGlobs();
|
||||
|
||||
appContext.setLayout(new MobileLayout());
|
||||
appContext.start();
|
||||
appContext.start();
|
||||
|
@ -4,13 +4,13 @@ import toastService from "./toast.js";
|
||||
import froca from "./froca.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
|
||||
branchIdsToMove = filterRootNote(branchIdsToMove);
|
||||
branchIdsToMove = filterSearchBranches(branchIdsToMove);
|
||||
|
||||
if (['root', 'lb_root', 'lb_availableshortcuts', 'lb_visibleshortcuts'].includes(beforeBranchId)) {
|
||||
if (['root', 'lb_root', 'lb_availablelaunchers', 'lb_visiblelaunchers'].includes(beforeBranchId)) {
|
||||
toastService.showError('Cannot move notes here.');
|
||||
return;
|
||||
}
|
||||
@ -35,8 +35,8 @@ async function moveAfterBranch(branchIdsToMove, afterBranchId) {
|
||||
'root',
|
||||
hoistedNoteService.getHoistedNoteId(),
|
||||
'lb_root',
|
||||
'lb_availableshortcuts',
|
||||
'lb_visibleshortcuts'
|
||||
'lb_availablelaunchers',
|
||||
'lb_visiblelaunchers'
|
||||
];
|
||||
|
||||
if (forbiddenNoteIds.includes(afterNote.noteId)) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
async function info(message) {
|
||||
return new Promise(res =>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
const fileModificationStatus = {};
|
||||
|
||||
|
@ -2,7 +2,7 @@ import Branch from "../entities/branch.js";
|
||||
import NoteShort from "../entities/note_short.js";
|
||||
import Attribute from "../entities/attribute.js";
|
||||
import server from "./server.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import NoteComplement from "../entities/note_complement.js";
|
||||
|
||||
/**
|
||||
|
@ -76,7 +76,7 @@ async function processEntityChanges(entityChanges) {
|
||||
noteAttributeCache.invalidate();
|
||||
}
|
||||
|
||||
const appContext = (await import("./app_context.js")).default;
|
||||
const appContext = (await import("../components/app_context.js")).default;
|
||||
await appContext.triggerEvent('entitiesReloaded', {loadResults});
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,11 @@ import dateNotesService from './date_notes.js';
|
||||
import searchService from './search.js';
|
||||
import CollapsibleWidget from '../widgets/collapsible_widget.js';
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import NoteContextAwareWidget from "../widgets/note_context_aware_widget.js";
|
||||
import BasicWidget from "../widgets/basic_widget.js";
|
||||
import SpacedUpdate from "./spaced_update.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
|
||||
/**
|
||||
* This is the main frontend API interface for scripts. It's published in the local "api" object.
|
||||
@ -508,8 +509,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
||||
* @method
|
||||
* @param {string} keyboardShortcut - e.g. "ctrl+shift+a"
|
||||
* @param {function} handler
|
||||
* @param {string} [namespace] - specify namespace of the handler for the cases where call for bind may be repeated.
|
||||
* If a handler with this ID exists, it's replaced by the new handler.
|
||||
*/
|
||||
this.bindGlobalShortcut = utils.bindGlobalShortcut;
|
||||
this.bindGlobalShortcut = shortcutService.bindGlobalShortcut;
|
||||
|
||||
/**
|
||||
* Trilium runs in backend and frontend process, when something is changed on the backend from script,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import utils from "./utils.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import server from "./server.js";
|
||||
import libraryLoader from "./library_loader.js";
|
||||
import ws from "./ws.js";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import treeService from "./tree.js";
|
||||
import dialogService from "./dialog.js";
|
||||
import froca from "./froca.js";
|
||||
|
@ -2,7 +2,7 @@ import toastService from "./toast.js";
|
||||
import server from "./server.js";
|
||||
import ws from "./ws.js";
|
||||
import utils from "./utils.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
export async function uploadFiles(parentNoteId, files, options) {
|
||||
if (files.length === 0) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import server from "./server.js";
|
||||
import utils from "./utils.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
|
||||
const keyboardActionRepo = {};
|
||||
|
||||
@ -31,7 +31,7 @@ async function setupActionsForElement(scope, $el, component) {
|
||||
|
||||
for (const action of actions) {
|
||||
for (const shortcut of action.effectiveShortcuts) {
|
||||
utils.bindElShortcut($el, shortcut, () => component.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeNtxId}));
|
||||
shortcutService.bindElShortcut($el, shortcut, () => component.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeNtxId}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -39,37 +39,11 @@ async function setupActionsForElement(scope, $el, component) {
|
||||
getActionsForScope("window").then(actions => {
|
||||
for (const action of actions) {
|
||||
for (const shortcut of action.effectiveShortcuts) {
|
||||
utils.bindGlobalShortcut(shortcut, () => appContext.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeNtxId}));
|
||||
shortcutService.bindGlobalShortcut(shortcut, () => appContext.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeNtxId}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
server.get('keyboard-shortcuts-for-notes').then(shortcutForNotes => {
|
||||
for (const shortcut in shortcutForNotes) {
|
||||
utils.bindGlobalShortcut(shortcut, async () => {
|
||||
appContext.tabManager.getActiveContext().setNote(shortcutForNotes[shortcut]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function setElementActionHandler($el, actionName, handler) {
|
||||
keyboardActionsLoaded.then(() => {
|
||||
const action = keyboardActionRepo[actionName];
|
||||
|
||||
if (!action) {
|
||||
throw new Error(`Cannot find keyboard action '${actionName}'`);
|
||||
}
|
||||
|
||||
// not setting action.handler since this is not global
|
||||
|
||||
for (const shortcut of action.effectiveShortcuts) {
|
||||
if (shortcut) {
|
||||
utils.bindElShortcut($el, shortcut, handler);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function getAction(actionName, silent = false) {
|
||||
await keyboardActionsLoaded;
|
||||
|
||||
@ -116,10 +90,8 @@ function updateDisplayedShortcuts($container) {
|
||||
}
|
||||
|
||||
export default {
|
||||
setElementActionHandler,
|
||||
updateDisplayedShortcuts,
|
||||
setupActionsForElement,
|
||||
getActions,
|
||||
getActionsForScope,
|
||||
getAction
|
||||
getActionsForScope
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import treeService from './tree.js';
|
||||
import linkContextMenuService from "../menus/link_context_menu.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import froca from "./froca.js";
|
||||
import utils from "./utils.js";
|
||||
|
||||
|
@ -2,15 +2,16 @@
|
||||
* Mac specific initialization
|
||||
*/
|
||||
import utils from "./utils.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
|
||||
function init() {
|
||||
if (utils.isElectron() && utils.isMac()) {
|
||||
utils.bindGlobalShortcut('meta+c', () => exec("copy"));
|
||||
utils.bindGlobalShortcut('meta+v', () => exec('paste'));
|
||||
utils.bindGlobalShortcut('meta+x', () => exec('cut'));
|
||||
utils.bindGlobalShortcut('meta+a', () => exec('selectAll'));
|
||||
utils.bindGlobalShortcut('meta+z', () => exec('undo'));
|
||||
utils.bindGlobalShortcut('meta+y', () => exec('redo'));
|
||||
shortcutService.bindGlobalShortcut('meta+c', () => exec("copy"));
|
||||
shortcutService.bindGlobalShortcut('meta+v', () => exec('paste'));
|
||||
shortcutService.bindGlobalShortcut('meta+x', () => exec('cut'));
|
||||
shortcutService.bindGlobalShortcut('meta+a', () => exec('selectAll'));
|
||||
shortcutService.bindGlobalShortcut('meta+z', () => exec('undo'));
|
||||
shortcutService.bindGlobalShortcut('meta+y', () => exec('redo'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,4 +23,4 @@ function exec(cmd) {
|
||||
|
||||
export default {
|
||||
init
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import server from "./server.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import utils from './utils.js';
|
||||
import noteCreateService from './note_create.js';
|
||||
import treeService from './tree.js';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import utils from "./utils.js";
|
||||
import protectedSessionHolder from "./protected_session_holder.js";
|
||||
import server from "./server.js";
|
||||
|
@ -2,7 +2,7 @@ import server from './server.js';
|
||||
import protectedSessionHolder from './protected_session_holder.js';
|
||||
import toastService from "./toast.js";
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import froca from "./froca.js";
|
||||
import utils from "./utils.js";
|
||||
import options from "./options.js";
|
||||
|
@ -3,7 +3,7 @@ import utils from './utils.js';
|
||||
const REQUEST_LOGGING_ENABLED = false;
|
||||
|
||||
async function getHeaders(headers) {
|
||||
const appContext = (await import('./app_context.js')).default;
|
||||
const appContext = (await import('../components/app_context.js')).default;
|
||||
const activeNoteContext = appContext.tabManager ? appContext.tabManager.getActiveContext() : null;
|
||||
|
||||
// headers need to be lowercase because node.js automatically converts them to lower case
|
||||
|
57
src/public/app/services/shortcuts.js
Normal file
57
src/public/app/services/shortcuts.js
Normal file
@ -0,0 +1,57 @@
|
||||
import utils from "./utils.js";
|
||||
|
||||
function removeGlobalShortcut(namespace) {
|
||||
bindGlobalShortcut('', null, namespace);
|
||||
}
|
||||
|
||||
function bindGlobalShortcut(keyboardShortcut, handler, namespace = null) {
|
||||
bindElShortcut($(document), keyboardShortcut, handler, namespace);
|
||||
}
|
||||
|
||||
function bindElShortcut($el, keyboardShortcut, handler, namespace = null) {
|
||||
if (utils.isDesktop()) {
|
||||
keyboardShortcut = normalizeShortcut(keyboardShortcut);
|
||||
|
||||
let eventName = 'keydown';
|
||||
|
||||
if (namespace) {
|
||||
eventName += "." + namespace;
|
||||
|
||||
// if there's a namespace then we replace the existing event handler with the new one
|
||||
$el.off(eventName);
|
||||
}
|
||||
|
||||
// method can be called to remove the shortcut (e.g. when keyboardShortcut label is deleted)
|
||||
if (keyboardShortcut) {
|
||||
$el.bind(eventName, keyboardShortcut, e => {
|
||||
handler(e);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize to the form expected by the jquery.hotkeys.js
|
||||
*/
|
||||
function normalizeShortcut(shortcut) {
|
||||
if (!shortcut) {
|
||||
return shortcut;
|
||||
}
|
||||
|
||||
return shortcut
|
||||
.toLowerCase()
|
||||
.replace("enter", "return")
|
||||
.replace("delete", "del")
|
||||
.replace("ctrl+alt", "alt+ctrl")
|
||||
.replace("meta+alt", "alt+meta"); // alt needs to be first;
|
||||
}
|
||||
|
||||
export default {
|
||||
bindGlobalShortcut,
|
||||
bindElShortcut,
|
||||
removeGlobalShortcut,
|
||||
normalizeShortcut
|
||||
}
|
@ -3,7 +3,7 @@ import utils from './utils.js';
|
||||
import server from './server.js';
|
||||
import froca from './froca.js';
|
||||
import hoistedNoteService from '../services/hoisted_note.js';
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
/**
|
||||
* @return {string|null}
|
||||
|
@ -132,35 +132,6 @@ function randomString(len) {
|
||||
return text;
|
||||
}
|
||||
|
||||
function bindGlobalShortcut(keyboardShortcut, handler) {
|
||||
bindElShortcut($(document), keyboardShortcut, handler);
|
||||
}
|
||||
|
||||
function bindElShortcut($el, keyboardShortcut, handler) {
|
||||
if (isDesktop()) {
|
||||
keyboardShortcut = normalizeShortcut(keyboardShortcut);
|
||||
|
||||
$el.bind('keydown', keyboardShortcut, e => {
|
||||
handler(e);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize to the form expected by the jquery.hotkeys.js
|
||||
*/
|
||||
function normalizeShortcut(shortcut) {
|
||||
return shortcut
|
||||
.toLowerCase()
|
||||
.replace("enter", "return")
|
||||
.replace("delete", "del")
|
||||
.replace("ctrl+alt", "alt+ctrl")
|
||||
.replace("meta+alt", "alt+meta"); // alt needs to be first;
|
||||
}
|
||||
|
||||
function isMobile() {
|
||||
return window.device === "mobile"
|
||||
// window.device is not available in setup
|
||||
@ -387,8 +358,6 @@ export default {
|
||||
formatLabel,
|
||||
toObject,
|
||||
randomString,
|
||||
bindGlobalShortcut,
|
||||
bindElShortcut,
|
||||
isMobile,
|
||||
isDesktop,
|
||||
setCookie,
|
||||
@ -402,7 +371,6 @@ export default {
|
||||
focusSavedElement,
|
||||
isHtmlEmpty,
|
||||
clearBrowserCache,
|
||||
normalizeShortcut,
|
||||
copySelectionToClipboard,
|
||||
dynamicRequire,
|
||||
timeLimit,
|
||||
|
@ -3,7 +3,7 @@ import toastService from "./toast.js";
|
||||
import server from "./server.js";
|
||||
import options from "./options.js";
|
||||
import frocaUpdater from "./froca_updater.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
const messageHandlers = [];
|
||||
|
||||
|
@ -8,6 +8,7 @@ import promotedAttributeDefinitionParser from '../../services/promoted_attribute
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import SpacedUpdate from "../../services/spaced_update.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import shortcutService from "../../services/shortcuts.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="attr-detail">
|
||||
@ -271,8 +272,8 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
|
||||
|
||||
this.$widget = $(TPL);
|
||||
|
||||
utils.bindElShortcut(this.$widget, 'ctrl+return', () => this.saveAndClose());
|
||||
utils.bindElShortcut(this.$widget, 'esc', () => this.cancelAndClose());
|
||||
shortcutService.bindElShortcut(this.$widget, 'ctrl+return', () => this.saveAndClose());
|
||||
shortcutService.bindElShortcut(this.$widget, 'esc', () => this.cancelAndClose());
|
||||
|
||||
|
||||
this.$title = this.$widget.find('.attr-detail-title');
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Component from "./component.js";
|
||||
import Component from "../components/component.js";
|
||||
|
||||
class BasicWidget extends Component {
|
||||
constructor() {
|
||||
|
@ -2,7 +2,7 @@ import libraryLoader from "../../services/library_loader.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import dateNoteService from "../../services/date_notes.js";
|
||||
import server from "../../services/server.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import RightDropdownButtonWidget from "./right_dropdown_button.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import attributeService from "../../services/attributes.js";
|
||||
import protectedSessionHolder from "../../services/protected_session_holder.js";
|
||||
|
||||
|
@ -124,9 +124,9 @@ const TPL = `
|
||||
<kbd ></kbd>
|
||||
</li>
|
||||
|
||||
<li class="dropdown-item" data-trigger-command="showLaunchBarShortcuts">
|
||||
<li class="dropdown-item" data-trigger-command="showLaunchBarSubtree">
|
||||
<span class="bx bx-sidebar"></span>
|
||||
Configure launchbar shortcuts
|
||||
Configure launchbar
|
||||
</li>
|
||||
|
||||
<li class="dropdown-item" data-trigger-command="showShareSubtree">
|
||||
|
@ -11,6 +11,6 @@ export default class NoteRevisionsButton extends ButtonWidget {
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return super.isEnabled() && !['shortcut', 'doc'].includes(this.note?.type);
|
||||
return super.isEnabled() && !['launcher', 'doc'].includes(this.note?.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import froca from "../../services/froca.js";
|
||||
|
||||
// FIXME: this widget might not be useful anymore
|
||||
|
149
src/public/app/widgets/containers/launcher.js
Normal file
149
src/public/app/widgets/containers/launcher.js
Normal file
@ -0,0 +1,149 @@
|
||||
import ButtonWidget from "../buttons/button_widget.js";
|
||||
import dialogService from "../../services/dialog.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import CalendarWidget from "../buttons/calendar.js";
|
||||
import SpacerWidget from "../spacer.js";
|
||||
import BookmarkButtons from "../bookmark_buttons.js";
|
||||
import ProtectedSessionStatusWidget from "../buttons/protected_session_status.js";
|
||||
import SyncStatusWidget from "../sync_status.js";
|
||||
import BackInHistoryButtonWidget from "../buttons/history/history_back.js";
|
||||
import ForwardInHistoryButtonWidget from "../buttons/history/history_forward.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import shortcutService from "../../services/shortcuts.js";
|
||||
|
||||
export default class LauncherWidget extends BasicWidget {
|
||||
constructor(launcherNote) {
|
||||
super();
|
||||
|
||||
if (launcherNote.type !== 'launcher') {
|
||||
throw new Error(`Note '${this.note.noteId}' '${this.note.title}' is not a launcher even though it's in the launcher subtree`);
|
||||
}
|
||||
|
||||
this.note = launcherNote;
|
||||
this.innerWidget = null;
|
||||
this.handler = null;
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.innerWidget.isEnabled();
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = this.innerWidget.render();
|
||||
}
|
||||
|
||||
async initLauncher() {
|
||||
const launcherType = this.note.getLabelValue("launcherType");
|
||||
|
||||
if (launcherType === 'command') {
|
||||
this.handler = () => this.triggerCommand(this.note.getLabelValue("command"));
|
||||
|
||||
this.innerWidget = new ButtonWidget()
|
||||
.title(this.note.title)
|
||||
.icon(this.note.getIcon())
|
||||
.onClick(this.handler);
|
||||
} else if (launcherType === 'note') {
|
||||
// we're intentionally displaying the launcher title and icon instead of the target
|
||||
// e.g. you want to make launchers to 2 mermaid diagrams which both have mermaid icon (ok),
|
||||
// but on the launchpad you want them distinguishable.
|
||||
// for titles, the note titles may follow a different scheme than maybe desirable on the launchpad
|
||||
// another reason is the discrepancy between what user sees on the launchpad and in the config (esp. icons).
|
||||
// The only (but major) downside is more work in setting up the typical case where you actually want to have both title and icon in sync.
|
||||
|
||||
this.handler = () => {
|
||||
const targetNoteId = this.note.getRelationValue('targetNote');
|
||||
|
||||
if (!targetNoteId) {
|
||||
dialogService.info("This launcher doesn't define target note.");
|
||||
return;
|
||||
}
|
||||
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(targetNoteId, true)
|
||||
};
|
||||
|
||||
this.innerWidget = new ButtonWidget()
|
||||
.title(this.note.title)
|
||||
.icon(this.note.getIcon())
|
||||
.onClick(this.handler);
|
||||
} else if (launcherType === 'script') {
|
||||
this.handler = async () => {
|
||||
const script = await this.note.getRelationTarget('script');
|
||||
|
||||
await script.executeScript();
|
||||
};
|
||||
|
||||
this.innerWidget = new ButtonWidget()
|
||||
.title(this.note.title)
|
||||
.icon(this.note.getIcon())
|
||||
.onClick(this.handler);
|
||||
} else if (launcherType === 'customWidget') {
|
||||
const widget = await this.note.getRelationTarget('widget');
|
||||
|
||||
if (widget) {
|
||||
this.innerWidget = await widget.executeScript();
|
||||
} else {
|
||||
throw new Error(`Could not initiate custom widget of launcher '${this.note.noteId}' '${this.note.title}`);
|
||||
}
|
||||
} else if (launcherType === 'builtinWidget') {
|
||||
const builtinWidget = this.note.getLabelValue("builtinWidget");
|
||||
|
||||
if (builtinWidget) {
|
||||
if (builtinWidget === 'calendar') {
|
||||
this.innerWidget = new CalendarWidget(this.note.title, this.note.getIcon());
|
||||
} else if (builtinWidget === 'spacer') {
|
||||
// || has to be inside since 0 is a valid value
|
||||
const baseSize = parseInt(this.note.getLabelValue("baseSize") || "40");
|
||||
const growthFactor = parseInt(this.note.getLabelValue("growthFactor") || "100");
|
||||
|
||||
this.innerWidget = new SpacerWidget(baseSize, growthFactor);
|
||||
} else if (builtinWidget === 'bookmarks') {
|
||||
this.innerWidget = new BookmarkButtons();
|
||||
} else if (builtinWidget === 'protectedSession') {
|
||||
this.innerWidget = new ProtectedSessionStatusWidget();
|
||||
} else if (builtinWidget === 'syncStatus') {
|
||||
this.innerWidget = new SyncStatusWidget();
|
||||
} else if (builtinWidget === 'backInHistoryButton') {
|
||||
this.innerWidget = new BackInHistoryButtonWidget();
|
||||
} else if (builtinWidget === 'forwardInHistoryButton') {
|
||||
this.innerWidget = new ForwardInHistoryButtonWidget();
|
||||
} else {
|
||||
throw new Error(`Unrecognized builtin widget ${builtinWidget} for launcher ${this.note.noteId} "${this.note.title}"`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Error(`Unrecognized launcher type '${launcherType}' for launcher '${this.note.noteId}' title ${this.note.title}`);
|
||||
}
|
||||
|
||||
if (!this.innerWidget) {
|
||||
throw new Error(`Unknown initialization error for note '${this.note.noteId}', title '${this.note.title}'`);
|
||||
}
|
||||
|
||||
for (const label of this.note.getLabels('keyboardShortcut')) {
|
||||
this.bindNoteShortcutHandler(label);
|
||||
}
|
||||
|
||||
this.child(this.innerWidget);
|
||||
}
|
||||
|
||||
bindNoteShortcutHandler(label) {
|
||||
if (!this.handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
const namespace = label.attributeId;
|
||||
|
||||
if (label.isDeleted) {
|
||||
shortcutService.removeGlobalShortcut(namespace);
|
||||
} else {
|
||||
shortcutService.bindGlobalShortcut(label.value, this.handler, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
for (const attr of loadResults.getAttributes()) {
|
||||
if (attr.noteId === this.note.noteId && attr.type === 'label' && attr.name === 'keyboardShortcut') {
|
||||
this.bindNoteShortcutHandler(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
70
src/public/app/widgets/containers/launcher_container.js
Normal file
70
src/public/app/widgets/containers/launcher_container.js
Normal file
@ -0,0 +1,70 @@
|
||||
import FlexContainer from "./flex_container.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import LauncherWidget from "./launcher.js";
|
||||
|
||||
export default class LauncherContainer extends FlexContainer {
|
||||
constructor() {
|
||||
super('column');
|
||||
|
||||
this.id('launcher-container');
|
||||
this.css('height', '100%');
|
||||
this.filling();
|
||||
|
||||
this.load();
|
||||
}
|
||||
|
||||
async load() {
|
||||
this.children = [];
|
||||
|
||||
const visibleLaunchersRoot = await froca.getNote('lb_visiblelaunchers', true);
|
||||
|
||||
if (!visibleLaunchersRoot) {
|
||||
console.log("Visible launchers root note doesn't exist.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await Promise.allSettled(
|
||||
(await visibleLaunchersRoot.getChildNotes())
|
||||
.map(async launcherNote => {
|
||||
try {
|
||||
const launcherWidget = new LauncherWidget(launcherNote);
|
||||
await launcherWidget.initLauncher();
|
||||
this.child(launcherWidget);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e.message);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this.$widget.empty();
|
||||
this.renderChildren();
|
||||
|
||||
await this.handleEventInChildren('initialRenderComplete');
|
||||
|
||||
const activeContext = appContext.tabManager.getActiveContext();
|
||||
|
||||
if (activeContext) {
|
||||
await this.handleEvent('setNoteContext', {
|
||||
noteContext: activeContext
|
||||
});
|
||||
|
||||
if (activeContext.notePath) {
|
||||
await this.handleEvent('noteSwitched', {
|
||||
noteContext: activeContext,
|
||||
notePath: activeContext.notePath
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
if (loadResults.getNoteIds().find(noteId => froca.notes[noteId]?.isLaunchBarConfig())
|
||||
|| loadResults.getBranches().find(branch => branch.parentNoteId.startsWith("lb_"))
|
||||
|| loadResults.getAttributes().find(attr => froca.notes[attr.noteId]?.isLaunchBarConfig())) {
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
import FlexContainer from "./flex_container.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import ButtonWidget from "../buttons/button_widget.js";
|
||||
import CalendarWidget from "../buttons/calendar.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import SpacerWidget from "../spacer.js";
|
||||
import BookmarkButtons from "../bookmark_buttons.js";
|
||||
import ProtectedSessionStatusWidget from "../buttons/protected_session_status.js";
|
||||
import SyncStatusWidget from "../sync_status.js";
|
||||
import BackInHistoryButtonWidget from "../buttons/history/history_back.js";
|
||||
import ForwardInHistoryButtonWidget from "../buttons/history/history_forward.js";
|
||||
import dialogService from "../../services/dialog.js";
|
||||
|
||||
export default class ShortcutContainer extends FlexContainer {
|
||||
constructor() {
|
||||
super('column');
|
||||
|
||||
this.id('shortcut-container');
|
||||
this.css('height', '100%');
|
||||
this.filling();
|
||||
|
||||
this.load();
|
||||
}
|
||||
|
||||
async load() {
|
||||
this.children = [];
|
||||
|
||||
const visibleShortcutsRoot = await froca.getNote('lb_visibleshortcuts', true);
|
||||
|
||||
if (!visibleShortcutsRoot) {
|
||||
console.log("Visible shortcuts root note doesn't exist.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await Promise.allSettled(
|
||||
(await visibleShortcutsRoot.getChildNotes())
|
||||
.map(shortcut => this.initShortcut(shortcut))
|
||||
);
|
||||
|
||||
this.$widget.empty();
|
||||
this.renderChildren();
|
||||
|
||||
await this.handleEventInChildren('initialRenderComplete');
|
||||
|
||||
const activeContext = appContext.tabManager.getActiveContext();
|
||||
|
||||
if (activeContext) {
|
||||
await this.handleEvent('setNoteContext', {
|
||||
noteContext: activeContext
|
||||
});
|
||||
|
||||
if (activeContext.notePath) {
|
||||
await this.handleEvent('noteSwitched', {
|
||||
noteContext: activeContext,
|
||||
notePath: activeContext.notePath
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async initShortcut(shortcut) {
|
||||
try {
|
||||
if (shortcut.type !== 'shortcut') {
|
||||
console.warn(`Note ${shortcut.noteId} is not a shortcut even though it's in shortcut subtree`);
|
||||
return;
|
||||
}
|
||||
|
||||
const shortcutType = shortcut.getLabelValue("shortcutType");
|
||||
|
||||
if (shortcutType === 'command') {
|
||||
this.child(new ButtonWidget()
|
||||
.title(shortcut.title)
|
||||
.icon(shortcut.getIcon())
|
||||
.command(shortcut.getLabelValue("command")));
|
||||
} else if (shortcutType === 'note') {
|
||||
// we're intentionally displaying the shortcut title and icon instead of the target
|
||||
// e.g. you want to make shortcuts to 2 mermaid diagrams which both have mermaid icon (ok),
|
||||
// but on the launchpad you want them distinguishable.
|
||||
// for titles, the note titles may follow a different scheme than maybe desirable on the launchpad
|
||||
// another reason is the discrepancy between what user sees on the launchpad and in the config (esp. icons).
|
||||
// The only (but major) downside is more work in setting up the typical case where you actually want to have both title and icon in sync.
|
||||
|
||||
this.child(new ButtonWidget()
|
||||
.title(shortcut.title)
|
||||
.icon(shortcut.getIcon())
|
||||
.onClick(() => {
|
||||
const targetNoteId = shortcut.getRelationValue('targetNote');
|
||||
|
||||
if (!targetNoteId) {
|
||||
dialogService.info("This shortcut doesn't define target note.");
|
||||
return;
|
||||
}
|
||||
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(targetNoteId, true)
|
||||
}));
|
||||
} else if (shortcutType === 'script') {
|
||||
this.child(new ButtonWidget()
|
||||
.title(shortcut.title)
|
||||
.icon(shortcut.getIcon())
|
||||
.onClick(async () => {
|
||||
const script = await shortcut.getRelationTarget('script');
|
||||
|
||||
await script.executeScript();
|
||||
}));
|
||||
} else if (shortcutType === 'customWidget') {
|
||||
const widget = await shortcut.getRelationTarget('widget');
|
||||
|
||||
if (widget) {
|
||||
const res = await widget.executeScript();
|
||||
|
||||
this.child(res);
|
||||
}
|
||||
} else if (shortcutType === 'builtinWidget') {
|
||||
const builtinWidget = shortcut.getLabelValue("builtinWidget");
|
||||
|
||||
if (builtinWidget) {
|
||||
if (builtinWidget === 'calendar') {
|
||||
this.child(new CalendarWidget(shortcut.title, shortcut.getIcon()));
|
||||
} else if (builtinWidget === 'spacer') {
|
||||
// || has to be inside since 0 is a valid value
|
||||
const baseSize = parseInt(shortcut.getLabelValue("baseSize") || "40");
|
||||
const growthFactor = parseInt(shortcut.getLabelValue("growthFactor") || "100");
|
||||
|
||||
this.child(new SpacerWidget(baseSize, growthFactor));
|
||||
} else if (builtinWidget === 'bookmarks') {
|
||||
this.child(new BookmarkButtons());
|
||||
} else if (builtinWidget === 'protectedSession') {
|
||||
this.child(new ProtectedSessionStatusWidget());
|
||||
} else if (builtinWidget === 'syncStatus') {
|
||||
this.child(new SyncStatusWidget());
|
||||
} else if (builtinWidget === 'backInHistoryButton') {
|
||||
this.child(new BackInHistoryButtonWidget());
|
||||
} else if (builtinWidget === 'forwardInHistoryButton') {
|
||||
this.child(new ForwardInHistoryButtonWidget());
|
||||
} else {
|
||||
console.warn(`Unrecognized builtin widget ${builtinWidget} for shortcut ${shortcut.noteId} "${shortcut.title}"`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn(`Unrecognized shortcut type ${shortcutType} for shortcut '${shortcut.noteId}' title ${shortcut.title}`);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`Initialization of shortcut '${shortcut.noteId}' with title '${shortcut.title}' failed with error: ${e.message} ${e.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
if (loadResults.getNoteIds().find(noteId => froca.notes[noteId]?.isLaunchBarConfig())
|
||||
|| loadResults.getBranches().find(branch => branch.parentNoteId.startsWith("lb_"))
|
||||
|| loadResults.getAttributes().find(attr => froca.notes[attr.noteId]?.isLaunchBarConfig())) {
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import FlexContainer from "./flex_container.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
|
||||
export default class SplitNoteContainer extends FlexContainer {
|
||||
constructor(widgetFactory) {
|
||||
|
@ -4,7 +4,7 @@ import froca from "../../services/froca.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
|
||||
let branchId;
|
||||
|
||||
|
@ -4,7 +4,7 @@ import treeService from "../../services/tree.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import branchService from "../../services/branches.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
|
||||
const TPL = `
|
||||
|
@ -1,7 +1,8 @@
|
||||
import noteAutocompleteService from '../../services/note_autocomplete.js';
|
||||
import utils from "../../services/utils.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import shortcutService from "../../services/shortcuts.js";
|
||||
|
||||
const TPL = `<div class="jump-to-note-dialog modal mx-auto" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
@ -42,7 +43,7 @@ export default class JumpToNoteDialog extends BasicWidget {
|
||||
this.$showInFullTextButton = this.$widget.find(".show-in-full-text-button");
|
||||
this.$showInFullTextButton.on('click', e => this.showInFullText(e));
|
||||
|
||||
utils.bindElShortcut(this.$widget, 'ctrl+return', e => this.showInFullText(e));
|
||||
shortcutService.bindElShortcut(this.$widget, 'ctrl+return', e => this.showInFullText(e));
|
||||
}
|
||||
|
||||
async jumpToNoteEvent() {
|
||||
|
@ -1,8 +1,9 @@
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import shortcutService from "../../services/shortcuts.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="markdown-import-dialog modal fade mx-auto" tabindex="-1" role="dialog">
|
||||
@ -42,7 +43,7 @@ export default class MarkdownImportDialog extends BasicWidget {
|
||||
|
||||
this.$widget.on('shown.bs.modal', () => this.$importTextarea.trigger('focus'));
|
||||
|
||||
utils.bindElShortcut(this.$widget, 'ctrl+return', () => this.sendForm());
|
||||
shortcutService.bindElShortcut(this.$widget, 'ctrl+return', () => this.sendForm());
|
||||
}
|
||||
|
||||
async convertMarkdownToHtml(text) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import utils from '../../services/utils.js';
|
||||
import server from '../../services/server.js';
|
||||
import toastService from "../../services/toast.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
import openService from "../../services/open.js";
|
||||
import protectedSessionHolder from "../../services/protected_session_holder.js";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import utils from "../../services/utils.js";
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import server from "../../../services/server.js";
|
||||
import utils from "../../../services/utils.js";
|
||||
import appContext from "../../../services/app_context.js";
|
||||
import appContext from "../../../components/app_context.js";
|
||||
import OptionsTab from "./options_tab.js";
|
||||
|
||||
const FONT_FAMILIES = [
|
||||
|
@ -3,7 +3,7 @@ import utils from '../../services/utils.js';
|
||||
import server from '../../services/server.js';
|
||||
import treeService from "../../services/tree.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import hoistedNoteService from "../../services/hoisted_note.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import dialogService from "../../services/dialog.js";
|
||||
|
@ -3,7 +3,7 @@
|
||||
// for consistency
|
||||
import libraryLoader from "../services/library_loader.js";
|
||||
import utils from "../services/utils.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
const FIND_RESULT_SELECTED_CSS_CLASSNAME = "ck-find-result_selected";
|
||||
const FIND_RESULT_CSS_CLASSNAME = "ck-find-result";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import contextMenu from "../../menus/context_menu.js";
|
||||
import noteCreateService from "../../services/note_create.js";
|
||||
import branchService from "../../services/branches.js";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import BasicWidget from "./basic_widget.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
export default class NoteContextAwareWidget extends BasicWidget {
|
||||
isNoteContext(ntxId) {
|
||||
|
@ -3,7 +3,7 @@ import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import SpacedUpdate from "../services/spaced_update.js";
|
||||
import server from "../services/server.js";
|
||||
import libraryLoader from "../services/library_loader.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import attributeService from "../services/attributes.js";
|
||||
@ -197,7 +197,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
||||
type = 'editable-code';
|
||||
}
|
||||
|
||||
if (type === 'shortcut') {
|
||||
if (type === 'launcher') {
|
||||
type = 'doc';
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import libraryLoader from "../services/library_loader.js";
|
||||
import server from "../services/server.js";
|
||||
import attributeService from "../services/attributes.js";
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import linkContextMenuService from "../menus/link_context_menu.js";
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import utils from "../services/utils.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import server from "../services/server.js";
|
||||
import SpacedUpdate from "../services/spaced_update.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import branchService from "../services/branches.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-title-widget">
|
||||
@ -58,13 +58,13 @@ export default class NoteTitleWidget extends NoteContextAwareWidget {
|
||||
this.deleteNoteOnEscape = false;
|
||||
});
|
||||
|
||||
utils.bindElShortcut(this.$noteTitle, 'esc', () => {
|
||||
shortcutService.bindElShortcut(this.$noteTitle, 'esc', () => {
|
||||
if (this.deleteNoteOnEscape && this.noteContext.isActive()) {
|
||||
branchService.deleteNotes(Object.values(this.noteContext.note.parentToBranch));
|
||||
}
|
||||
});
|
||||
|
||||
utils.bindElShortcut(this.$noteTitle, 'return', () => {
|
||||
shortcutService.bindElShortcut(this.$noteTitle, 'return', () => {
|
||||
this.triggerCommand('focusOnDetail', {ntxId: this.noteContext.ntxId});
|
||||
});
|
||||
}
|
||||
@ -73,7 +73,7 @@ export default class NoteTitleWidget extends NoteContextAwareWidget {
|
||||
this.$noteTitle.val(note.title);
|
||||
|
||||
this.$noteTitle.prop("readonly", (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable())
|
||||
|| ["lb_root", "lb_availableshortcuts", "lb_visibleshortcuts"].includes(note.noteId));
|
||||
|| ["lb_root", "lb_availablelaunchers", "lb_visiblelaunchers"].includes(note.noteId));
|
||||
|
||||
this.setProtectedStatus(note);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import server from "../services/server.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import clipboard from "../services/clipboard.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
@ -18,6 +18,7 @@ import syncService from "../services/sync.js";
|
||||
import options from "../services/options.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import dialogService from "../services/dialog.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="tree-wrapper">
|
||||
@ -396,7 +397,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
autoExpandMS: 600,
|
||||
preventLazyParents: false,
|
||||
dragStart: (node, data) => {
|
||||
if (['root', 'hidden', 'lb_root', 'lb_availableshortcuts', 'lb_visibleshortcuts'].includes(node.data.noteId)) {
|
||||
if (['root', 'hidden', 'lb_root', 'lb_availablelaunchers', 'lb_visiblelaunchers'].includes(node.data.noteId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -426,7 +427,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
return false;
|
||||
} else if (node.data.noteId === 'lb_root') {
|
||||
return false;
|
||||
} else if (node.data.noteType === 'shortcut') {
|
||||
} else if (node.data.noteType === 'launcher') {
|
||||
return ['before', 'after'];
|
||||
} else {
|
||||
return true;
|
||||
@ -563,7 +564,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
$span.append($refreshSearchButton);
|
||||
}
|
||||
|
||||
if (!['search', 'shortcut'].includes(note.type)) {
|
||||
if (!['search', 'launcher'].includes(note.type)) {
|
||||
const $createChildNoteButton = $('<span class="tree-item-button add-note-button bx bx-plus" title="Create child note"></span>');
|
||||
|
||||
$span.append($createChildNoteButton);
|
||||
@ -603,8 +604,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
const node = $.ui.fancytree.getNode(e);
|
||||
|
||||
if (hoistedNoteService.getHoistedNoteId() === 'lb_root') {
|
||||
import("../menus/shortcut_context_menu.js").then(({default: ShortcutContextMenu}) => {
|
||||
const shortcutContextMenu = new ShortcutContextMenu(this, node);
|
||||
import("../menus/launcher_context_menu.js").then(({LauncherContextMenu: ShortcutContextMenu}) => {
|
||||
const shortcutContextMenu = new LauncherContextMenu(this, node);
|
||||
shortcutContextMenu.show(e);
|
||||
});
|
||||
} else {
|
||||
@ -1331,7 +1332,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
|
||||
for (const action of actions) {
|
||||
for (const shortcut of action.effectiveShortcuts) {
|
||||
hotKeyMap[utils.normalizeShortcut(shortcut)] = node => {
|
||||
hotKeyMap[shortcutService.normalizeShortcut(shortcut)] = node => {
|
||||
const notePath = treeService.getNotePath(node);
|
||||
|
||||
this.triggerCommand(action.actionName, {node, notePath});
|
||||
@ -1550,11 +1551,11 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
moveShortcutToVisibleCommand({node, selectedOrActiveBranchIds}) {
|
||||
branchService.moveToParentNote(selectedOrActiveBranchIds, 'lb_visibleshortcuts');
|
||||
branchService.moveToParentNote(selectedOrActiveBranchIds, 'lb_visiblelaunchers');
|
||||
}
|
||||
|
||||
moveShortcutToAvailableCommand({node, selectedOrActiveBranchIds}) {
|
||||
branchService.moveToParentNote(selectedOrActiveBranchIds, 'lb_availableshortcuts');
|
||||
branchService.moveToParentNote(selectedOrActiveBranchIds, 'lb_availablelaunchers');
|
||||
}
|
||||
|
||||
addNoteShortcutCommand({node}) {
|
||||
@ -1573,8 +1574,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
this.createShortcutNote(node, 'spacer');
|
||||
}
|
||||
|
||||
async createShortcutNote(node, shortcutType) {
|
||||
const resp = await server.post(`special-notes/shortcuts/${node.data.noteId}/${shortcutType}`);
|
||||
async createShortcutNote(node, launcherType) {
|
||||
const resp = await server.post(`special-notes/shortcuts/${node.data.noteId}/${launcherType}`);
|
||||
|
||||
if (!resp.success) {
|
||||
alert(resp.message);
|
||||
|
@ -8,7 +8,7 @@ const NOTE_TYPES = [
|
||||
{ type: "image", title: "Image", selectable: false },
|
||||
{ type: "search", title: "Saved Search", selectable: false },
|
||||
{ type: "note-map", mime: '', title: "Note Map", selectable: false },
|
||||
{ type: "shortcut", mime: '', title: "Shortcut", selectable: false },
|
||||
{ type: "launcher", mime: '', title: "Launcher", selectable: false },
|
||||
{ type: "doc", mime: '', title: "Doc", selectable: false },
|
||||
|
||||
{ type: "text", mime: "text/html", title: "Text", selectable: true },
|
||||
|
@ -1,10 +1,10 @@
|
||||
import BasicWidget from "./basic_widget.js";
|
||||
import server from "../services/server.js";
|
||||
import linkService from "../services/link.js";
|
||||
import dateNotesService from "../services/date_notes.js";
|
||||
import froca from "../services/froca.js";
|
||||
import utils from "../services/utils.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="quick-search input-group input-group-sm">
|
||||
@ -66,7 +66,7 @@ export default class QuickSearchWidget extends BasicWidget {
|
||||
})
|
||||
}
|
||||
|
||||
utils.bindElShortcut(this.$searchString, 'return', () => {
|
||||
shortcutService.bindElShortcut(this.$searchString, 'return', () => {
|
||||
if (this.$dropdownMenu.is(":visible")) {
|
||||
this.search(); // just update already visible dropdown
|
||||
} else {
|
||||
@ -76,11 +76,11 @@ export default class QuickSearchWidget extends BasicWidget {
|
||||
this.$searchString.focus();
|
||||
});
|
||||
|
||||
utils.bindElShortcut(this.$searchString, 'down', () => {
|
||||
shortcutService.bindElShortcut(this.$searchString, 'down', () => {
|
||||
this.$dropdownMenu.find('.dropdown-item:first').focus();
|
||||
});
|
||||
|
||||
utils.bindElShortcut(this.$searchString, 'esc', () => {
|
||||
shortcutService.bindElShortcut(this.$searchString, 'esc', () => {
|
||||
this.$dropdownToggle.dropdown('hide');
|
||||
});
|
||||
|
||||
@ -120,7 +120,7 @@ export default class QuickSearchWidget extends BasicWidget {
|
||||
appContext.tabManager.getActiveContext().setNote(note.noteId);
|
||||
}
|
||||
});
|
||||
utils.bindElShortcut($link, 'return', () => {
|
||||
shortcutService.bindElShortcut($link, 'return', () => {
|
||||
this.$dropdownToggle.dropdown("hide");
|
||||
|
||||
appContext.tabManager.getActiveContext().setNote(note.noteId);
|
||||
@ -140,9 +140,9 @@ export default class QuickSearchWidget extends BasicWidget {
|
||||
|
||||
$showInFullButton.on('click', () => this.showInFullSearch());
|
||||
|
||||
utils.bindElShortcut($showInFullButton, 'return', () => this.showInFullSearch());
|
||||
shortcutService.bindElShortcut($showInFullButton, 'return', () => this.showInFullSearch());
|
||||
|
||||
utils.bindElShortcut(this.$dropdownMenu.find('.dropdown-item:first'), 'up', () => this.$searchString.focus());
|
||||
shortcutService.bindElShortcut(this.$dropdownMenu.find('.dropdown-item:first'), 'up', () => this.$searchString.focus());
|
||||
|
||||
this.$dropdownToggle.dropdown('update');
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import OrderBy from "../search_options/order_by.js";
|
||||
import SearchScript from "../search_options/search_script.js";
|
||||
import Limit from "../search_options/limit.js";
|
||||
import Debug from "../search_options/debug.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import bulkActionService from "../../services/bulk_action.js";
|
||||
|
||||
const TPL = `
|
||||
|
@ -1,6 +1,6 @@
|
||||
import server from "../../services/server.js";
|
||||
import ws from "../../services/ws.js";
|
||||
import Component from "../component.js";
|
||||
import Component from "../../components/component.js";
|
||||
import utils from "../../services/utils.js";
|
||||
|
||||
export default class AbstractSearchOption extends Component {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import AbstractSearchOption from "./abstract_search_option.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import SpacedUpdate from "../../services/spaced_update.js";
|
||||
import server from "../../services/server.js";
|
||||
import shortcutService from "../../services/shortcuts.js";
|
||||
|
||||
const TPL = `
|
||||
<tr>
|
||||
@ -45,7 +45,7 @@ export default class SearchString extends AbstractSearchOption {
|
||||
this.$searchString = $option.find('.search-string');
|
||||
this.$searchString.on('input', () => this.spacedUpdate.scheduleUpdate());
|
||||
|
||||
utils.bindElShortcut(this.$searchString, 'return', async () => {
|
||||
shortcutService.bindElShortcut(this.$searchString, 'return', async () => {
|
||||
// this also in effect disallows new lines in query string.
|
||||
// on one hand this makes sense since search string is a label
|
||||
// on the other hand it could be nice for structuring long search string. It's probably a niche case though.
|
||||
|
@ -2,7 +2,7 @@ import BasicWidget from "./basic_widget.js";
|
||||
import contextMenu from "../menus/context_menu.js";
|
||||
import utils from "../services/utils.js";
|
||||
import keyboardActionService from "../services/keyboard_actions.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import froca from "../services/froca.js";
|
||||
import attributeService from "../services/attributes.js";
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import linkService from "../../services/link.js";
|
||||
import noteContentRenderer from "../../services/note_content_renderer.js";
|
||||
|
@ -1,6 +1,6 @@
|
||||
import server from "../../services/server.js";
|
||||
import ws from "../../services/ws.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
import treeService from "../../services/tree.js";
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
|
@ -8,7 +8,7 @@ import treeService from "../../services/tree.js";
|
||||
import noteCreateService from "../../services/note_create.js";
|
||||
import AbstractTextTypeWidget from "./abstract_text_type_widget.js";
|
||||
import link from "../../services/link.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
|
||||
const ENABLE_INSPECTOR = false;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import noteAutocompleteService from '../../services/note_autocomplete.js';
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import searchService from "../../services/search.js";
|
||||
|
||||
const TPL = `
|
||||
|
@ -5,7 +5,7 @@ import contextMenu from "../../menus/context_menu.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
import attributeAutocompleteService from "../../services/attribute_autocomplete.js";
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import dialogService from "../../services/dialog.js";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
|
||||
export default class TypeWidget extends NoteContextAwareWidget {
|
||||
// for overriding
|
||||
@ -40,7 +40,7 @@ export default class TypeWidget extends NoteContextAwareWidget {
|
||||
|
||||
/**
|
||||
* @returns {Promise|*} promise resolving content or directly the content
|
||||
*/
|
||||
*/
|
||||
getContent() {}
|
||||
|
||||
focus() {}
|
||||
|
@ -8,15 +8,10 @@ function getKeyboardActions() {
|
||||
}
|
||||
|
||||
function getShortcutsForNotes() {
|
||||
const attrs = becca.findAttributes('label', 'keyboardShortcut');
|
||||
const labels = becca.findAttributes('label', 'keyboardShortcut');
|
||||
|
||||
const map = {};
|
||||
|
||||
for (const attr of attrs) {
|
||||
map[attr.value] = attr.noteId;
|
||||
}
|
||||
|
||||
return map;
|
||||
// launchers have different handling
|
||||
return labels.filter(attr => becca.getNote(attr.noteId)?.type !== 'launcher');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -66,12 +66,12 @@ function getHoistedNote() {
|
||||
return becca.getNote(cls.getHoistedNoteId());
|
||||
}
|
||||
|
||||
function createShortcut(req) {
|
||||
return specialNotesService.createShortcut(req.params.parentNoteId, req.params.shortcutType);
|
||||
function createLauncher(req) {
|
||||
return specialNotesService.createLauncher(req.params.parentNoteId, req.params.launcherType);
|
||||
}
|
||||
|
||||
function resetShortcut(req) {
|
||||
return specialNotesService.resetShortcut(req.params.noteId);
|
||||
function resetLauncher(req) {
|
||||
return specialNotesService.resetLauncher(req.params.noteId);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@ -85,6 +85,6 @@ module.exports = {
|
||||
saveSqlConsole,
|
||||
createSearchNote,
|
||||
saveSearchNote,
|
||||
createShortcut,
|
||||
resetShortcut
|
||||
createLauncher,
|
||||
resetLauncher
|
||||
};
|
||||
|
@ -326,8 +326,8 @@ function register(app) {
|
||||
apiRoute(POST, '/api/special-notes/save-sql-console', specialNotesRoute.saveSqlConsole);
|
||||
apiRoute(POST, '/api/special-notes/search-note', specialNotesRoute.createSearchNote);
|
||||
apiRoute(POST, '/api/special-notes/save-search-note', specialNotesRoute.saveSearchNote);
|
||||
apiRoute(POST, '/api/special-notes/shortcuts/:noteId/reset', specialNotesRoute.resetShortcut);
|
||||
apiRoute(POST, '/api/special-notes/shortcuts/:parentNoteId/:shortcutType', specialNotesRoute.createShortcut);
|
||||
apiRoute(POST, '/api/special-notes/launchers/:noteId/reset', specialNotesRoute.resetLauncher);
|
||||
apiRoute(POST, '/api/special-notes/launchers/:parentNoteId/:launcherType', specialNotesRoute.createLauncher);
|
||||
|
||||
// :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename
|
||||
route(GET, '/api/images/:noteId/:filename', [auth.checkApiAuthOrElectron], imageRoute.returnImage);
|
||||
|
@ -11,6 +11,6 @@ module.exports = [
|
||||
'mermaid',
|
||||
'canvas',
|
||||
'web-view',
|
||||
'shortcut',
|
||||
'launcher',
|
||||
'doc'
|
||||
];
|
||||
|
@ -110,16 +110,16 @@ function getAndValidateParent(params) {
|
||||
throw new Error(`Parent note "${params.parentNoteId}" not found.`);
|
||||
}
|
||||
|
||||
if (parentNote.type === 'shortcut') {
|
||||
throw new Error(`Shortcuts should not have child notes.`);
|
||||
if (parentNote.type === 'launcher') {
|
||||
throw new Error(`Launchers should not have child notes.`);
|
||||
}
|
||||
|
||||
if (!params.ignoreForbiddenParents && ['lb_root'].includes(parentNote.noteId)) {
|
||||
throw new Error(`Creating child notes into '${parentNote.noteId}' is not allowed.`);
|
||||
}
|
||||
|
||||
if (['lb_availableshortcuts', 'lb_visibleshortcuts'].includes(parentNote.noteId) && params.type !== 'shortcut') {
|
||||
throw new Error(`Creating child notes into '${parentNote.noteId}' is only possible for type 'shortcut'.`);
|
||||
if (['lb_availablelaunchers', 'lb_visiblelaunchers'].includes(parentNote.noteId) && params.type !== 'launcher') {
|
||||
throw new Error(`Creating child notes into '${parentNote.noteId}' is only possible for type 'launcher'.`);
|
||||
}
|
||||
|
||||
return parentNote;
|
||||
|
@ -8,7 +8,7 @@ const dateUtils = require("./date_utils");
|
||||
const LBTPL_ROOT = "lbtpl_root";
|
||||
const LBTPL_BASE = "lbtpl_base";
|
||||
const LBTPL_COMMAND = "lbtpl_command";
|
||||
const LBTPL_NOTE_SHORTCUT = "lbtpl_noteshortcut";
|
||||
const LBTPL_NOTE_LAUNCHER = "lbtpl_notelauncher";
|
||||
const LBTPL_SCRIPT = "lbtpl_script";
|
||||
const LBTPL_BUILTIN_WIDGET = "lbtpl_builtinwidget";
|
||||
const LBTPL_SPACER = "lbtpl_spacer";
|
||||
@ -276,14 +276,14 @@ function getLaunchBarRoot() {
|
||||
return note;
|
||||
}
|
||||
|
||||
function getLaunchBarAvailableShortcutsRoot() {
|
||||
let note = becca.getNote('lb_availableshortcuts');
|
||||
function getLaunchBarAvailableLaunchersRoot() {
|
||||
let note = becca.getNote('lb_availablelaunchers');
|
||||
|
||||
if (!note) {
|
||||
note = noteService.createNewNote({
|
||||
branchId: 'lb_availableshortcuts',
|
||||
noteId: 'lb_availableshortcuts',
|
||||
title: 'Available shortcuts',
|
||||
branchId: 'lb_availablelaunchers',
|
||||
noteId: 'lb_availablelaunchers',
|
||||
title: 'Available launchers',
|
||||
type: 'doc',
|
||||
content: '',
|
||||
parentNoteId: getLaunchBarRoot().noteId,
|
||||
@ -294,7 +294,7 @@ function getLaunchBarAvailableShortcutsRoot() {
|
||||
note.addLabel("docName", "launchbar_intro");
|
||||
}
|
||||
|
||||
const branch = becca.getBranch('lb_availableshortcuts');
|
||||
const branch = becca.getBranch('lb_availablelaunchers');
|
||||
if (!branch.isExpanded) {
|
||||
branch.isExpanded = true;
|
||||
branch.save();
|
||||
@ -303,14 +303,14 @@ function getLaunchBarAvailableShortcutsRoot() {
|
||||
return note;
|
||||
}
|
||||
|
||||
function getLaunchBarVisibleShortcutsRoot() {
|
||||
let note = becca.getNote('lb_visibleshortcuts');
|
||||
function getLaunchBarVisibleLaunchersRoot() {
|
||||
let note = becca.getNote('lb_visiblelaunchers');
|
||||
|
||||
if (!note) {
|
||||
note = noteService.createNewNote({
|
||||
branchId: 'lb_visibleshortcuts',
|
||||
noteId: 'lb_visibleshortcuts',
|
||||
title: 'Visible shortcuts',
|
||||
branchId: 'lb_visiblelaunchers',
|
||||
noteId: 'lb_visiblelaunchers',
|
||||
title: 'Visible launchers',
|
||||
type: 'doc',
|
||||
content: '',
|
||||
parentNoteId: getLaunchBarRoot().noteId,
|
||||
@ -321,7 +321,7 @@ function getLaunchBarVisibleShortcutsRoot() {
|
||||
note.addLabel("docName", "launchbar_intro");
|
||||
}
|
||||
|
||||
const branch = becca.getBranch('lb_visibleshortcuts');
|
||||
const branch = becca.getBranch('lb_visiblelaunchers');
|
||||
if (!branch.isExpanded) {
|
||||
branch.isExpanded = true;
|
||||
branch.save();
|
||||
@ -330,20 +330,20 @@ function getLaunchBarVisibleShortcutsRoot() {
|
||||
return note;
|
||||
}
|
||||
|
||||
const shortcuts = [
|
||||
// visible shortcuts:
|
||||
const launchers = [
|
||||
// visible launchers:
|
||||
{ id: 'lb_newnote', command: 'createNoteIntoInbox', title: 'New note', icon: 'bx bx-file-blank', isVisible: true },
|
||||
{ id: 'lb_search', command: 'searchNotes', title: 'Search notes', icon: 'bx bx-search', isVisible: true },
|
||||
{ id: 'lb_jumpto', command: 'jumpToNote', title: 'Jump to note', icon: 'bx bx-send', isVisible: true },
|
||||
{ id: 'lb_notemap', targetNoteId: 'globalnotemap', title: 'Note map', icon: 'bx bx-map-alt', isVisible: true },
|
||||
{ id: 'lb_calendar', builtinWidget: 'calendar', title: 'Calendar', icon: 'bx bx-calendar', isVisible: true },
|
||||
{ id: 'lb_spacer1', builtinWidget: 'spacer', title: 'Spacer', isVisible: true, baseSize: 50, growthFactor: 0 },
|
||||
{ id: 'lb_spacer1', builtinWidget: 'spacer', title: 'Spacer', isVisible: true, baseSize: "50", growthFactor: "0" },
|
||||
{ id: 'lb_bookmarks', builtinWidget: 'bookmarks', title: 'Bookmarks', icon: 'bx bx-bookmark', isVisible: true },
|
||||
{ id: 'lb_spacer2', builtinWidget: 'spacer', title: 'Spacer', isVisible: true, baseSize: 0, growthFactor: 1 },
|
||||
{ id: 'lb_spacer2', builtinWidget: 'spacer', title: 'Spacer', isVisible: true, baseSize: "0", growthFactor: "1" },
|
||||
{ id: 'lb_protectedsession', builtinWidget: 'protectedSession', title: 'Protected session', icon: 'bx bx bx-shield-quarter', isVisible: true },
|
||||
{ id: 'lb_syncstatus', builtinWidget: 'syncStatus', title: 'Sync status', icon: 'bx bx-wifi', isVisible: true },
|
||||
|
||||
// available shortcuts:
|
||||
// available launchers:
|
||||
{ id: 'lb_recentchanges', command: 'showRecentChanges', title: 'Recent changes', icon: 'bx bx-history', isVisible: false },
|
||||
{ id: 'lb_backinhistory', builtinWidget: 'backInHistoryButton', title: 'Back in history', icon: 'bx bxs-left-arrow-square', isVisible: false },
|
||||
{ id: 'lb_forwardinhistory', builtinWidget: 'forwardInHistoryButton', title: 'Forward in history', icon: 'bx bxs-right-arrow-square', isVisible: false },
|
||||
@ -353,53 +353,53 @@ function createMissingSpecialNotes() {
|
||||
getSqlConsoleRoot();
|
||||
getGlobalNoteMap();
|
||||
getBulkActionNote();
|
||||
createShortcutTemplates();
|
||||
createLauncherTemplates();
|
||||
getLaunchBarRoot();
|
||||
getLaunchBarAvailableShortcutsRoot();
|
||||
getLaunchBarVisibleShortcutsRoot();
|
||||
getLaunchBarAvailableLaunchersRoot();
|
||||
getLaunchBarVisibleLaunchersRoot();
|
||||
getShareRoot();
|
||||
|
||||
for (const shortcut of shortcuts) {
|
||||
let note = becca.getNote(shortcut.id);
|
||||
for (const launcher of launchers) {
|
||||
let note = becca.getNote(launcher.id);
|
||||
|
||||
if (note) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const parentNoteId = shortcut.isVisible
|
||||
? getLaunchBarVisibleShortcutsRoot().noteId
|
||||
: getLaunchBarAvailableShortcutsRoot().noteId;
|
||||
const parentNoteId = launcher.isVisible
|
||||
? getLaunchBarVisibleLaunchersRoot().noteId
|
||||
: getLaunchBarAvailableLaunchersRoot().noteId;
|
||||
|
||||
note = noteService.createNewNote({
|
||||
noteId: shortcut.id,
|
||||
title: shortcut.title,
|
||||
type: 'shortcut',
|
||||
noteId: launcher.id,
|
||||
title: launcher.title,
|
||||
type: 'launcher',
|
||||
content: '',
|
||||
parentNoteId: parentNoteId
|
||||
}).note;
|
||||
|
||||
if (shortcut.icon) {
|
||||
note.addLabel('iconClass', shortcut.icon);
|
||||
if (launcher.icon) {
|
||||
note.addLabel('iconClass', launcher.icon);
|
||||
}
|
||||
|
||||
if (shortcut.command) {
|
||||
if (launcher.command) {
|
||||
note.addRelation('template', LBTPL_COMMAND);
|
||||
note.addLabel('command', shortcut.command);
|
||||
} else if (shortcut.builtinWidget) {
|
||||
if (shortcut.builtinWidget === 'spacer') {
|
||||
note.addLabel('command', launcher.command);
|
||||
} else if (launcher.builtinWidget) {
|
||||
if (launcher.builtinWidget === 'spacer') {
|
||||
note.addRelation('template', LBTPL_SPACER);
|
||||
note.addLabel("baseSize", shortcut.baseSize);
|
||||
note.addLabel("growthFactor", shortcut.growthFactor);
|
||||
note.addLabel("baseSize", launcher.baseSize);
|
||||
note.addLabel("growthFactor", launcher.growthFactor);
|
||||
} else {
|
||||
note.addRelation('template', LBTPL_BUILTIN_WIDGET);
|
||||
}
|
||||
|
||||
note.addLabel('builtinWidget', shortcut.builtinWidget);
|
||||
} else if (shortcut.targetNoteId) {
|
||||
note.addRelation('template', LBTPL_NOTE_SHORTCUT);
|
||||
note.addRelation('targetNote', shortcut.targetNoteId);
|
||||
note.addLabel('builtinWidget', launcher.builtinWidget);
|
||||
} else if (launcher.targetNoteId) {
|
||||
note.addRelation('template', LBTPL_NOTE_LAUNCHER);
|
||||
note.addRelation('targetNote', launcher.targetNoteId);
|
||||
} else {
|
||||
throw new Error(`No action defined for shortcut ${JSON.stringify(shortcut)}`);
|
||||
throw new Error(`No action defined for launcher ${JSON.stringify(launcher)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,47 +412,47 @@ function createMissingSpecialNotes() {
|
||||
}
|
||||
}
|
||||
|
||||
function createShortcut(parentNoteId, shortcutType) {
|
||||
function createLauncher(parentNoteId, launcherType) {
|
||||
let note;
|
||||
|
||||
if (shortcutType === 'note') {
|
||||
if (launcherType === 'note') {
|
||||
note = noteService.createNewNote({
|
||||
title: "Note shortcut",
|
||||
type: 'shortcut',
|
||||
title: "Note launcher",
|
||||
type: 'launcher',
|
||||
content: '',
|
||||
parentNoteId: parentNoteId
|
||||
}).note;
|
||||
|
||||
note.addRelation('template', LBTPL_NOTE_SHORTCUT);
|
||||
} else if (shortcutType === 'script') {
|
||||
note.addRelation('template', LBTPL_NOTE_LAUNCHER);
|
||||
} else if (launcherType === 'script') {
|
||||
note = noteService.createNewNote({
|
||||
title: "Script shortcut",
|
||||
type: 'shortcut',
|
||||
title: "Script launcher",
|
||||
type: 'launcher',
|
||||
content: '',
|
||||
parentNoteId: parentNoteId
|
||||
}).note;
|
||||
|
||||
note.addRelation('template', LBTPL_SCRIPT);
|
||||
} else if (shortcutType === 'customWidget') {
|
||||
} else if (launcherType === 'customWidget') {
|
||||
note = noteService.createNewNote({
|
||||
title: "Widget shortcut",
|
||||
type: 'shortcut',
|
||||
title: "Widget launcher",
|
||||
type: 'launcher',
|
||||
content: '',
|
||||
parentNoteId: parentNoteId
|
||||
}).note;
|
||||
|
||||
note.addRelation('template', LBTPL_CUSTOM_WIDGET);
|
||||
} else if (shortcutType === 'spacer') {
|
||||
} else if (launcherType === 'spacer') {
|
||||
note = noteService.createNewNote({
|
||||
title: "Spacer",
|
||||
type: 'shortcut',
|
||||
type: 'launcher',
|
||||
content: '',
|
||||
parentNoteId: parentNoteId
|
||||
}).note;
|
||||
|
||||
note.addRelation('template', LBTPL_SPACER);
|
||||
} else {
|
||||
throw new Error(`Unrecognized shortcut type ${shortcutType}`);
|
||||
throw new Error(`Unrecognized launcher type ${launcherType}`);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -461,7 +461,7 @@ function createShortcut(parentNoteId, shortcutType) {
|
||||
};
|
||||
}
|
||||
|
||||
function createShortcutTemplates() {
|
||||
function createLauncherTemplates() {
|
||||
if (!(LBTPL_ROOT in becca.notes)) {
|
||||
noteService.createNewNote({
|
||||
branchId: LBTPL_ROOT,
|
||||
@ -474,46 +474,46 @@ function createShortcutTemplates() {
|
||||
}
|
||||
|
||||
if (!(LBTPL_BASE in becca.notes)) {
|
||||
const tpl = noteService.createNewNote({
|
||||
noteService.createNewNote({
|
||||
branchId: LBTPL_BASE,
|
||||
noteId: LBTPL_BASE,
|
||||
title: 'Launch bar base shortcut',
|
||||
title: 'Launch bar base launcher',
|
||||
type: 'doc',
|
||||
content: '',
|
||||
parentNoteId: getHiddenRoot().noteId
|
||||
}).note;
|
||||
|
||||
tpl.addLabel('label:keyboardShortcut', 'promoted,text');
|
||||
});
|
||||
}
|
||||
|
||||
if (!(LBTPL_COMMAND in becca.notes)) {
|
||||
const tpl = noteService.createNewNote({
|
||||
branchId: LBTPL_COMMAND,
|
||||
noteId: LBTPL_COMMAND,
|
||||
title: 'Command shortcut',
|
||||
title: 'Command launcher',
|
||||
type: 'doc',
|
||||
content: '',
|
||||
parentNoteId: LBTPL_ROOT
|
||||
}).note;
|
||||
|
||||
tpl.addRelation('template', LBTPL_BASE);
|
||||
tpl.addLabel('shortcutType', 'command');
|
||||
tpl.addLabel('launcherType', 'command');
|
||||
tpl.addLabel('docName', 'launchbar_command_launcher');
|
||||
}
|
||||
|
||||
if (!(LBTPL_NOTE_SHORTCUT in becca.notes)) {
|
||||
if (!(LBTPL_NOTE_LAUNCHER in becca.notes)) {
|
||||
const tpl = noteService.createNewNote({
|
||||
branchId: LBTPL_NOTE_SHORTCUT,
|
||||
noteId: LBTPL_NOTE_SHORTCUT,
|
||||
title: 'Note shortcut',
|
||||
branchId: LBTPL_NOTE_LAUNCHER,
|
||||
noteId: LBTPL_NOTE_LAUNCHER,
|
||||
title: 'Note launcher',
|
||||
type: 'doc',
|
||||
content: '',
|
||||
parentNoteId: LBTPL_ROOT
|
||||
}).note;
|
||||
|
||||
tpl.addRelation('template', LBTPL_BASE);
|
||||
tpl.addLabel('shortcutType', 'note');
|
||||
tpl.addLabel('launcherType', 'note');
|
||||
tpl.addLabel('relation:targetNote', 'promoted');
|
||||
tpl.addLabel('docName', 'launchbar_note_shortcut');
|
||||
tpl.addLabel('docName', 'launchbar_note_launcher');
|
||||
tpl.addLabel('label:keyboardShortcut', 'promoted,text');
|
||||
}
|
||||
|
||||
if (!(LBTPL_SCRIPT in becca.notes)) {
|
||||
@ -527,9 +527,10 @@ function createShortcutTemplates() {
|
||||
}).note;
|
||||
|
||||
tpl.addRelation('template', LBTPL_BASE);
|
||||
tpl.addLabel('shortcutType', 'script');
|
||||
tpl.addLabel('launcherType', 'script');
|
||||
tpl.addLabel('relation:script', 'promoted');
|
||||
tpl.addLabel('docName', 'launchbar_script_shortcut');
|
||||
tpl.addLabel('docName', 'launchbar_script_launcher');
|
||||
tpl.addLabel('label:keyboardShortcut', 'promoted,text');
|
||||
}
|
||||
|
||||
if (!(LBTPL_BUILTIN_WIDGET in becca.notes)) {
|
||||
@ -543,7 +544,7 @@ function createShortcutTemplates() {
|
||||
}).note;
|
||||
|
||||
tpl.addRelation('template', LBTPL_BASE);
|
||||
tpl.addLabel('shortcutType', 'builtinWidget');
|
||||
tpl.addLabel('launcherType', 'builtinWidget');
|
||||
}
|
||||
|
||||
if (!(LBTPL_SPACER in becca.notes)) {
|
||||
@ -575,13 +576,13 @@ function createShortcutTemplates() {
|
||||
}).note;
|
||||
|
||||
tpl.addRelation('template', LBTPL_BASE);
|
||||
tpl.addLabel('shortcutType', 'customWidget');
|
||||
tpl.addLabel('launcherType', 'customWidget');
|
||||
tpl.addLabel('relation:widget', 'promoted');
|
||||
tpl.addLabel('docName', 'launchbar_widget_shortcut');
|
||||
tpl.addLabel('docName', 'launchbar_widget_launcher');
|
||||
}
|
||||
}
|
||||
|
||||
function resetShortcut(noteId) {
|
||||
function resetLauncher(noteId) {
|
||||
if (noteId.startsWith('lb_')) {
|
||||
const note = becca.getNote(noteId);
|
||||
|
||||
@ -598,7 +599,7 @@ function resetShortcut(noteId) {
|
||||
log.info(`Note ${noteId} has not been found and cannot be reset.`);
|
||||
}
|
||||
} else {
|
||||
log.info(`Note ${noteId} is not a resettable shortcut note.`);
|
||||
log.info(`Note ${noteId} is not a resettable launcher note.`);
|
||||
}
|
||||
|
||||
createMissingSpecialNotes();
|
||||
@ -614,6 +615,6 @@ module.exports = {
|
||||
getShareRoot,
|
||||
getHiddenRoot,
|
||||
getBulkActionNote,
|
||||
createShortcut,
|
||||
resetShortcut
|
||||
createLauncher,
|
||||
resetLauncher
|
||||
};
|
||||
|
@ -30,7 +30,7 @@ function getNotes(noteIds) {
|
||||
}
|
||||
|
||||
function validateParentChild(parentNoteId, childNoteId, branchId = null) {
|
||||
if (['root', 'hidden', 'share', 'lb_root', 'lb_availableshortcuts', 'lb_visibleshortcuts'].includes(childNoteId)) {
|
||||
if (['root', 'hidden', 'share', 'lb_root', 'lb_availablelaunchers', 'lb_visiblelaunchers'].includes(childNoteId)) {
|
||||
return { success: false, message: `Cannot change this note's location.`};
|
||||
}
|
||||
|
||||
@ -58,10 +58,10 @@ function validateParentChild(parentNoteId, childNoteId, branchId = null) {
|
||||
};
|
||||
}
|
||||
|
||||
if (becca.getNote(parentNoteId).type === 'shortcut') {
|
||||
if (becca.getNote(parentNoteId).type === 'launcher') {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Shortcut note cannot have any children.'
|
||||
message: 'Launcher note cannot have any children.'
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user