mirror of
https://github.com/zadam/trilium.git
synced 2025-01-16 20:21:43 +08:00
refactorings of note creation code
This commit is contained in:
parent
b63ecba695
commit
9f62490a75
5 changed files with 91 additions and 163 deletions
|
@ -30,6 +30,9 @@ import bundleService from "./bundle.js";
|
|||
import DialogEventComponent from "./dialog_events.js";
|
||||
import Entrypoints from "./entrypoints.js";
|
||||
import CalendarWidget from "../widgets/calendar.js";
|
||||
import optionsService from "./options.js";
|
||||
import utils from "./utils.js";
|
||||
import treeService from "./tree.js";
|
||||
|
||||
class AppContext {
|
||||
constructor() {
|
||||
|
@ -45,9 +48,84 @@ class AppContext {
|
|||
start() {
|
||||
this.showWidgets();
|
||||
|
||||
this.loadTabs();
|
||||
|
||||
bundleService.executeStartupBundles();
|
||||
}
|
||||
|
||||
async loadTabs() {
|
||||
const options = await optionsService.waitForOptions();
|
||||
|
||||
const openTabs = options.getJson('openTabs') || [];
|
||||
|
||||
await treeCache.initializedPromise;
|
||||
|
||||
// if there's notePath in the URL, make sure it's open and active
|
||||
// (useful, among others, for opening clipped notes from clipper)
|
||||
if (window.location.hash) {
|
||||
const notePath = window.location.hash.substr(1);
|
||||
const noteId = treeService.getNoteIdFromNotePath(notePath);
|
||||
|
||||
if (noteId && await treeCache.noteExists(noteId)) {
|
||||
for (const tab of openTabs) {
|
||||
tab.active = false;
|
||||
}
|
||||
|
||||
const foundTab = openTabs.find(tab => noteId === treeService.getNoteIdFromNotePath(tab.notePath));
|
||||
|
||||
if (foundTab) {
|
||||
foundTab.active = true;
|
||||
}
|
||||
else {
|
||||
openTabs.push({
|
||||
notePath: notePath,
|
||||
active: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let filteredTabs = [];
|
||||
|
||||
for (const openTab of openTabs) {
|
||||
const noteId = treeService.getNoteIdFromNotePath(openTab.notePath);
|
||||
|
||||
if (await treeCache.noteExists(noteId)) {
|
||||
// note doesn't exist so don't try to open tab for it
|
||||
filteredTabs.push(openTab);
|
||||
}
|
||||
}
|
||||
|
||||
if (utils.isMobile()) {
|
||||
// mobile frontend doesn't have tabs so show only the active tab
|
||||
filteredTabs = filteredTabs.filter(tab => tab.active);
|
||||
}
|
||||
|
||||
if (filteredTabs.length === 0) {
|
||||
filteredTabs.push({
|
||||
notePath: 'root',
|
||||
active: true
|
||||
});
|
||||
}
|
||||
|
||||
if (!filteredTabs.find(tab => tab.active)) {
|
||||
filteredTabs[0].active = true;
|
||||
}
|
||||
|
||||
for (const tab of filteredTabs) {
|
||||
const tabContext = this.openEmptyTab();
|
||||
tabContext.setNote(tab.notePath);
|
||||
|
||||
if (tab.active) {
|
||||
this.activateTab(tabContext.tabId);
|
||||
}
|
||||
}
|
||||
|
||||
// previous opening triggered task to save tab changes but these are bogus changes (this is init)
|
||||
// so we'll cancel it
|
||||
this.clearOpenTabsTask();
|
||||
}
|
||||
|
||||
showWidgets() {
|
||||
this.tabRow = new TabRowWidget(this);
|
||||
|
||||
|
|
|
@ -133,82 +133,6 @@ async function getSomeNotePath(note) {
|
|||
return path.reverse().join('/');
|
||||
}
|
||||
|
||||
async function treeInitialized() {
|
||||
if (appContext.getTabContexts().length > 0) {
|
||||
// this is just tree reload - tabs are already in place
|
||||
return;
|
||||
}
|
||||
|
||||
const options = await optionsService.waitForOptions();
|
||||
|
||||
const openTabs = options.getJson('openTabs') || [];
|
||||
|
||||
// if there's notePath in the URL, make sure it's open and active
|
||||
// (useful, among others, for opening clipped notes from clipper)
|
||||
if (location.hash) {
|
||||
const notePath = location.hash.substr(1);
|
||||
const noteId = getNoteIdFromNotePath(notePath);
|
||||
|
||||
if (noteId && await treeCache.noteExists(noteId)) {
|
||||
for (const tab of openTabs) {
|
||||
tab.active = false;
|
||||
}
|
||||
|
||||
const foundTab = openTabs.find(tab => noteId === getNoteIdFromNotePath(tab.notePath));
|
||||
|
||||
if (foundTab) {
|
||||
foundTab.active = true;
|
||||
}
|
||||
else {
|
||||
openTabs.push({
|
||||
notePath: notePath,
|
||||
active: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let filteredTabs = [];
|
||||
|
||||
for (const openTab of openTabs) {
|
||||
const noteId = getNoteIdFromNotePath(openTab.notePath);
|
||||
|
||||
if (await treeCache.noteExists(noteId)) {
|
||||
// note doesn't exist so don't try to open tab for it
|
||||
filteredTabs.push(openTab);
|
||||
}
|
||||
}
|
||||
|
||||
if (utils.isMobile()) {
|
||||
// mobile frontend doesn't have tabs so show only the active tab
|
||||
filteredTabs = filteredTabs.filter(tab => tab.active);
|
||||
}
|
||||
|
||||
if (filteredTabs.length === 0) {
|
||||
filteredTabs.push({
|
||||
notePath: 'root',
|
||||
active: true
|
||||
});
|
||||
}
|
||||
|
||||
if (!filteredTabs.find(tab => tab.active)) {
|
||||
filteredTabs[0].active = true;
|
||||
}
|
||||
|
||||
for (const tab of filteredTabs) {
|
||||
const tabContext = appContext.openEmptyTab();
|
||||
tabContext.setNote(tab.notePath);
|
||||
|
||||
if (tab.active) {
|
||||
appContext.activateTab(tabContext.tabId);
|
||||
}
|
||||
}
|
||||
|
||||
// previous opening triggered task to save tab changes but these are bogus changes (this is init)
|
||||
// so we'll cancel it
|
||||
appContext.clearOpenTabsTask();
|
||||
}
|
||||
|
||||
function isNotePathInAddress() {
|
||||
const [notePath, tabId] = getHashValueFromAddress();
|
||||
|
||||
|
@ -264,72 +188,9 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) {
|
|||
window.cutToNote.removeSelection();
|
||||
}
|
||||
|
||||
noteDetailService.addDetailLoadedListener(note.noteId, () => appContext.trigger('focusAndSelectTitle'));
|
||||
|
||||
const noteEntity = await treeCache.getNote(note.noteId);
|
||||
const branchEntity = treeCache.getBranch(branch.branchId);
|
||||
|
||||
let newNodeData = {
|
||||
title: newNoteName,
|
||||
noteId: branchEntity.noteId,
|
||||
parentNoteId: parentNoteId,
|
||||
refKey: branchEntity.noteId,
|
||||
branchId: branchEntity.branchId,
|
||||
isProtected: extraOptions.isProtected,
|
||||
type: noteEntity.type,
|
||||
extraClasses: await treeBuilder.getExtraClasses(noteEntity),
|
||||
icon: await treeBuilder.getIcon(noteEntity),
|
||||
folder: extraOptions.type === 'search',
|
||||
lazy: true,
|
||||
key: utils.randomString(12) // this should prevent some "duplicate key" errors
|
||||
};
|
||||
|
||||
/** @var {FancytreeNode} */
|
||||
let newNode;
|
||||
|
||||
if (target === 'after') {
|
||||
newNode = node.appendSibling(newNodeData);
|
||||
}
|
||||
else if (target === 'into') {
|
||||
if (!node.getChildren() && node.isFolder()) {
|
||||
// folder is not loaded - load will bring up the note since it was already put into cache
|
||||
await node.load(true);
|
||||
|
||||
await node.setExpanded();
|
||||
}
|
||||
else {
|
||||
node.addChildren(newNodeData);
|
||||
}
|
||||
|
||||
newNode = node.getLastChild();
|
||||
|
||||
const parentNoteEntity = await treeCache.getNote(node.data.noteId);
|
||||
|
||||
node.folder = true;
|
||||
node.icon = await treeBuilder.getIcon(parentNoteEntity); // icon might change into folder
|
||||
node.renderTitle();
|
||||
}
|
||||
else {
|
||||
toastService.throwError("Unrecognized target: " + target);
|
||||
}
|
||||
|
||||
if (extraOptions.activate) {
|
||||
await newNode.setActive(true);
|
||||
}
|
||||
|
||||
// need to refresh because original doesn't have methods like .getParent()
|
||||
newNodeData = appContext.getMainNoteTree().getNodesByNoteId(branchEntity.noteId)[0];
|
||||
|
||||
// following for cycle will make sure that also clones of a parent are refreshed
|
||||
for (const newParentNode of appContext.getMainNoteTree().getNodesByNoteId(parentNoteId)) {
|
||||
if (newParentNode.key === newNodeData.getParent().key) {
|
||||
// we've added a note into this one so no need to refresh
|
||||
continue;
|
||||
}
|
||||
|
||||
await newParentNode.load(true); // force reload to show up new note
|
||||
|
||||
await appContext.getMainNoteTree().updateNode(newParentNode);
|
||||
const activeTabContext = appContext.getActiveTabContext();
|
||||
activeTabContext.setNote(note.noteId);
|
||||
}
|
||||
|
||||
return {note, branch};
|
||||
|
@ -353,15 +214,10 @@ function parseSelectedHtml(selectedHtml) {
|
|||
|
||||
async function sortAlphabetically(noteId) {
|
||||
await server.put('notes/' + noteId + '/sort');
|
||||
|
||||
await reload();
|
||||
}
|
||||
|
||||
ws.subscribeToMessages(message => {
|
||||
if (message.type === 'refresh-tree') {
|
||||
reload();
|
||||
}
|
||||
else if (message.type === 'open-note') {
|
||||
if (message.type === 'open-note') {
|
||||
appContext.activateOrOpenNote(message.noteId);
|
||||
|
||||
if (utils.isElectron()) {
|
||||
|
@ -507,7 +363,6 @@ async function getNotePathTitle(notePath) {
|
|||
export default {
|
||||
createNote,
|
||||
sortAlphabetically,
|
||||
treeInitialized,
|
||||
resolveNotePath,
|
||||
getSomeNotePath,
|
||||
createNewTopLevelNote,
|
||||
|
|
|
@ -110,7 +110,6 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
},
|
||||
expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true),
|
||||
collapse: (event, data) => this.setExpandedToServer(data.node.data.branchId, false),
|
||||
init: (event, data) => treeService.treeInitialized(),
|
||||
hotkeys: {
|
||||
keydown: await treeKeyBindingService.getKeyboardBindings(this)
|
||||
},
|
||||
|
@ -386,7 +385,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
}
|
||||
|
||||
/** @return {FancytreeNode[]} */
|
||||
async getNodesByBranchId(branchId) {
|
||||
getNodesByBranchId(branchId) {
|
||||
utils.assertArguments(branchId);
|
||||
|
||||
const branch = treeCache.getBranch(branchId);
|
||||
|
@ -464,7 +463,9 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
newActive = node.getParent();
|
||||
}
|
||||
|
||||
await newActive.setActive(true, {noEvents: true});
|
||||
const notePath = await treeService.getNotePath(newActive);
|
||||
|
||||
appContext.getActiveTabContext().setNote(notePath);
|
||||
}
|
||||
|
||||
node.remove();
|
||||
|
@ -489,8 +490,9 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
}
|
||||
}
|
||||
|
||||
const activeNode = this.getActiveNode();
|
||||
const activateNotePath = activeNode ? await treeService.getNotePath(activeNode) : null;
|
||||
for (const noteId of loadResults.getNoteIds()) {
|
||||
noteIdsToUpdate.push(noteId);
|
||||
}
|
||||
|
||||
for (const noteId of noteIdsToReload) {
|
||||
for (const node of this.getNodesByNoteId(noteId)) {
|
||||
|
@ -500,7 +502,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
}
|
||||
}
|
||||
|
||||
for (const noteId of noteIdsToReload) {
|
||||
for (const noteId of noteIdsToUpdate) {
|
||||
for (const node of this.getNodesByNoteId(noteId)) {
|
||||
await this.updateNode(node);
|
||||
}
|
||||
|
@ -523,6 +525,8 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
}
|
||||
}
|
||||
|
||||
const activateNotePath = appContext.getActiveTabNotePath();
|
||||
|
||||
if (activateNotePath) {
|
||||
const node = await this.getNodeFromPath(activateNotePath);
|
||||
|
||||
|
|
|
@ -638,10 +638,6 @@ class ConsistencyChecks {
|
|||
elapsedTimeMs = Date.now() - startTime.getTime();
|
||||
});
|
||||
|
||||
if (this.fixedIssues) {
|
||||
ws.refreshTree();
|
||||
}
|
||||
|
||||
if (this.unrecoveredConsistencyErrors) {
|
||||
log.info(`Consistency checks failed (took ${elapsedTimeMs}ms)`);
|
||||
|
||||
|
|
|
@ -125,10 +125,6 @@ function sendPingToAllClients() {
|
|||
}
|
||||
}
|
||||
|
||||
function refreshTree() {
|
||||
sendMessageToAllClients({ type: 'refresh-tree' });
|
||||
}
|
||||
|
||||
function syncPullInProgress() {
|
||||
sendMessageToAllClients({ type: 'sync-pull-in-progress' });
|
||||
}
|
||||
|
@ -140,7 +136,6 @@ function syncPullFinished() {
|
|||
module.exports = {
|
||||
init,
|
||||
sendMessageToAllClients,
|
||||
refreshTree,
|
||||
syncPullInProgress,
|
||||
syncPullFinished,
|
||||
sendPingToAllClients
|
||||
|
|
Loading…
Reference in a new issue