launchbar WIP

This commit is contained in:
zadam 2022-08-06 15:00:56 +02:00
parent 54900b35dc
commit 08aa65bddb
13 changed files with 71 additions and 53 deletions

11
package-lock.json generated
View File

@ -22,6 +22,7 @@
"csurf": "1.11.0",
"dayjs": "1.11.4",
"dayjs-plugin-utc": "^0.1.2",
"debounce": "^1.2.1",
"ejs": "3.1.8",
"electron-debug": "3.2.0",
"electron-dl": "3.3.1",
@ -3237,6 +3238,11 @@
"resolved": "https://registry.npmjs.org/dayjs-plugin-utc/-/dayjs-plugin-utc-0.1.2.tgz",
"integrity": "sha512-ExERH5o3oo6jFOdkvMP3gytTCQ9Ksi5PtylclJWghr7k7m3o2U5QrwtdiJkOxLOH4ghr0EKhpqGefzGz1VvVJg=="
},
"node_modules/debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -13266,6 +13272,11 @@
"resolved": "https://registry.npmjs.org/dayjs-plugin-utc/-/dayjs-plugin-utc-0.1.2.tgz",
"integrity": "sha512-ExERH5o3oo6jFOdkvMP3gytTCQ9Ksi5PtylclJWghr7k7m3o2U5QrwtdiJkOxLOH4ghr0EKhpqGefzGz1VvVJg=="
},
"debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",

View File

@ -38,6 +38,7 @@
"csurf": "1.11.0",
"dayjs": "1.11.4",
"dayjs-plugin-utc": "^0.1.2",
"debounce": "^1.2.1",
"ejs": "3.1.8",
"electron-debug": "3.2.0",
"electron-dl": "3.3.1",

View File

@ -706,7 +706,7 @@ components:
type: string
type:
type: string
enum: [text, code, render, file, image, search, relation-map, book, note-map, mermaid]
enum: [text, code, render, file, image, search, relation-map, book, note-map, mermaid, web-view, shortcut]
mime:
type: string
isProtected:

View File

