mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 09:58:32 +02:00
added note hoisting option to the note launcher
This commit is contained in:
parent
0de0b6fd06
commit
5fca606730
@ -226,7 +226,7 @@ export default class TabManager extends Component {
|
|||||||
async openEmptyTab(ntxId = null, hoistedNoteId = 'root', mainNtxId = null) {
|
async openEmptyTab(ntxId = null, hoistedNoteId = 'root', mainNtxId = null) {
|
||||||
const noteContext = new NoteContext(ntxId, hoistedNoteId, mainNtxId);
|
const noteContext = new NoteContext(ntxId, hoistedNoteId, mainNtxId);
|
||||||
|
|
||||||
let existingNoteContext
|
let existingNoteContext;
|
||||||
|
|
||||||
if (utils.isMobile()) {
|
if (utils.isMobile()) {
|
||||||
// kind of hacky way to enforce a single tab on mobile interface - all requests to create a new one
|
// kind of hacky way to enforce a single tab on mobile interface - all requests to create a new one
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
<p>Please define the target note in the promoted attributes.</p>
|
<p>You can define the following attributes:</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li><code>targetNote</code> - note which should be opened upon activating the launcher</li>
|
||||||
|
<li><code>hoistedNote</code> - optional, will change the hoisted note before opening the target note</li>
|
||||||
|
<li><code>keyboardShortcut</code> - optional, pressing the keyboard shortcut will open the note</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
<p>Launchbar displays the title / icon from the shortcut which does not necessarily mirrors those of the target note.</p>
|
<p>Launchbar displays the title / icon from the shortcut which does not necessarily mirrors those of the target note.</p>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import contextMenu from "./context_menu.js";
|
import contextMenu from "./context_menu.js";
|
||||||
import appContext from "../components/app_context.js";
|
import appContext from "../components/app_context.js";
|
||||||
|
|
||||||
function openContextMenu(notePath, e) {
|
function openContextMenu(notePath, hoistedNoteId, e) {
|
||||||
contextMenu.show({
|
contextMenu.show({
|
||||||
x: e.pageX,
|
x: e.pageX,
|
||||||
y: e.pageY,
|
y: e.pageY,
|
||||||
@ -11,17 +11,21 @@ function openContextMenu(notePath, e) {
|
|||||||
{title: "Open note in a new window", command: "openNoteInNewWindow", uiIcon: "bx bx-window-open"}
|
{title: "Open note in a new window", command: "openNoteInNewWindow", uiIcon: "bx bx-window-open"}
|
||||||
],
|
],
|
||||||
selectMenuItemHandler: ({command}) => {
|
selectMenuItemHandler: ({command}) => {
|
||||||
|
if (!hoistedNoteId) {
|
||||||
|
hoistedNoteId = appContext.tabManager.getActiveContext().hoistedNoteId;
|
||||||
|
}
|
||||||
|
|
||||||
if (command === 'openNoteInNewTab') {
|
if (command === 'openNoteInNewTab') {
|
||||||
appContext.tabManager.openTabWithNoteWithHoisting(notePath);
|
appContext.tabManager.openContextWithNote(notePath, false, null, hoistedNoteId);
|
||||||
}
|
}
|
||||||
else if (command === 'openNoteInNewSplit') {
|
else if (command === 'openNoteInNewSplit') {
|
||||||
const subContexts = appContext.tabManager.getActiveContext().getSubContexts();
|
const subContexts = appContext.tabManager.getActiveContext().getSubContexts();
|
||||||
const {ntxId} = subContexts[subContexts.length - 1];
|
const {ntxId} = subContexts[subContexts.length - 1];
|
||||||
|
|
||||||
appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath});
|
appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath, hoistedNoteId});
|
||||||
}
|
}
|
||||||
else if (command === 'openNoteInNewWindow') {
|
else if (command === 'openNoteInNewWindow') {
|
||||||
appContext.triggerCommand('openInWindow', {notePath, hoistedNoteId: 'root'});
|
appContext.triggerCommand('openInWindow', {notePath, hoistedNoteId});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -155,7 +155,7 @@ function linkContextMenu(e) {
|
|||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
linkContextMenuService.openContextMenu(notePath, e);
|
linkContextMenuService.openContextMenu(notePath, null, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadReferenceLinkTitle(noteId, $el) {
|
async function loadReferenceLinkTitle(noteId, $el) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import shortcutService from "../../../services/shortcuts.js";
|
import shortcutService from "../../../services/shortcuts.js";
|
||||||
|
import attributesService from "../../../services/attributes.js";
|
||||||
import OnClickButtonWidget from "../onclick_button.js";
|
import OnClickButtonWidget from "../onclick_button.js";
|
||||||
|
|
||||||
export default class AbstractLauncher extends OnClickButtonWidget {
|
export default class AbstractLauncher extends OnClickButtonWidget {
|
||||||
@ -33,6 +34,8 @@ export default class AbstractLauncher extends OnClickButtonWidget {
|
|||||||
for (const attr of loadResults.getAttributes()) {
|
for (const attr of loadResults.getAttributes()) {
|
||||||
if (attr.noteId === this.launcherNote.noteId && attr.type === 'label' && attr.name === 'keyboardShortcut') {
|
if (attr.noteId === this.launcherNote.noteId && attr.type === 'label' && attr.name === 'keyboardShortcut') {
|
||||||
this.bindNoteShortcutHandler(attr);
|
this.bindNoteShortcutHandler(attr);
|
||||||
|
} else if (attr.type === 'label' && attr.name === 'iconClass' && attributesService.isAffecting(attr, this.launcherNote)) {
|
||||||
|
this.refreshIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ export default class NoteLauncher extends AbstractLauncher {
|
|||||||
constructor(launcherNote) {
|
constructor(launcherNote) {
|
||||||
super(launcherNote);
|
super(launcherNote);
|
||||||
|
|
||||||
this.title(this.launcherNote.title)
|
this.title(() => this.launcherNote.title)
|
||||||
.icon(this.launcherNote.getIcon())
|
.icon(() => this.launcherNote.getIcon())
|
||||||
.onClick((widget, evt) => this.launch(evt))
|
.onClick((widget, evt) => this.launch(evt))
|
||||||
.onAuxClick((widget, evt) => this.launch(evt))
|
.onAuxClick((widget, evt) => this.launch(evt))
|
||||||
.onContextMenu(evt => {
|
.onContextMenu(evt => {
|
||||||
@ -25,30 +25,46 @@ export default class NoteLauncher extends AbstractLauncher {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
linkContextMenuService.openContextMenu(targetNoteId, evt);
|
const hoistedNoteId = this.getHoistedNoteId();
|
||||||
|
|
||||||
|
linkContextMenuService.openContextMenu(targetNoteId, hoistedNoteId, evt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
launch(evt) {
|
async launch(evt) {
|
||||||
const targetNoteId = this.getTargetNoteId();
|
const targetNoteId = this.getTargetNoteId();
|
||||||
if (!targetNoteId) {
|
if (!targetNoteId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hoistedNoteId = this.getHoistedNoteId();
|
||||||
|
|
||||||
if (!evt) {
|
if (!evt) {
|
||||||
// keyboard shortcut
|
// keyboard shortcut
|
||||||
appContext.tabManager.getActiveContext().setNote(targetNoteId)
|
await this.openInSameTab(targetNoteId, hoistedNoteId);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ctrlKey = utils.isCtrlKey(evt);
|
|
||||||
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
|
|
||||||
appContext.tabManager.openTabWithNoteWithHoisting(targetNoteId);
|
|
||||||
} else {
|
} else {
|
||||||
appContext.tabManager.getActiveContext().setNote(targetNoteId);
|
const ctrlKey = utils.isCtrlKey(evt);
|
||||||
|
|
||||||
|
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
|
||||||
|
await this.openInNewTab(targetNoteId, hoistedNoteId);
|
||||||
|
} else {
|
||||||
|
await this.openInSameTab(targetNoteId, hoistedNoteId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async openInNewTab(targetNoteId, hoistedNoteId) {
|
||||||
|
const noteContext = await appContext.tabManager.openEmptyTab(null, hoistedNoteId);
|
||||||
|
|
||||||
|
await noteContext.setNote(targetNoteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async openInSameTab(targetNoteId, hoistedNoteId) {
|
||||||
|
const activeContext = appContext.tabManager.getActiveContext();
|
||||||
|
await activeContext.setHoistedNoteId(hoistedNoteId);
|
||||||
|
await activeContext.setNote(targetNoteId);
|
||||||
|
}
|
||||||
|
|
||||||
getTargetNoteId() {
|
getTargetNoteId() {
|
||||||
const targetNoteId = this.launcherNote.getRelationValue('targetNote');
|
const targetNoteId = this.launcherNote.getRelationValue('targetNote');
|
||||||
|
|
||||||
@ -60,6 +76,11 @@ export default class NoteLauncher extends AbstractLauncher {
|
|||||||
return targetNoteId;
|
return targetNoteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getHoistedNoteId() {
|
||||||
|
return this.launcherNote.getRelationValue('hoistedNote')
|
||||||
|
|| appContext.tabManager.getActiveContext().hoistedNoteId;
|
||||||
|
}
|
||||||
|
|
||||||
getTitle() {
|
getTitle() {
|
||||||
const shortcuts = this.launcherNote.getLabels("keyboardShortcut")
|
const shortcuts = this.launcherNote.getLabels("keyboardShortcut")
|
||||||
.map(l => l.value)
|
.map(l => l.value)
|
||||||
@ -73,4 +94,4 @@ export default class NoteLauncher extends AbstractLauncher {
|
|||||||
|
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ export default class ScriptLauncher extends AbstractLauncher {
|
|||||||
constructor(launcherNote) {
|
constructor(launcherNote) {
|
||||||
super(launcherNote);
|
super(launcherNote);
|
||||||
|
|
||||||
this.title(this.launcherNote.title)
|
this.title(() => this.launcherNote.title)
|
||||||
.icon(this.launcherNote.getIcon())
|
.icon(() => this.launcherNote.getIcon())
|
||||||
.onClick(() => this.launch());
|
.onClick(() => this.launch());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export default class SplitNoteContainer extends FlexContainer {
|
|||||||
this.child(widget);
|
this.child(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
async openNewNoteSplitEvent({ntxId, notePath}) {
|
async openNewNoteSplitEvent({ntxId, notePath, hoistedNoteId}) {
|
||||||
const mainNtxId = appContext.tabManager.getActiveMainContext().ntxId;
|
const mainNtxId = appContext.tabManager.getActiveMainContext().ntxId;
|
||||||
|
|
||||||
if (!ntxId) {
|
if (!ntxId) {
|
||||||
@ -43,7 +43,7 @@ export default class SplitNoteContainer extends FlexContainer {
|
|||||||
ntxId = mainNtxId;
|
ntxId = mainNtxId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hoistedNoteId = appContext.tabManager.getActiveContext().hoistedNoteId;
|
hoistedNoteId = hoistedNoteId || appContext.tabManager.getActiveContext().hoistedNoteId;
|
||||||
|
|
||||||
const noteContext = await appContext.tabManager.openEmptyTab(null, hoistedNoteId, mainNtxId);
|
const noteContext = await appContext.tabManager.openEmptyTab(null, hoistedNoteId, mainNtxId);
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ export default class NoteMapWidget extends NoteContextAwareWidget {
|
|||||||
.linkWidth(1)
|
.linkWidth(1)
|
||||||
.linkColor(() => this.css.mutedTextColor)
|
.linkColor(() => this.css.mutedTextColor)
|
||||||
.onNodeClick(node => appContext.tabManager.getActiveContext().setNote(node.id))
|
.onNodeClick(node => appContext.tabManager.getActiveContext().setNote(node.id))
|
||||||
.onNodeRightClick((node, e) => linkContextMenuService.openContextMenu(node.id, e));
|
.onNodeRightClick((node, e) => linkContextMenuService.openContextMenu(node.id, null, e));
|
||||||
|
|
||||||
if (this.mapType === 'link') {
|
if (this.mapType === 'link') {
|
||||||
this.graph
|
this.graph
|
||||||
|
@ -757,7 +757,7 @@ li.dropdown-submenu:hover > ul.dropdown-menu {
|
|||||||
.dropdown-submenu > .dropdown-menu {
|
.dropdown-submenu > .dropdown-menu {
|
||||||
top: 0;
|
top: 0;
|
||||||
left: calc(100% - 2px); /* -2px, otherwise there's a small gap between menu and submenu where the hover can disappear */
|
left: calc(100% - 2px); /* -2px, otherwise there's a small gap between menu and submenu where the hover can disappear */
|
||||||
margin-top: -6px;
|
margin-top: -10px;
|
||||||
min-width: 15rem;
|
min-width: 15rem;
|
||||||
/* to make submenu scrollable https://github.com/zadam/trilium/issues/3136 */
|
/* to make submenu scrollable https://github.com/zadam/trilium/issues/3136 */
|
||||||
max-height: 600px;
|
max-height: 600px;
|
||||||
|
@ -97,6 +97,7 @@ const HIDDEN_SUBTREE_DEFINITION = {
|
|||||||
{ type: 'relation', name: 'template', value: LBTPL_BASE },
|
{ type: 'relation', name: 'template', value: LBTPL_BASE },
|
||||||
{ type: 'label', name: 'launcherType', value: 'note' },
|
{ type: 'label', name: 'launcherType', value: 'note' },
|
||||||
{ type: 'label', name: 'relation:targetNote', value: 'promoted' },
|
{ type: 'label', name: 'relation:targetNote', value: 'promoted' },
|
||||||
|
{ type: 'label', name: 'relation:hoistedNote', value: 'promoted' },
|
||||||
{ type: 'label', name: 'label:keyboardShortcut', value: 'promoted,text' },
|
{ type: 'label', name: 'label:keyboardShortcut', value: 'promoted,text' },
|
||||||
{ type: 'label', name: 'docName', value: 'launchbar_note_launcher' }
|
{ type: 'label', name: 'docName', value: 'launchbar_note_launcher' }
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user