mirror of
https://github.com/zadam/trilium.git
synced 2025-02-27 00:29:21 +08:00
reloading notes after script changes
This commit is contained in:
parent
78f5b7b288
commit
2305ad7405
21 changed files with 115 additions and 82 deletions
|
@ -1581,7 +1581,7 @@
|
|||
|
||||
|
||||
|
||||
<h4 class="name" id="getActiveNote"><span class="type-signature"></span>getActiveNote<span class="signature">()</span><span class="type-signature"> → {<a href="NoteFull.html">NoteFull</a>}</span></h4>
|
||||
<h4 class="name" id="getActiveTabNote"><span class="type-signature"></span>getActiveTabNote<span class="signature">()</span><span class="type-signature"> → {<a href="NoteFull.html">NoteFull</a>}</span></h4>
|
||||
|
||||
|
||||
|
||||
|
@ -1687,7 +1687,7 @@
|
|||
|
||||
|
||||
|
||||
<h4 class="name" id="getActiveNotePath"><span class="type-signature"></span>getActiveNotePath<span class="signature">()</span><span class="type-signature"> → {Promise.<(string|null)>}</span></h4>
|
||||
<h4 class="name" id="getActiveTabNotePath"><span class="type-signature"></span>getActiveTabNotePath<span class="signature">()</span><span class="type-signature"> → {Promise.<(string|null)>}</span></h4>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
|
|||
* @param {string} noteId
|
||||
* @method
|
||||
*/
|
||||
this.reloadChildren = async noteId => await treeCache.reloadChildren(noteId);
|
||||
this.reloadChildren = async noteId => await treeCache.reloadNotesAndTheirChildren(noteId);
|
||||
|
||||
/**
|
||||
* @param {string} noteId
|
||||
|
@ -303,13 +303,13 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
|
|||
* @method
|
||||
* @returns {NoteFull} active note (loaded into right pane)
|
||||
*/
|
||||
this.getActiveNote = noteDetailService.getActiveNote;
|
||||
this.getActiveTabNote = noteDetailService.getActiveTabNote;
|
||||
|
||||
/**
|
||||
* @method
|
||||
* @returns {Promise<string|null>} returns note path of active note or null if there isn't active note
|
||||
*/
|
||||
this.getActiveNotePath = () => {
|
||||
this.getActiveTabNotePath = () => {
|
||||
const activeTabContext = noteDetailService.getActiveTabContext();
|
||||
|
||||
return activeTabContext ? activeTabContext.notePath : null;
|
||||
|
|
4
libraries/codemirror/addon/lint/eslint.js
vendored
4
libraries/codemirror/addon/lint/eslint.js
vendored
|
@ -29,8 +29,8 @@
|
|||
|
||||
async function validatorJavaScript(text, options) {
|
||||
if (glob.isMobile()
|
||||
|| glob.getActiveNote() == null
|
||||
|| glob.getActiveNote().mime === 'application/json') {
|
||||
|| glob.getActiveTabNote() == null
|
||||
|| glob.getActiveTabNote().mime === 'application/json') {
|
||||
// eslint doesn't seem to validate pure JSON well
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ window.glob.noteChanged = noteDetailService.noteChanged;
|
|||
window.glob.refreshTree = treeService.reload;
|
||||
|
||||
// required for ESLint plugin
|
||||
window.glob.getActiveNote = noteDetailService.getActiveNote;
|
||||
window.glob.getActiveTabNote = noteDetailService.getActiveTabNote;
|
||||
window.glob.requireLibrary = libraryLoader.requireLibrary;
|
||||
window.glob.ESLINT = libraryLoader.ESLINT;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ export async function showDialog(linkType) {
|
|||
|
||||
glob.activeDialog = $dialog;
|
||||
|
||||
if (noteDetailService.getActiveNoteType() === 'text') {
|
||||
if (noteDetailService.getActiveTabNoteType() === 'text') {
|
||||
$linkTypeHtml.prop('disabled', false);
|
||||
|
||||
setLinkType('html');
|
||||
|
@ -110,14 +110,14 @@ $form.submit(() => {
|
|||
else if (linkType === 'selected-to-active') {
|
||||
const prefix = $clonePrefix.val();
|
||||
|
||||
cloningService.cloneNoteTo(noteId, noteDetailService.getActiveNoteId(), prefix);
|
||||
cloningService.cloneNoteTo(noteId, noteDetailService.getActiveTabNoteId(), prefix);
|
||||
|
||||
$dialog.modal('hide');
|
||||
}
|
||||
else if (linkType === 'active-to-selected') {
|
||||
const prefix = $clonePrefix.val();
|
||||
|
||||
cloningService.cloneNoteTo(noteDetailService.getActiveNoteId(), noteId, prefix);
|
||||
cloningService.cloneNoteTo(noteDetailService.getActiveTabNoteId(), noteId, prefix);
|
||||
|
||||
$dialog.modal('hide');
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ function AttributesModel() {
|
|||
}
|
||||
|
||||
this.loadAttributes = async function() {
|
||||
const noteId = noteDetailService.getActiveNoteId();
|
||||
const noteId = noteDetailService.getActiveTabNoteId();
|
||||
|
||||
const attributes = await server.get('notes/' + noteId + '/attributes');
|
||||
|
||||
|
@ -138,7 +138,7 @@ function AttributesModel() {
|
|||
|
||||
self.updateAttributePositions();
|
||||
|
||||
const noteId = noteDetailService.getActiveNoteId();
|
||||
const noteId = noteDetailService.getActiveTabNoteId();
|
||||
|
||||
const attributesToSave = self.ownedAttributes()
|
||||
.map(attribute => attribute())
|
||||
|
|
|
@ -23,7 +23,7 @@ export async function showDialog() {
|
|||
// set default settings
|
||||
$maxNotesInput.val(20);
|
||||
|
||||
const note = noteDetailService.getActiveNote();
|
||||
const note = noteDetailService.getActiveTabNote();
|
||||
|
||||
if (!note) {
|
||||
return;
|
||||
|
|
|
@ -16,7 +16,7 @@ export function showDialog() {
|
|||
|
||||
$dialog.modal();
|
||||
|
||||
const activeNote = noteDetailService.getActiveNote();
|
||||
const activeNote = noteDetailService.getActiveTabNote();
|
||||
|
||||
$noteId.text(activeNote.noteId);
|
||||
$dateCreated.text(activeNote.dateCreated);
|
||||
|
|
|
@ -11,7 +11,7 @@ let revisionItems = [];
|
|||
let note;
|
||||
|
||||
export async function showCurrentNoteRevisions() {
|
||||
await showNoteRevisionsDialog(noteDetailService.getActiveNoteId());
|
||||
await showNoteRevisionsDialog(noteDetailService.getActiveTabNoteId());
|
||||
}
|
||||
|
||||
export async function showNoteRevisionsDialog(noteId, noteRevisionId) {
|
||||
|
@ -24,7 +24,7 @@ export async function showNoteRevisionsDialog(noteId, noteRevisionId) {
|
|||
$list.empty();
|
||||
$content.empty();
|
||||
|
||||
note = noteDetailService.getActiveNote();
|
||||
note = noteDetailService.getActiveTabNote();
|
||||
revisionItems = await server.get('notes/' + noteId + '/revisions');
|
||||
|
||||
for (const item of revisionItems) {
|
||||
|
|
|
@ -11,7 +11,7 @@ export function showDialog() {
|
|||
|
||||
$dialog.modal();
|
||||
|
||||
const noteText = noteDetailService.getActiveNote().content;
|
||||
const noteText = noteDetailService.getActiveTabNote().content;
|
||||
|
||||
$noteSource.text(formatHtml(noteText));
|
||||
}
|
||||
|
|
|
@ -162,9 +162,7 @@ async function deleteNodes(nodes) {
|
|||
node.remove();
|
||||
}
|
||||
|
||||
for (const parentNoteId of parentNoteIds) {
|
||||
await treeService.reloadNote(parentNoteId);
|
||||
}
|
||||
await treeService.reloadNotes(parentNoteIds);
|
||||
|
||||
// activate after all the reloading
|
||||
if (activeNotePath) {
|
||||
|
|
|
@ -14,7 +14,7 @@ async function cloneNoteTo(childNoteId, parentNoteId, prefix) {
|
|||
|
||||
treeCache.addBranchRelationship(resp.branchId, childNoteId, parentNoteId);
|
||||
|
||||
await treeService.reloadNote(parentNoteId);
|
||||
await treeService.reloadNotes([parentNoteId]);
|
||||
}
|
||||
|
||||
// beware that first arg is noteId and second is branchId!
|
||||
|
@ -30,7 +30,7 @@ async function cloneNoteAfter(noteId, afterBranchId) {
|
|||
|
||||
treeCache.addBranchRelationship(resp.branchId, noteId, afterBranch.parentNoteId);
|
||||
|
||||
await treeService.reloadNote(afterBranch.parentNoteId);
|
||||
await treeService.reloadNotes([afterBranch.parentNoteId]);
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
|
@ -210,7 +210,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
|
|||
* @param {string} noteId
|
||||
* @method
|
||||
*/
|
||||
this.reloadChildren = async noteId => await treeCache.reloadChildren(noteId);
|
||||
this.reloadNotesAndTheirChildren = async noteId => await treeCache.reloadNotesAndTheirChildren(noteId);
|
||||
|
||||
/**
|
||||
* @param {string} noteId
|
||||
|
@ -277,17 +277,13 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
|
|||
* @method
|
||||
* @returns {NoteFull} active note (loaded into right pane)
|
||||
*/
|
||||
this.getActiveNote = noteDetailService.getActiveNote;
|
||||
this.getActiveTabNote = noteDetailService.getActiveTabNote;
|
||||
|
||||
/**
|
||||
* @method
|
||||
* @returns {Promise<string|null>} returns note path of active note or null if there isn't active note
|
||||
*/
|
||||
this.getActiveNotePath = () => {
|
||||
const activeTabContext = noteDetailService.getActiveTabContext();
|
||||
|
||||
return activeTabContext ? activeTabContext.notePath : null;
|
||||
};
|
||||
this.getActiveTabNotePath = noteDetailService.getActiveTabNotePath;
|
||||
|
||||
/**
|
||||
* This method checks whether user navigated away from the note from which the scripts has been started.
|
||||
|
|
|
@ -63,7 +63,7 @@ ws.subscribeToMessages(async message => {
|
|||
|
||||
toastService.showPersistent(toast);
|
||||
|
||||
await treeService.reloadNote(message.parentNoteId);
|
||||
await treeService.reloadNotes([message.parentNoteId]);
|
||||
|
||||
if (message.result.importedNoteId) {
|
||||
const node = await treeService.activateNote(message.result.importedNoteId);
|
||||
|
|
|
@ -8,7 +8,7 @@ const SELECTED_PATH_KEY = "data-note-path";
|
|||
async function autocompleteSource(term, cb) {
|
||||
const result = await server.get('autocomplete'
|
||||
+ '?query=' + encodeURIComponent(term)
|
||||
+ '&activeNoteId=' + noteDetailService.getActiveNoteId());
|
||||
+ '&activeNoteId=' + noteDetailService.getActiveTabNoteId());
|
||||
|
||||
if (result.length === 0) {
|
||||
result.push({
|
||||
|
|
|
@ -107,20 +107,26 @@ function getActiveTabContext() {
|
|||
return tabContexts.find(tc => tc.tabId === tabId);
|
||||
}
|
||||
|
||||
/** @returns {string|null} */
|
||||
function getActiveTabNotePath() {
|
||||
const activeContext = getActiveTabContext();
|
||||
return activeContext ? activeContext.notePath : null;
|
||||
}
|
||||
|
||||
/** @return {NoteFull} */
|
||||
function getActiveNote() {
|
||||
function getActiveTabNote() {
|
||||
const activeContext = getActiveTabContext();
|
||||
return activeContext ? activeContext.note : null;
|
||||
}
|
||||
|
||||
function getActiveNoteId() {
|
||||
const activeNote = getActiveNote();
|
||||
function getActiveTabNoteId() {
|
||||
const activeNote = getActiveTabNote();
|
||||
|
||||
return activeNote ? activeNote.noteId : null;
|
||||
}
|
||||
|
||||
function getActiveNoteType() {
|
||||
const activeNote = getActiveNote();
|
||||
function getActiveTabNoteType() {
|
||||
const activeNote = getActiveTabNote();
|
||||
|
||||
return activeNote ? activeNote.type : null;
|
||||
}
|
||||
|
@ -300,7 +306,7 @@ function addDetailLoadedListener(noteId, callback) {
|
|||
|
||||
function fireDetailLoaded() {
|
||||
for (const {noteId, callback} of detailLoadedListeners) {
|
||||
if (noteId === getActiveNoteId()) {
|
||||
if (noteId === getActiveTabNoteId()) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +343,7 @@ $tabContentsContainer.on("dragover", e => e.preventDefault());
|
|||
$tabContentsContainer.on("dragleave", e => e.preventDefault());
|
||||
|
||||
$tabContentsContainer.on("drop", async e => {
|
||||
const activeNote = getActiveNote();
|
||||
const activeNote = getActiveTabNote();
|
||||
|
||||
if (!activeNote) {
|
||||
return;
|
||||
|
@ -497,9 +503,6 @@ export default {
|
|||
switchToNote,
|
||||
loadNote,
|
||||
loadNoteDetail,
|
||||
getActiveNote,
|
||||
getActiveNoteType,
|
||||
getActiveNoteId,
|
||||
focusOnTitle,
|
||||
focusAndSelectTitle,
|
||||
saveNotesIfChanged,
|
||||
|
@ -508,6 +511,10 @@ export default {
|
|||
switchToTab,
|
||||
getTabContexts,
|
||||
getActiveTabContext,
|
||||
getActiveTabNotePath,
|
||||
getActiveTabNote,
|
||||
getActiveTabNoteType,
|
||||
getActiveTabNoteId,
|
||||
getActiveEditor,
|
||||
activateOrOpenNote,
|
||||
clearOpenTabsTask,
|
||||
|
|
|
@ -70,13 +70,13 @@ async function enterProtectedSessionOnServer(password) {
|
|||
}
|
||||
|
||||
async function protectNoteAndSendToServer() {
|
||||
if (!noteDetailService.getActiveNote() || noteDetailService.getActiveNote().isProtected) {
|
||||
if (!noteDetailService.getActiveTabNote() || noteDetailService.getActiveTabNote().isProtected) {
|
||||
return;
|
||||
}
|
||||
|
||||
await enterProtectedSession();
|
||||
|
||||
const note = noteDetailService.getActiveNote();
|
||||
const note = noteDetailService.getActiveTabNote();
|
||||
note.isProtected = true;
|
||||
|
||||
await noteDetailService.getActiveTabContext().saveNote();
|
||||
|
@ -87,7 +87,7 @@ async function protectNoteAndSendToServer() {
|
|||
}
|
||||
|
||||
async function unprotectNoteAndSendToServer() {
|
||||
const activeNote = noteDetailService.getActiveNote();
|
||||
const activeNote = noteDetailService.getActiveTabNote();
|
||||
|
||||
if (!activeNote.isProtected) {
|
||||
toastService.showAndLogError(`Note ${activeNote.noteId} is not protected`);
|
||||
|
|
|
@ -580,14 +580,11 @@ async function scrollToActiveNote() {
|
|||
}
|
||||
}
|
||||
|
||||
function setBranchBackgroundBasedOnProtectedStatus(noteId) {
|
||||
getNodesByNoteId(noteId).map(node => node.toggleClass("protected", node.data.isProtected));
|
||||
}
|
||||
|
||||
function setProtected(noteId, isProtected) {
|
||||
getNodesByNoteId(noteId).map(node => node.data.isProtected = isProtected);
|
||||
|
||||
setBranchBackgroundBasedOnProtectedStatus(noteId);
|
||||
getNodesByNoteId(noteId).map(node => {
|
||||
node.data.isProtected = isProtected;
|
||||
node.toggleClass("protected", isProtected);
|
||||
});
|
||||
}
|
||||
|
||||
async function setNoteTitle(noteId, title) {
|
||||
|
@ -619,7 +616,7 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) {
|
|||
extraOptions.isProtected = false;
|
||||
}
|
||||
|
||||
if (noteDetailService.getActiveNoteType() !== 'text') {
|
||||
if (noteDetailService.getActiveTabNoteType() !== 'text') {
|
||||
extraOptions.saveSelection = false;
|
||||
}
|
||||
else {
|
||||
|
@ -762,13 +759,27 @@ ws.subscribeToMessages(message => {
|
|||
});
|
||||
|
||||
ws.subscribeToOutsideSyncMessages(syncData => {
|
||||
if (syncData.some(sync => sync.entityName === 'branches')
|
||||
|| syncData.some(sync => sync.entityName === 'notes')) {
|
||||
const noteIdsToRefresh = [];
|
||||
|
||||
console.log(utils.now(), "Reloading tree because of background changes");
|
||||
|
||||
reload();
|
||||
for (const sync of syncData.filter(sync => sync.entityName === 'branches')) {
|
||||
if (!noteIdsToRefresh.includes(sync.parentNoteId)) {
|
||||
noteIdsToRefresh.push(sync.parentNoteId);
|
||||
}
|
||||
}
|
||||
|
||||
for (const sync of syncData.filter(sync => sync.entityName === 'notes')) {
|
||||
if (!noteIdsToRefresh.includes(sync.noteId)) {
|
||||
noteIdsToRefresh.push(sync.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
for (const sync of syncData.filter(sync => sync.entityName === 'note_reordering')) {
|
||||
if (!noteIdsToRefresh.includes(sync.entityId)) {
|
||||
noteIdsToRefresh.push(sync.entityId);
|
||||
}
|
||||
}
|
||||
|
||||
reloadNotes(noteIdsToRefresh);
|
||||
});
|
||||
|
||||
utils.bindGlobalShortcut('ctrl+o', async () => {
|
||||
|
@ -805,13 +816,25 @@ async function checkFolderStatus(node) {
|
|||
node.renderTitle();
|
||||
}
|
||||
|
||||
async function reloadNote(noteId) {
|
||||
await treeCache.reloadChildren(noteId);
|
||||
async function reloadNotes(noteIds) {
|
||||
await treeCache.reloadNotesAndTheirChildren(noteIds);
|
||||
|
||||
for (const node of getNodesByNoteId(noteId)) {
|
||||
await node.load(true);
|
||||
const activeNotePath = noteDetailService.getActiveTabNotePath();
|
||||
|
||||
await checkFolderStatus(node);
|
||||
for (const noteId of noteIds) {
|
||||
for (const node of getNodesByNoteId(noteId)) {
|
||||
await node.load(true);
|
||||
|
||||
await checkFolderStatus(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (activeNotePath) {
|
||||
const node = await getNodeFromPath(activeNotePath);
|
||||
|
||||
if (node) {
|
||||
node.setActive(true, {noEvents: true}); // this node has been already active so no need to fire events again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,7 +891,6 @@ frontendLoaded.then(bundle.executeStartupBundles);
|
|||
export default {
|
||||
reload,
|
||||
collapseTree,
|
||||
setBranchBackgroundBasedOnProtectedStatus,
|
||||
setProtected,
|
||||
activateNote,
|
||||
getFocusedNode,
|
||||
|
@ -887,7 +909,7 @@ export default {
|
|||
setExpandedToServer,
|
||||
getNodesByNoteId,
|
||||
checkFolderStatus,
|
||||
reloadNote,
|
||||
reloadNotes,
|
||||
loadTreeCache,
|
||||
expandToNote,
|
||||
getNodeFromPath,
|
||||
|
|
|
@ -54,24 +54,27 @@ class TreeCache {
|
|||
}
|
||||
|
||||
/**
|
||||
* Reload children of given noteId.
|
||||
* Reload notes and their children.
|
||||
*/
|
||||
async reloadChildren(noteId) {
|
||||
const resp = await server.post('tree/load', { noteIds: [noteId] });
|
||||
async reloadNotesAndTheirChildren(noteIds) {
|
||||
// first load the data before clearing the cache
|
||||
const resp = await server.post('tree/load', { noteIds });
|
||||
|
||||
for (const childNoteId of this.children[noteId] || []) {
|
||||
this.parents[childNoteId] = this.parents[childNoteId].filter(p => p !== noteId);
|
||||
for (const noteId of noteIds) {
|
||||
for (const childNoteId of this.children[noteId] || []) {
|
||||
this.parents[childNoteId] = this.parents[childNoteId].filter(p => p !== noteId);
|
||||
|
||||
const branchId = this.getBranchIdByChildParent(childNoteId, noteId);
|
||||
const branchId = this.getBranchIdByChildParent(childNoteId, noteId);
|
||||
|
||||
delete this.branches[branchId];
|
||||
delete this.childParentToBranch[childNoteId + '-' + noteId];
|
||||
delete this.branches[branchId];
|
||||
delete this.childParentToBranch[childNoteId + '-' + noteId];
|
||||
}
|
||||
|
||||
this.children[noteId] = [];
|
||||
|
||||
delete this.notes[noteId];
|
||||
}
|
||||
|
||||
this.children[noteId] = [];
|
||||
|
||||
delete this.notes[noteId];
|
||||
|
||||
this.addResp(resp.notes, resp.branches, resp.relations);
|
||||
}
|
||||
|
||||
|
@ -83,12 +86,10 @@ class TreeCache {
|
|||
// to be able to find parents we need first to make sure it is actually loaded
|
||||
await this.getNote(noteId);
|
||||
|
||||
for (const parentNoteId of this.parents[noteId] || []) {
|
||||
await this.reloadChildren(parentNoteId);
|
||||
}
|
||||
await this.reloadNotesAndTheirChildren(this.parents[noteId] || []);
|
||||
|
||||
// this is done to load the new parents for the noteId
|
||||
await this.reloadChildren(noteId);
|
||||
await this.reloadNotesAndTheirChildren([noteId]);
|
||||
}
|
||||
|
||||
/** @return {Promise<NoteShort[]>} */
|
||||
|
|
|
@ -863,12 +863,14 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
|
|||
position: absolute;
|
||||
width: 100%;
|
||||
top: 20px;
|
||||
z-index: -100;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.toast {
|
||||
background-color: var(--accented-background-color) !important;
|
||||
color: var(--main-text-color) !important;
|
||||
z-index: 9999999999 !important;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.toast-header {
|
||||
|
|
|
@ -67,12 +67,19 @@ async function sendPing(client, lastSentSyncId) {
|
|||
const syncData = await sql.getRows("SELECT * FROM sync WHERE id > ?", [lastSentSyncId]);
|
||||
|
||||
for (const sync of syncData) {
|
||||
// fill in some extra data needed by the frontend
|
||||
if (sync.entityName === 'attributes') {
|
||||
sync.noteId = await sql.getValue(`SELECT noteId FROM attributes WHERE attributeId = ?`, [sync.entityId]);
|
||||
}
|
||||
else if (sync.entityName === 'note_revisions') {
|
||||
sync.noteId = await sql.getValue(`SELECT noteId FROM note_revisions WHERE noteRevisionId = ?`, [sync.entityId]);
|
||||
}
|
||||
else if (sync.entityName === 'branches') {
|
||||
const {noteId, parentNoteId} = await sql.getRow(`SELECT noteId, parentNoteId FROM branches WHERE branchId = ?`, [sync.entityId]);
|
||||
|
||||
sync.noteId = noteId;
|
||||
sync.parentNoteId = parentNoteId;
|
||||
}
|
||||
}
|
||||
|
||||
const stats = require('./sync').stats;
|
||||
|
|
Loading…
Reference in a new issue