@ -19,7 +19,8 @@ const NOTE_TYPE_ICONS = {
"note-map": "bx bx-map-alt",
"mermaid": "bx bx-selection",
"canvas": "bx bx-pen",
"web-view": "bx bx-globe-alt"
"web-view": "bx bx-globe-alt",
"shortcut": "bx bx-up-arrow-circle"
};
/**

View File

@ -25,7 +25,7 @@ export default class ShortcutContextMenu {
async getMenuItems() {
const note = await froca.getNote(this.node.data.noteId);
const branch = froca.getBranch(this.node.data.branchId);
const isLbRoot = note.noteId === 'lb_root';
const isVisibleRoot = note.noteId === 'lb_visibleshortcuts';
const isAvailableRoot = note.noteId === 'lb_availableshortcuts';
const isVisibleItem = this.node.getParent().data.noteId === 'lb_visibleshortcuts';
@ -38,7 +38,7 @@ export default class ShortcutContextMenu {
(isVisibleRoot || isAvailableRoot) ? { title: 'Add spacer', command: 'addSpacerShortcut', uiIcon: "bx bx-plus" } : null,
(isVisibleRoot || isAvailableRoot) ? { title: "----" } : null,
{ title: 'Delete <kbd data-command="deleteNotes"></kbd>', command: "deleteNotes", uiIcon: "bx bx-trash",
enabled: isItem },
enabled: !isLbRoot}, // allow everything to be deleted as a form of a reset. Root can't be deleted because it's a hoisted note
{ 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,
@ -47,46 +47,12 @@ export default class ShortcutContextMenu {
].filter(row => row !== null);
}
async selectMenuItemHandler({command, type, templateNoteId}) {
const notePath = treeService.getNotePath(this.node);
if (command === 'openInTab') {
appContext.tabManager.openTabWithNoteWithHoisting(notePath);
}
else if (command === "insertNoteAfter") {
const parentNotePath = treeService.getNotePath(this.node.getParent());
const isProtected = await treeService.getParentProtectedStatus(this.node);
noteCreateService.createNote(parentNotePath, {
target: 'after',
targetBranchId: this.node.data.branchId,
type: type,
isProtected: isProtected,
templateNoteId: templateNoteId
});
}
else if (command === "insertChildNote") {
const parentNotePath = treeService.getNotePath(this.node);
noteCreateService.createNote(parentNotePath, {
type: type,
isProtected: this.node.data.isProtected,
templateNoteId: templateNoteId
});
}
else if (command === 'openNoteInSplit') {
const subContexts = appContext.tabManager.getActiveContext().getSubContexts();
const {ntxId} = subContexts[subContexts.length - 1];
this.treeWidget.triggerCommand("openNewNoteSplit", {ntxId, notePath});
}
else {
this.treeWidget.triggerCommand(command, {
node: this.node,
notePath: notePath,
selectedOrActiveBranchIds: this.treeWidget.getSelectedOrActiveBranchIds(this.node),
selectedOrActiveNoteIds: this.treeWidget.getSelectedOrActiveNoteIds(this.node)
});
}
async selectMenuItemHandler({command}) {
this.treeWidget.triggerCommand(command, {
node: this.node,
notePath: treeService.getNotePath(this.node),
selectedOrActiveBranchIds: this.treeWidget.getSelectedOrActiveBranchIds(this.node),
selectedOrActiveNoteIds: this.treeWidget.getSelectedOrActiveNoteIds(this.node)
});
}
}

View File

@ -22,7 +22,13 @@ export default class ShortcutContainer extends FlexContainer {
async load() {
this.children = [];
const visibleShortcutsRoot = await froca.getNote('lb_visibleshortcuts');
const visibleShortcutsRoot = await froca.getNote('lb_visibleshortcuts', true);
if (!visibleShortcutsRoot) {
console.log("Visible shortcuts root note doesn't exist.");
return;
}
for (const shortcut of await visibleShortcutsRoot.getChildNotes()) {
if (shortcut.getLabelValue("command")) {

View File

@ -25,6 +25,7 @@ import ReadOnlyCodeTypeWidget from "./type_widgets/read_only_code.js";
import NoneTypeWidget from "./type_widgets/none.js";
import NoteMapTypeWidget from "./type_widgets/note_map.js";
import WebViewTypeWidget from "./type_widgets/web_view.js";
import DocTypeWidget from "./type_widgets/doc.js";
const TPL = `
<div class="note-detail">
@ -57,7 +58,8 @@ const typeWidgetClasses = {
'protected-session': ProtectedSessionTypeWidget,
'book': BookTypeWidget,
'note-map': NoteMapTypeWidget,
'web-view': WebViewTypeWidget
'web-view': WebViewTypeWidget,
'doc': DocTypeWidget
};
export default class NoteDetailWidget extends NoteContextAwareWidget {
@ -195,6 +197,10 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
type = 'editable-code';
}
if (type === 'shortcut') {
type = 'doc';
}
if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) {
type = 'protected-session';
}

View File

@ -72,7 +72,8 @@ export default class NoteTitleWidget extends NoteContextAwareWidget {
async refreshWithNote(note) {
this.$noteTitle.val(note.title);
this.$noteTitle.prop("readonly", note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable());
this.$noteTitle.prop("readonly", (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable())
|| ["lb_root", "lb_availableshortcuts", "lb_visibleshortcuts"].includes(note.noteId));
this.setProtectedStatus(note);
}

View File

@ -8,6 +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: "text", mime: "text/html", title: "Text", selectable: true },
{ type: "relation-map", mime: "application/json", title: "Relation Map", selectable: true },

View File

@ -0,0 +1,13 @@
import TypeWidget from "./type_widget.js";
const TPL = `<div class="note-detail-doc note-detail-printable">Z</div>`;
export default class DocTypeWidget extends TypeWidget {
static getType() { return "doc"; }
doRender() {
this.$widget = $(TPL);
super.doRender();
}
}

View File

@ -4,6 +4,8 @@ const treeService = require('./tree');
const noteService = require('./notes');
const becca = require('../becca/becca');
const Attribute = require('../becca/entities/attribute');
const debounce = require('debounce');
const specialNotesService = require("./special_notes");
function runAttachedRelations(note, relationName, originEntity) {
if (!note) {
@ -160,6 +162,8 @@ eventService.subscribe(eventService.ENTITY_CHANGED, ({ entityName, entity }) =>
});
});
const debouncedCreateMissingSpecialNotes = debounce(() => specialNotesService.createMissingSpecialNotes(), 300);
eventService.subscribe(eventService.ENTITY_DELETED, ({ entityName, entity }) => {
processInverseRelations(entityName, entity, (definition, note, targetNote) => {
// if one inverse attribute is deleted then the other should be deleted as well
@ -175,6 +179,13 @@ eventService.subscribe(eventService.ENTITY_DELETED, ({ entityName, entity }) =>
if (entityName === 'branches') {
runAttachedRelations(entity.getNote(), 'runOnBranchDeletion', entity);
}
if (entityName === 'notes') {
if (entity.noteId.startsWith("lb_")) {
// if user deletes shortcuts, restore them immediately
debouncedCreateMissingSpecialNotes();
}
}
});
module.exports = {

View File

@ -10,5 +10,6 @@ module.exports = [
'note-map',
'mermaid',
'canvas',
'web-view'
'web-view',
'shortcut'
];

View File

@ -244,7 +244,7 @@ function getLaunchBarRoot() {
branchId: 'lb_root',
noteId: 'lb_root',
title: 'Launch bar',
type: 'text',
type: 'shortcut',
content: '',
parentNoteId: getHiddenRoot().noteId
}).note;
@ -263,7 +263,7 @@ function getLaunchBarAvailableShortcutsRoot() {
branchId: 'lb_availableshortcuts',
noteId: 'lb_availableshortcuts',
title: 'Available shortcuts',
type: 'text',
type: 'shortcut',
content: '',
parentNoteId: getLaunchBarRoot().noteId
}).note;
@ -288,7 +288,7 @@ function getLaunchBarVisibleShortcutsRoot() {
branchId: 'lb_visibleshortcuts',
noteId: 'lb_visibleshortcuts',
title: 'Visible shortcuts',
type: 'text',
type: 'shortcut',
content: '',
parentNoteId: getLaunchBarRoot().noteId
}).note;
@ -347,7 +347,7 @@ function createMissingSpecialNotes() {
branchId: shortcut.id,
noteId: shortcut.id,
title: shortcut.title,
type: 'text',
type: 'shortcut',
content: '',
parentNoteId: parentNoteId
}).note;