mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 11:02:28 +08:00
150 lines
6.3 KiB
JavaScript
150 lines
6.3 KiB
JavaScript
![]() |
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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|