Files
Trilium/src/public/app/widgets/buttons/launcher/note_launcher.ts

99 lines
3.7 KiB
TypeScript
Raw Normal View History

import { t } from "../../../services/i18n.js";
2024-08-02 09:21:15 +08:00
import AbstractLauncher from "./abstract_launcher.js";
2022-12-02 16:46:14 +01:00
import dialogService from "../../../services/dialog.js";
import appContext from "../../../components/app_context.js";
import utils from "../../../services/utils.js";
import linkContextMenuService from "../../../menus/link_context_menu.js";
import type FNote from "../../../entities/fnote.js";
2022-12-02 16:46:14 +01:00
2023-06-30 11:18:34 +02:00
// 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 downside is more work in setting up the typical case
// where you actually want to have both title and icon in sync, but for those cases there are bookmarks
2022-12-02 16:46:14 +01:00
export default class NoteLauncher extends AbstractLauncher {
constructor(launcherNote: FNote) {
2022-12-02 16:46:14 +01:00
super(launcherNote);
this.title(() => this.launcherNote.title)
.icon(() => this.launcherNote.getIcon())
.onClick((widget, evt) => this.launch(evt))
.onAuxClick((widget, evt) => this.launch(evt))
.onContextMenu(async (evt) => {
let targetNoteId = await Promise.resolve(this.getTargetNoteId());
if (!targetNoteId || !evt) {
return;
}
const hoistedNoteId = this.getHoistedNoteId();
2023-04-03 23:47:24 +02:00
linkContextMenuService.openContextMenu(targetNoteId, evt, {}, hoistedNoteId);
});
}
async launch(evt?: JQuery.ClickEvent | JQuery.ContextMenuEvent | JQuery.TriggeredEvent) {
2022-12-18 23:25:35 +01:00
// await because subclass overrides can be async
const targetNoteId = await this.getTargetNoteId();
if (!targetNoteId || evt?.which === 3) {
return;
}
2022-12-18 23:25:35 +01:00
const hoistedNoteId = await this.getHoistedNoteId();
if (!hoistedNoteId) {
return;
}
if (!evt) {
// keyboard shortcut
// TODO: Fix once tabManager is ported.
//@ts-ignore
await appContext.tabManager.openInSameTab(targetNoteId, hoistedNoteId);
} else {
const ctrlKey = utils.isCtrlKey(evt);
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
// TODO: Fix once tabManager is ported.
//@ts-ignore
await appContext.tabManager.openInNewTab(targetNoteId, hoistedNoteId);
} else {
// TODO: Fix once tabManager is ported.
//@ts-ignore
await appContext.tabManager.openInSameTab(targetNoteId, hoistedNoteId);
}
}
2022-12-02 16:46:14 +01:00
}
getTargetNoteId(): void | string | Promise<string | undefined> {
2025-01-09 18:07:02 +02:00
const targetNoteId = this.launcherNote.getRelationValue("target");
2022-12-02 16:46:14 +01:00
if (!targetNoteId) {
dialogService.info(t("note_launcher.this_launcher_doesnt_define_target_note"));
2022-12-02 16:46:14 +01:00
return;
}
return targetNoteId;
2022-12-02 16:46:14 +01:00
}
getHoistedNoteId() {
2025-01-09 18:07:02 +02:00
return this.launcherNote.getRelationValue("hoistedNote") || appContext.tabManager.getActiveContext().hoistedNoteId;
}
2022-12-02 16:46:14 +01:00
getTitle() {
2025-01-09 18:07:02 +02:00
const shortcuts = this.launcherNote
.getLabels("keyboardShortcut")
.map((l) => l.value)
.filter((v) => !!v)
2022-12-02 16:46:14 +01:00
.join(", ");
let title = super.getTitle();
if (shortcuts) {
title += ` (${shortcuts})`;
}
return title;
}
}