mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
clean up tree service WIP
This commit is contained in:
parent
d5ae3802d1
commit
b63ecba695
@ -135,7 +135,7 @@ macInit.init();
|
|||||||
|
|
||||||
searchNotesService.init(); // should be in front of treeService since that one manipulates address bar hash
|
searchNotesService.init(); // should be in front of treeService since that one manipulates address bar hash
|
||||||
|
|
||||||
appContext.showWidgets();
|
appContext.start();
|
||||||
|
|
||||||
noteTooltipService.setupGlobalTooltip();
|
noteTooltipService.setupGlobalTooltip();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import treeService from '../services/tree.js';
|
|
||||||
import searchNotesService from '../services/search_notes.js';
|
import searchNotesService from '../services/search_notes.js';
|
||||||
import noteAutocompleteService from '../services/note_autocomplete.js';
|
import noteAutocompleteService from '../services/note_autocomplete.js';
|
||||||
import utils from "../services/utils.js";
|
import utils from "../services/utils.js";
|
||||||
|
import appContext from "../services/app_context.js";
|
||||||
|
|
||||||
const $dialog = $("#jump-to-note-dialog");
|
const $dialog = $("#jump-to-note-dialog");
|
||||||
const $autoComplete = $("#jump-to-note-autocomplete");
|
const $autoComplete = $("#jump-to-note-autocomplete");
|
||||||
@ -22,7 +22,7 @@ export async function showDialog() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
treeService.activateNote(suggestion.path);
|
appContext.getActiveTabContext().setNote(suggestion.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
noteAutocompleteService.showRecentNotes($autoComplete);
|
noteAutocompleteService.showRecentNotes($autoComplete);
|
||||||
|
@ -3,6 +3,7 @@ import utils from '../services/utils.js';
|
|||||||
import server from '../services/server.js';
|
import server from '../services/server.js';
|
||||||
import treeService from "../services/tree.js";
|
import treeService from "../services/tree.js";
|
||||||
import treeCache from "../services/tree_cache.js";
|
import treeCache from "../services/tree_cache.js";
|
||||||
|
import appContext from "../services/app_context.js";
|
||||||
|
|
||||||
const $dialog = $("#recent-changes-dialog");
|
const $dialog = $("#recent-changes-dialog");
|
||||||
const $content = $("#recent-changes-content");
|
const $content = $("#recent-changes-content");
|
||||||
@ -54,7 +55,7 @@ export async function showDialog() {
|
|||||||
|
|
||||||
await treeCache.reloadNotes([change.noteId]);
|
await treeCache.reloadNotes([change.noteId]);
|
||||||
|
|
||||||
treeService.activateNote(change.noteId);
|
appContext.getActiveTabContext().setNote(change.noteId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -42,8 +42,13 @@ class AppContext {
|
|||||||
this.activeTabId = null;
|
this.activeTabId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
showWidgets() {
|
start() {
|
||||||
|
this.showWidgets();
|
||||||
|
|
||||||
|
bundleService.executeStartupBundles();
|
||||||
|
}
|
||||||
|
|
||||||
|
showWidgets() {
|
||||||
this.tabRow = new TabRowWidget(this);
|
this.tabRow = new TabRowWidget(this);
|
||||||
|
|
||||||
const topPaneWidgets = [
|
const topPaneWidgets = [
|
||||||
@ -247,18 +252,22 @@ class AppContext {
|
|||||||
await tabContext.setNote(noteId);
|
await tabContext.setNote(noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async filterTabs(noteId) {
|
hoistedNoteChangedListener({hoistedNoteId}) {
|
||||||
|
if (hoistedNoteId === 'root') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const tc of this.tabContexts) {
|
for (const tc of this.tabContexts) {
|
||||||
if (tc.notePath && !tc.notePath.split("/").includes(noteId)) {
|
if (tc.notePath && !tc.notePath.split("/").includes(hoistedNoteId)) {
|
||||||
this.tabRow.removeTab(tc.tabId);
|
this.tabRow.removeTab(tc.tabId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.tabContexts.length === 0) {
|
if (this.tabContexts.length === 0) {
|
||||||
this.openAndActivateEmptyTab()
|
this.openAndActivateEmptyTab();
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.saveOpenTabs();
|
this.saveOpenTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveOpenTabs() {
|
async saveOpenTabs() {
|
||||||
|
@ -38,7 +38,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
|
|||||||
this.tabContext = tabContext;
|
this.tabContext = tabContext;
|
||||||
|
|
||||||
/** @property {CollapsibleWidget} */
|
/** @property {CollapsibleWidget} */
|
||||||
this.StandardWidget = CollapsibleWidget;
|
this.CollapsibleWidget = CollapsibleWidget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates note in the tree and in the note detail.
|
* Activates note in the tree and in the note detail.
|
||||||
@ -47,14 +47,8 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
|
|||||||
* @param {string} notePath (or noteId)
|
* @param {string} notePath (or noteId)
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
this.activateNote = async (notePath, noteLoadedListener) => {
|
this.activateNote = async notePath => {
|
||||||
await treeService.activateNote(notePath, async () => {
|
await appContext.getActiveTabContext().setNote(notePath);
|
||||||
await appContext.getMainNoteTree().scrollToActiveNoteListener();
|
|
||||||
|
|
||||||
if (noteLoadedListener) {
|
|
||||||
noteLoadedListener();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +60,8 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
|
|||||||
this.activateNewNote = async notePath => {
|
this.activateNewNote = async notePath => {
|
||||||
await ws.waitForMaxKnownSyncId();
|
await ws.waitForMaxKnownSyncId();
|
||||||
|
|
||||||
await treeService.activateNote(notePath, () => appContext.trigger('focusAndSelectTitle'));
|
await appContext.getActiveTabContext().setNote(notePath);
|
||||||
|
appContext.trigger('focusAndSelectTitle');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import optionsService from './options.js';
|
import optionsService from './options.js';
|
||||||
import server from "./server.js";
|
import server from "./server.js";
|
||||||
import appContext from "./app_context.js";
|
import appContext from "./app_context.js";
|
||||||
|
import treeService from "./tree.js";
|
||||||
|
|
||||||
let hoistedNoteId = 'root';
|
let hoistedNoteId = 'root';
|
||||||
|
|
||||||
@ -19,15 +20,11 @@ async function getHoistedNoteId() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function setHoistedNoteId(noteId) {
|
async function setHoistedNoteId(noteId) {
|
||||||
if (noteId !== 'root') {
|
|
||||||
await appContext.filterTabs(noteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
hoistedNoteId = noteId;
|
hoistedNoteId = noteId;
|
||||||
|
|
||||||
await server.put('options/hoistedNoteId/' + noteId);
|
await server.put('options/hoistedNoteId/' + noteId);
|
||||||
|
|
||||||
appContext.trigger('hoistedNoteChanged');
|
appContext.trigger('hoistedNoteChanged', {hoistedNoteId});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unhoist() {
|
async function unhoist() {
|
||||||
@ -44,11 +41,38 @@ async function isRootNode(node) {
|
|||||||
|| node.data.noteId === await getHoistedNoteId();
|
|| node.data.noteId === await getHoistedNoteId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkNoteAccess(notePath) {
|
||||||
|
// notePath argument can contain only noteId which is not good when hoisted since
|
||||||
|
// then we need to check the whole note path
|
||||||
|
const runNotePath = await treeService.getRunPath(notePath);
|
||||||
|
|
||||||
|
if (!runNotePath) {
|
||||||
|
console.log("Cannot activate " + notePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hoistedNoteId = await getHoistedNoteId();
|
||||||
|
|
||||||
|
if (hoistedNoteId !== 'root' && !runNotePath.includes(hoistedNoteId)) {
|
||||||
|
const confirmDialog = await import('../dialogs/confirm.js');
|
||||||
|
|
||||||
|
if (!await confirmDialog.confirm("Requested note is outside of hoisted note subtree and you must unhoist to access the note. Do you want to proceed with unhoisting?")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unhoist so we can activate the note
|
||||||
|
await unhoist();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getHoistedNoteId,
|
getHoistedNoteId,
|
||||||
getHoistedNoteNoPromise,
|
getHoistedNoteNoPromise,
|
||||||
setHoistedNoteId,
|
setHoistedNoteId,
|
||||||
unhoist,
|
unhoist,
|
||||||
isTopLevelNode,
|
isTopLevelNode,
|
||||||
isRootNode
|
isRootNode,
|
||||||
|
checkNoteAccess
|
||||||
}
|
}
|
@ -67,9 +67,7 @@ ws.subscribeToMessages(async message => {
|
|||||||
appContext.trigger('reloadNotes', {noteIds: [message.result.parentNoteId]});
|
appContext.trigger('reloadNotes', {noteIds: [message.result.parentNoteId]});
|
||||||
|
|
||||||
if (message.result.importedNoteId) {
|
if (message.result.importedNoteId) {
|
||||||
const node = await treeService.activateNote(message.result.importedNoteId);
|
await appContext.getActiveTabContext.setNote(message.result.importedNoteId);
|
||||||
|
|
||||||
node.setExpanded(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -26,7 +26,7 @@ server.get('keyboard-shortcuts-for-notes').then(shortcutForNotes => {
|
|||||||
utils.bindGlobalShortcut(shortcut, async () => {
|
utils.bindGlobalShortcut(shortcut, async () => {
|
||||||
const treeService = (await import("./tree.js")).default;
|
const treeService = (await import("./tree.js")).default;
|
||||||
|
|
||||||
treeService.activateNote(shortcutForNotes[shortcut]);
|
appContext.getActiveTabContext().setNote(shortcutForNotes[shortcut]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -79,8 +79,6 @@ async function protectNoteAndSendToServer() {
|
|||||||
note.isProtected = true;
|
note.isProtected = true;
|
||||||
|
|
||||||
await appContext.getActiveTabContext().saveNote();
|
await appContext.getActiveTabContext().saveNote();
|
||||||
|
|
||||||
treeService.setProtected(note.noteId, note.isProtected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unprotectNoteAndSendToServer() {
|
async function unprotectNoteAndSendToServer() {
|
||||||
@ -104,8 +102,6 @@ async function unprotectNoteAndSendToServer() {
|
|||||||
activeNote.isProtected = false;
|
activeNote.isProtected = false;
|
||||||
|
|
||||||
await appContext.getActiveTabContext().saveNote();
|
await appContext.getActiveTabContext().saveNote();
|
||||||
|
|
||||||
treeService.setProtected(activeNote.noteId, activeNote.isProtected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function protectSubtree(noteId, protect) {
|
async function protectSubtree(noteId, protect) {
|
||||||
|
@ -7,6 +7,7 @@ import appContext from "./app_context.js";
|
|||||||
import treeService from "./tree.js";
|
import treeService from "./tree.js";
|
||||||
import Component from "../widgets/component.js";
|
import Component from "../widgets/component.js";
|
||||||
import treeCache from "./tree_cache.js";
|
import treeCache from "./tree_cache.js";
|
||||||
|
import hoistedNoteService from "./hoisted_note.js";
|
||||||
|
|
||||||
let showSidebarInNewTab = true;
|
let showSidebarInNewTab = true;
|
||||||
|
|
||||||
@ -42,6 +43,10 @@ class TabContext extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (await hoistedNoteService.checkNoteAccess(notePath) === false) {
|
||||||
|
return; // note is outside of hoisted subtree and user chose not to unhoist
|
||||||
|
}
|
||||||
|
|
||||||
await this.trigger('beforeNoteSwitch', {tabId: this.tabId}, true);
|
await this.trigger('beforeNoteSwitch', {tabId: this.tabId}, true);
|
||||||
|
|
||||||
this.notePath = notePath;
|
this.notePath = notePath;
|
||||||
@ -73,6 +78,7 @@ class TabContext extends Component {
|
|||||||
tabId: this.tabId,
|
tabId: this.tabId,
|
||||||
notePath: this.notePath
|
notePath: this.notePath
|
||||||
});
|
});
|
||||||
|
|
||||||
this.trigger('openTabsChanged');
|
this.trigger('openTabsChanged');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,73 +10,6 @@ import optionsService from "../services/options.js";
|
|||||||
import bundle from "./bundle.js";
|
import bundle from "./bundle.js";
|
||||||
import appContext from "./app_context.js";
|
import appContext from "./app_context.js";
|
||||||
|
|
||||||
let setFrontendAsLoaded;
|
|
||||||
const frontendLoaded = new Promise(resolve => { setFrontendAsLoaded = resolve; });
|
|
||||||
|
|
||||||
async function setPrefix(branchId, prefix) {
|
|
||||||
utils.assertArguments(branchId);
|
|
||||||
|
|
||||||
const branch = treeCache.getBranch(branchId);
|
|
||||||
|
|
||||||
branch.prefix = prefix;
|
|
||||||
|
|
||||||
for (const node of await appContext.getMainNoteTree().getNodesByBranchId(branchId)) {
|
|
||||||
await setNodeTitleWithPrefix(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setNodeTitleWithPrefix(node) {
|
|
||||||
const noteTitle = await getNoteTitle(node.data.noteId);
|
|
||||||
const branch = treeCache.getBranch(node.data.branchId);
|
|
||||||
|
|
||||||
const prefix = branch.prefix;
|
|
||||||
|
|
||||||
const title = (prefix ? (prefix + " - ") : "") + noteTitle;
|
|
||||||
|
|
||||||
node.setTitle(utils.escapeHtml(title));
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: unused?
|
|
||||||
/** @return {FancytreeNode} */
|
|
||||||
async function activateNote(notePath, noteLoadedListener) {
|
|
||||||
utils.assertArguments(notePath);
|
|
||||||
|
|
||||||
// notePath argument can contain only noteId which is not good when hoisted since
|
|
||||||
// then we need to check the whole note path
|
|
||||||
const runNotePath = await getRunPath(notePath);
|
|
||||||
|
|
||||||
if (!runNotePath) {
|
|
||||||
console.log("Cannot activate " + notePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
|
|
||||||
|
|
||||||
if (hoistedNoteId !== 'root' && !runNotePath.includes(hoistedNoteId)) {
|
|
||||||
const confirmDialog = await import('../dialogs/confirm.js');
|
|
||||||
|
|
||||||
if (!await confirmDialog.confirm("Requested note is outside of hoisted note subtree. Do you want to unhoist?")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unhoist so we can activate the note
|
|
||||||
await hoistedNoteService.unhoist();
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
const node = await appContext.getMainNoteTree().expandToNote(notePath);
|
|
||||||
|
|
||||||
if (noteLoadedListener) {
|
|
||||||
// FIXME
|
|
||||||
noteDetailService.addDetailLoadedListener(node.data.noteId, noteLoadedListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
await node.setActive(true);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts notePath which might or might not be valid and returns an existing path as close to the original
|
* Accepts notePath which might or might not be valid and returns an existing path as close to the original
|
||||||
* notePath as possible.
|
* notePath as possible.
|
||||||
@ -274,8 +207,6 @@ async function treeInitialized() {
|
|||||||
// previous opening triggered task to save tab changes but these are bogus changes (this is init)
|
// previous opening triggered task to save tab changes but these are bogus changes (this is init)
|
||||||
// so we'll cancel it
|
// so we'll cancel it
|
||||||
appContext.clearOpenTabsTask();
|
appContext.clearOpenTabsTask();
|
||||||
|
|
||||||
setFrontendAsLoaded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNotePathInAddress() {
|
function isNotePathInAddress() {
|
||||||
@ -292,13 +223,6 @@ function getHashValueFromAddress() {
|
|||||||
return str.split("-");
|
return str.split("-");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setProtected(noteId, isProtected) {
|
|
||||||
appContext.getMainNoteTree().getNodesByNoteId(noteId).map(node => {
|
|
||||||
node.data.isProtected = isProtected;
|
|
||||||
node.toggleClass("protected", isProtected);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createNewTopLevelNote() {
|
async function createNewTopLevelNote() {
|
||||||
const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
|
const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
|
||||||
|
|
||||||
@ -580,12 +504,7 @@ async function getNotePathTitle(notePath) {
|
|||||||
return titlePath.join(' / ');
|
return titlePath.join(' / ');
|
||||||
}
|
}
|
||||||
|
|
||||||
frontendLoaded.then(bundle.executeStartupBundles);
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setProtected,
|
|
||||||
activateNote,
|
|
||||||
setPrefix,
|
|
||||||
createNote,
|
createNote,
|
||||||
sortAlphabetically,
|
sortAlphabetically,
|
||||||
treeInitialized,
|
treeInitialized,
|
||||||
@ -594,7 +513,6 @@ export default {
|
|||||||
createNewTopLevelNote,
|
createNewTopLevelNote,
|
||||||
duplicateNote,
|
duplicateNote,
|
||||||
getRunPath,
|
getRunPath,
|
||||||
setNodeTitleWithPrefix,
|
|
||||||
getParentProtectedStatus,
|
getParentProtectedStatus,
|
||||||
getNotePath,
|
getNotePath,
|
||||||
getNoteIdFromNotePath,
|
getNoteIdFromNotePath,
|
||||||
|
@ -4,6 +4,7 @@ import utils from "../services/utils.js";
|
|||||||
import dateNoteService from "../services/date_notes.js";
|
import dateNoteService from "../services/date_notes.js";
|
||||||
import treeService from "../services/tree.js";
|
import treeService from "../services/tree.js";
|
||||||
import server from "../services/server.js";
|
import server from "../services/server.js";
|
||||||
|
import appContext from "../services/app_context.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="calendar-widget">
|
<div class="calendar-widget">
|
||||||
@ -58,7 +59,7 @@ export default class CalendarWidget extends CollapsibleWidget {
|
|||||||
const note = await dateNoteService.getDateNote(date);
|
const note = await dateNoteService.getDateNote(date);
|
||||||
|
|
||||||
if (note) {
|
if (note) {
|
||||||
treeService.activateNote(note.noteId);
|
appContext.getActiveTabContext().setNote(note.noteId);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
alert("Cannot find day note");
|
alert("Cannot find day note");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import noteAutocompleteService from '../../services/note_autocomplete.js';
|
import noteAutocompleteService from '../../services/note_autocomplete.js';
|
||||||
import treeService from "../../services/tree.js";
|
import treeService from "../../services/tree.js";
|
||||||
import TypeWidget from "./type_widget.js";
|
import TypeWidget from "./type_widget.js";
|
||||||
|
import appContext from "../../services/app_context.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="note-detail-empty note-detail-printable">
|
<div class="note-detail-empty note-detail-printable">
|
||||||
@ -27,7 +28,7 @@ export default class EmptyTypeWidget extends TypeWidget {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
treeService.activateNote(suggestion.path);
|
appContext.getActiveTabContext().setNote(suggestion.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
noteAutocompleteService.showRecentNotes(this.$autoComplete);
|
noteAutocompleteService.showRecentNotes(this.$autoComplete);
|
||||||
|
@ -4,6 +4,7 @@ import noteAutocompleteService from '../../services/note_autocomplete.js';
|
|||||||
import mimeTypesService from '../../services/mime_types.js';
|
import mimeTypesService from '../../services/mime_types.js';
|
||||||
import TypeWidget from "./type_widget.js";
|
import TypeWidget from "./type_widget.js";
|
||||||
import utils from "../../services/utils.js";
|
import utils from "../../services/utils.js";
|
||||||
|
import appContext from "../../services/app_context.js";
|
||||||
|
|
||||||
const ENABLE_INSPECTOR = false;
|
const ENABLE_INSPECTOR = false;
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ export default class TextTypeWidget extends TypeWidget {
|
|||||||
if (match) {
|
if (match) {
|
||||||
const noteId = match[1];
|
const noteId = match[1];
|
||||||
|
|
||||||
treeService.activateNote(noteId);
|
appContext.getActiveTabContext().setNote(noteId);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
window.open(src, '_blank');
|
window.open(src, '_blank');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user