mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Merge remote-tracking branch 'origin/next58' into next58
This commit is contained in:
commit
29923af17d
@ -1,15 +1,10 @@
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import keyboardActionsService from "../../services/keyboard_actions.js";
|
||||
|
||||
const TPL = `<span class="button-widget icon-action bx"
|
||||
data-toggle="tooltip"
|
||||
title=""></span>`;
|
||||
|
||||
let actions;
|
||||
|
||||
keyboardActionsService.getActions().then(as => actions = as);
|
||||
|
||||
export default class ButtonWidget extends NoteContextAwareWidget {
|
||||
export default class AbstractButtonWidget extends NoteContextAwareWidget {
|
||||
isEnabled() {
|
||||
return true;
|
||||
}
|
||||
@ -21,8 +16,6 @@ export default class ButtonWidget extends NoteContextAwareWidget {
|
||||
titlePlacement: 'right',
|
||||
title: null,
|
||||
icon: null,
|
||||
command: null,
|
||||
onClick: null,
|
||||
onContextMenu: null
|
||||
};
|
||||
}
|
||||
@ -30,20 +23,6 @@ export default class ButtonWidget extends NoteContextAwareWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
|
||||
if (this.settings.onClick) {
|
||||
this.$widget.on("click", e => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.settings.onClick(this, e);
|
||||
});
|
||||
} else {
|
||||
this.$widget.on("click", () => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.triggerCommand(this.settings.command);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.settings.onContextMenu) {
|
||||
this.$widget.on("contextmenu", e => {
|
||||
this.$widget.tooltip("hide");
|
||||
@ -56,26 +35,19 @@ export default class ButtonWidget extends NoteContextAwareWidget {
|
||||
|
||||
this.$widget.tooltip({
|
||||
html: true,
|
||||
title: () => {
|
||||
const title = typeof this.settings.title === "function"
|
||||
? this.settings.title()
|
||||
: this.settings.title;
|
||||
|
||||
const action = actions.find(act => act.actionName === this.settings.command);
|
||||
|
||||
if (action && action.effectiveShortcuts.length > 0) {
|
||||
return `${title} (${action.effectiveShortcuts.join(", ")})`;
|
||||
}
|
||||
else {
|
||||
return title;
|
||||
}
|
||||
},
|
||||
title: () => this.getTitle(),
|
||||
trigger: "hover"
|
||||
});
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
return typeof this.settings.title === "function"
|
||||
? this.settings.title()
|
||||
: this.settings.title;
|
||||
}
|
||||
|
||||
refreshIcon() {
|
||||
for (const className of this.$widget[0].classList) {
|
||||
if (className.startsWith("bx-")) {
|
||||
@ -83,39 +55,36 @@ export default class ButtonWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
}
|
||||
|
||||
this.$widget.addClass(this.settings.icon);
|
||||
const icon = typeof this.settings.icon === "function"
|
||||
? this.settings.icon()
|
||||
: this.settings.icon;
|
||||
|
||||
this.$widget.addClass(icon);
|
||||
}
|
||||
|
||||
initialRenderCompleteEvent() {
|
||||
this.refreshIcon();
|
||||
}
|
||||
|
||||
/** @param {string|function} icon */
|
||||
icon(icon) {
|
||||
this.settings.icon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @param {string|function} title */
|
||||
title(title) {
|
||||
this.settings.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @param {string} placement - "top", "bottom", "left", "right" */
|
||||
titlePlacement(placement) {
|
||||
this.settings.titlePlacement = placement;
|
||||
return this;
|
||||
}
|
||||
|
||||
command(command) {
|
||||
this.settings.command = command;
|
||||
return this;
|
||||
}
|
||||
|
||||
onClick(handler) {
|
||||
this.settings.onClick = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
onContextMenu(handler) {
|
||||
this.settings.onContextMenu = handler;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import attributeService from "../../services/attributes.js";
|
||||
import CommandButtonWidget from "./command_button.js";
|
||||
|
||||
export default class ButtonFromNoteWidget extends ButtonWidget {
|
||||
export default class ButtonFromNoteWidget extends CommandButtonWidget {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
|
||||
export default class ClosePaneButton extends ButtonWidget {
|
||||
export default class ClosePaneButton extends OnClickButtonWidget {
|
||||
isEnabled() {
|
||||
return super.isEnabled()
|
||||
// main note context should not be closeable
|
||||
|
54
src/public/app/widgets/buttons/command_button.js
Normal file
54
src/public/app/widgets/buttons/command_button.js
Normal file
@ -0,0 +1,54 @@
|
||||
import keyboardActionsService from "../../services/keyboard_actions.js";
|
||||
import AbstractButtonWidget from "./abstract_button.js";
|
||||
|
||||
let actions;
|
||||
|
||||
keyboardActionsService.getActions().then(as => actions = as);
|
||||
|
||||
export default class CommandButtonWidget extends AbstractButtonWidget {
|
||||
doRender() {
|
||||
super.doRender();
|
||||
|
||||
if (this.settings.command) {
|
||||
this.$widget.on("click", () => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.triggerCommand(this._command);
|
||||
});
|
||||
} else {
|
||||
console.warn(`Button widget '${this.componentId}' has no defined command`, this.settings);
|
||||
}
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
const title = super.getTitle();
|
||||
|
||||
const action = actions.find(act => act.actionName === this._command);
|
||||
|
||||
if (action && action.effectiveShortcuts.length > 0) {
|
||||
return `${title} (${action.effectiveShortcuts.join(", ")})`;
|
||||
} else {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
onClick(handler) {
|
||||
this.settings.onClick = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function|string} command
|
||||
* @returns {CommandButtonWidget}
|
||||
*/
|
||||
command(command) {
|
||||
this.settings.command = command;
|
||||
return this;
|
||||
}
|
||||
|
||||
get _command() {
|
||||
return typeof this.settings.command === "function"
|
||||
? this.settings.command()
|
||||
: this.settings.command;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
|
||||
export default class CreatePaneButton extends ButtonWidget {
|
||||
export default class CreatePaneButton extends OnClickButtonWidget {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import attributeService from "../../services/attributes.js";
|
||||
import protectedSessionHolder from "../../services/protected_session_holder.js";
|
||||
|
||||
export default class EditButton extends ButtonWidget {
|
||||
export default class EditButton extends OnClickButtonWidget {
|
||||
isEnabled() {
|
||||
return super.isEnabled() && this.noteContext;
|
||||
}
|
||||
|
33
src/public/app/widgets/buttons/launcher/abstract_launcher.js
Normal file
33
src/public/app/widgets/buttons/launcher/abstract_launcher.js
Normal file
@ -0,0 +1,33 @@
|
||||
import shortcutService from "../../../services/shortcuts.js";
|
||||
import OnClickButtonWidget from "../onclick_button.js";
|
||||
|
||||
export default class AbstractLauncher extends OnClickButtonWidget {
|
||||
constructor(launcherNote) {
|
||||
super();
|
||||
|
||||
/** @type {NoteShort} */
|
||||
this.launcherNote = launcherNote;
|
||||
}
|
||||
|
||||
launch() {
|
||||
throw new Error("Abstract implementation");
|
||||
}
|
||||
|
||||
bindNoteShortcutHandler(label) {
|
||||
const namespace = label.attributeId;
|
||||
|
||||
if (label.isDeleted) {
|
||||
shortcutService.removeGlobalShortcut(namespace);
|
||||
} else {
|
||||
shortcutService.bindGlobalShortcut(label.value, () => this.launch(), namespace);
|
||||
}
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
for (const attr of loadResults.getAttributes()) {
|
||||
if (attr.noteId === this.launcherNote.noteId && attr.type === 'label' && attr.name === 'keyboardShortcut') {
|
||||
this.bindNoteShortcutHandler(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
src/public/app/widgets/buttons/launcher/note_launcher.js
Normal file
44
src/public/app/widgets/buttons/launcher/note_launcher.js
Normal file
@ -0,0 +1,44 @@
|
||||
import AbstractLauncher from "./abstract_launcher.js";
|
||||
import dialogService from "../../../services/dialog.js";
|
||||
import appContext from "../../../components/app_context.js";
|
||||
|
||||
export default class NoteLauncher extends AbstractLauncher {
|
||||
constructor(launcherNote) {
|
||||
super(launcherNote);
|
||||
|
||||
this.title(this.launcherNote.title)
|
||||
.icon(this.launcherNote.getIcon())
|
||||
.onClick(() => this.launch());
|
||||
}
|
||||
|
||||
launch() {
|
||||
// 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.
|
||||
const targetNoteId = this.launcherNote.getRelationValue('targetNote');
|
||||
|
||||
if (!targetNoteId) {
|
||||
dialogService.info("This launcher doesn't define target note.");
|
||||
return;
|
||||
}
|
||||
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(targetNoteId, true);
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
const shortcuts = this.launcherNote.getLabels("keyboardShortcut")
|
||||
.map(l => l.value)
|
||||
.filter(v => !!v)
|
||||
.join(", ");
|
||||
|
||||
let title = super.getTitle();
|
||||
if (shortcuts) {
|
||||
title += ` (${shortcuts})`;
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
}
|
17
src/public/app/widgets/buttons/launcher/script_launcher.js
Normal file
17
src/public/app/widgets/buttons/launcher/script_launcher.js
Normal file
@ -0,0 +1,17 @@
|
||||
import AbstractLauncher from "./abstract_launcher.js";
|
||||
|
||||
export default class ScriptLauncher extends AbstractLauncher {
|
||||
constructor(launcherNote) {
|
||||
super(launcherNote);
|
||||
|
||||
this.title(this.launcherNote.title)
|
||||
.icon(this.launcherNote.getIcon())
|
||||
.onClick(this.handler);
|
||||
}
|
||||
|
||||
async launch() {
|
||||
const script = await this.launcherNote.getRelationTarget('script');
|
||||
|
||||
await script.executeScript();
|
||||
}
|
||||
}
|
@ -1,26 +1,28 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import options from "../../services/options.js";
|
||||
import splitService from "../../services/resizer.js";
|
||||
import CommandButtonWidget from "./command_button.js";
|
||||
|
||||
export default class LeftPaneToggleWidget extends ButtonWidget {
|
||||
refreshIcon() {
|
||||
const isLeftPaneVisible = options.is('leftPaneVisible');
|
||||
export default class LeftPaneToggleWidget extends CommandButtonWidget {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.settings.icon = isLeftPaneVisible
|
||||
this.settings.icon = () => options.is('leftPaneVisible')
|
||||
? "bx-chevrons-left"
|
||||
: "bx-chevrons-right";
|
||||
|
||||
this.settings.title = isLeftPaneVisible
|
||||
this.settings.title = () => options.is('leftPaneVisible')
|
||||
? "Hide panel"
|
||||
: "Open panel";
|
||||
|
||||
this.settings.command = isLeftPaneVisible
|
||||
this.settings.command = () => options.is('leftPaneVisible')
|
||||
? "hideLeftPane"
|
||||
: "showLeftPane";
|
||||
}
|
||||
|
||||
refreshIcon() {
|
||||
super.refreshIcon();
|
||||
|
||||
splitService.setupLeftPaneResizer(isLeftPaneVisible);
|
||||
splitService.setupLeftPaneResizer(options.is('leftPaneVisible'));
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import CommandButtonWidget from "./command_button.js";
|
||||
|
||||
export default class NoteRevisionsButton extends ButtonWidget {
|
||||
export default class NoteRevisionsButton extends CommandButtonWidget {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
22
src/public/app/widgets/buttons/onclick_button.js
Normal file
22
src/public/app/widgets/buttons/onclick_button.js
Normal file
@ -0,0 +1,22 @@
|
||||
import AbstractButtonWidget from "./abstract_button.js";
|
||||
|
||||
export default class OnClickButtonWidget extends AbstractButtonWidget {
|
||||
doRender() {
|
||||
super.doRender();
|
||||
|
||||
if (this.settings.onClick) {
|
||||
this.$widget.on("click", e => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.settings.onClick(this, e);
|
||||
});
|
||||
} else {
|
||||
console.warn(`Button widget '${this.componentId}' has no defined click handler`, this.settings);
|
||||
}
|
||||
}
|
||||
|
||||
onClick(handler) {
|
||||
this.settings.onClick = handler;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import froca from "../../services/froca.js";
|
||||
|
||||
// FIXME: this widget might not be useful anymore
|
||||
|
||||
export default class OpenNoteButtonWidget extends ButtonWidget {
|
||||
export default class OpenNoteButtonWidget extends OnClickButtonWidget {
|
||||
targetNote(noteId) {
|
||||
froca.getNote(noteId).then(note => {
|
||||
if (!note) {
|
||||
|
@ -1,29 +1,24 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import protectedSessionHolder from "../../services/protected_session_holder.js";
|
||||
import CommandButtonWidget from "./command_button.js";
|
||||
|
||||
export default class ProtectedSessionStatusWidget extends ButtonWidget {
|
||||
doRender() {
|
||||
this.updateSettings();
|
||||
export default class ProtectedSessionStatusWidget extends CommandButtonWidget {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
updateSettings() {
|
||||
this.settings.icon = protectedSessionHolder.isProtectedSessionAvailable()
|
||||
this.settings.icon = () => protectedSessionHolder.isProtectedSessionAvailable()
|
||||
? "bx-check-shield"
|
||||
: "bx-shield-quarter";
|
||||
|
||||
this.settings.title = protectedSessionHolder.isProtectedSessionAvailable()
|
||||
this.settings.title = () => protectedSessionHolder.isProtectedSessionAvailable()
|
||||
? "Protected session is active. Click to leave protected session."
|
||||
: "Click to enter protected session";
|
||||
|
||||
this.settings.command = protectedSessionHolder.isProtectedSessionAvailable()
|
||||
this.settings.command = () => protectedSessionHolder.isProtectedSessionAvailable()
|
||||
? "leaveProtectedSession"
|
||||
: "enterProtectedSession";
|
||||
}
|
||||
|
||||
protectedSessionStartedEvent() {
|
||||
this.updateSettings();
|
||||
this.refreshIcon();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
import ButtonWidget from "../buttons/button_widget.js";
|
||||
import dialogService from "../../services/dialog.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import OnClickButtonWidget from "../buttons/onclick_button.js";
|
||||
import CalendarWidget from "../buttons/calendar.js";
|
||||
import SpacerWidget from "../spacer.js";
|
||||
import BookmarkButtons from "../bookmark_buttons.js";
|
||||
@ -9,19 +7,15 @@ 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";
|
||||
import NoteLauncher from "../buttons/launcher/note_launcher.js";
|
||||
import ScriptLauncher from "../buttons/launcher/script_launcher.js";
|
||||
import CommandButtonWidget from "../buttons/command_button.js";
|
||||
|
||||
export default class LauncherWidget extends BasicWidget {
|
||||
constructor(launcherNote) {
|
||||
constructor() {
|
||||
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() {
|
||||
@ -32,118 +26,74 @@ export default class LauncherWidget extends BasicWidget {
|
||||
this.$widget = this.innerWidget.render();
|
||||
}
|
||||
|
||||
async initLauncher() {
|
||||
const launcherType = this.note.getLabelValue("launcherType");
|
||||
async initLauncher(note) {
|
||||
if (note.type !== 'launcher') {
|
||||
throw new Error(`Note '${note.noteId}' '${note.title}' is not a launcher even though it's in the launcher subtree`);
|
||||
}
|
||||
|
||||
const launcherType = 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);
|
||||
this.innerWidget = this.initCommandWidget(note);
|
||||
} 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);
|
||||
this.innerWidget = new NoteLauncher(note);
|
||||
} 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);
|
||||
this.innerWidget = new ScriptLauncher(note);
|
||||
} 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}`);
|
||||
}
|
||||
this.innerWidget = await this.initCustomWidget(note);
|
||||
} 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}"`);
|
||||
}
|
||||
}
|
||||
this.innerWidget = this.initBuiltinWidget(note);
|
||||
} else {
|
||||
throw new Error(`Unrecognized launcher type '${launcherType}' for launcher '${this.note.noteId}' title ${this.note.title}`);
|
||||
throw new Error(`Unrecognized launcher type '${launcherType}' for launcher '${note.noteId}' title ${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);
|
||||
throw new Error(`Unknown initialization error for note '${note.noteId}', title '${note.title}'`);
|
||||
}
|
||||
|
||||
this.child(this.innerWidget);
|
||||
}
|
||||
|
||||
bindNoteShortcutHandler(label) {
|
||||
if (!this.handler) {
|
||||
return;
|
||||
}
|
||||
initCommandWidget(note) {
|
||||
return new CommandButtonWidget()
|
||||
.title(note.title)
|
||||
.icon(note.getIcon())
|
||||
.command(() => note.getLabelValue("command"));
|
||||
}
|
||||
|
||||
const namespace = label.attributeId;
|
||||
async initCustomWidget(note) {
|
||||
const widget = await note.getRelationTarget('widget');
|
||||
|
||||
if (label.isDeleted) {
|
||||
shortcutService.removeGlobalShortcut(namespace);
|
||||
if (widget) {
|
||||
return await widget.executeScript();
|
||||
} else {
|
||||
shortcutService.bindGlobalShortcut(label.value, this.handler, namespace);
|
||||
throw new Error(`Custom widget of launcher '${note.noteId}' '${note.title}' is not defined.`);
|
||||
}
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
for (const attr of loadResults.getAttributes()) {
|
||||
if (attr.noteId === this.note.noteId && attr.type === 'label' && attr.name === 'keyboardShortcut') {
|
||||
this.bindNoteShortcutHandler(attr);
|
||||
}
|
||||
initBuiltinWidget(note) {
|
||||
const builtinWidget = note.getLabelValue("builtinWidget");
|
||||
|
||||
if (builtinWidget === 'calendar') {
|
||||
return new CalendarWidget(note.title, note.getIcon());
|
||||
} else if (builtinWidget === 'spacer') {
|
||||
// || has to be inside since 0 is a valid value
|
||||
const baseSize = parseInt(note.getLabelValue("baseSize") || "40");
|
||||
const growthFactor = parseInt(note.getLabelValue("growthFactor") || "100");
|
||||
|
||||
return new SpacerWidget(baseSize, growthFactor);
|
||||
} else if (builtinWidget === 'bookmarks') {
|
||||
return new BookmarkButtons();
|
||||
} else if (builtinWidget === 'protectedSession') {
|
||||
return new ProtectedSessionStatusWidget();
|
||||
} else if (builtinWidget === 'syncStatus') {
|
||||
return new SyncStatusWidget();
|
||||
} else if (builtinWidget === 'backInHistoryButton') {
|
||||
return new BackInHistoryButtonWidget();
|
||||
} else if (builtinWidget === 'forwardInHistoryButton') {
|
||||
return new ForwardInHistoryButtonWidget();
|
||||
} else {
|
||||
throw new Error(`Unrecognized builtin widget ${builtinWidget} for launcher ${note.noteId} "${note.title}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,12 +29,12 @@ export default class LauncherContainer extends FlexContainer {
|
||||
(await visibleLaunchersRoot.getChildNotes())
|
||||
.map(async launcherNote => {
|
||||
try {
|
||||
const launcherWidget = new LauncherWidget(launcherNote);
|
||||
await launcherWidget.initLauncher();
|
||||
const launcherWidget = new LauncherWidget();
|
||||
await launcherWidget.initLauncher(launcherNote);
|
||||
this.child(launcherWidget);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e.message);
|
||||
console.error(e);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@ -19,6 +19,7 @@ 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";
|
||||
import LauncherContextMenu from "../menus/launcher_context_menu.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="tree-wrapper">
|
||||
@ -1558,24 +1559,24 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
branchService.moveToParentNote(selectedOrActiveBranchIds, 'lb_availablelaunchers');
|
||||
}
|
||||
|
||||
addNoteShortcutCommand({node}) {
|
||||
this.createShortcutNote(node, 'note');
|
||||
addNoteLauncherCommand({node}) {
|
||||
this.createLauncherNote(node, 'note');
|
||||
}
|
||||
|
||||
addScriptShortcutCommand({node}) {
|
||||
this.createShortcutNote(node, 'script');
|
||||
addScriptLauncherCommand({node}) {
|
||||
this.createLauncherNote(node, 'script');
|
||||
}
|
||||
|
||||
addWidgetShortcutCommand({node}) {
|
||||
this.createShortcutNote(node, 'customWidget');
|
||||
addWidgetLauncherCommand({node}) {
|
||||
this.createLauncherNote(node, 'customWidget');
|
||||
}
|
||||
|
||||
addSpacerShortcutCommand({node}) {
|
||||
this.createShortcutNote(node, 'spacer');
|
||||
addSpacerLauncherCommand({node}) {
|
||||
this.createLauncherNote(node, 'spacer');
|
||||
}
|
||||
|
||||
async createShortcutNote(node, launcherType) {
|
||||
const resp = await server.post(`special-notes/shortcuts/${node.data.noteId}/${launcherType}`);
|
||||
async createLauncherNote(node, launcherType) {
|
||||
const resp = await server.post(`special-notes/launchers/${node.data.noteId}/${launcherType}`);
|
||||
|
||||
if (!resp.success) {
|
||||
alert(resp.message);
|
||||
|
Loading…
x
Reference in New Issue
Block a user