Merge branch 'master' into next53

This commit is contained in:
zadam
2022-06-02 22:32:29 +02:00
16 changed files with 1221 additions and 315 deletions

View File

@@ -9,6 +9,8 @@ const entityChangesService = require('../../services/entity_changes');
const AbstractEntity = require("./abstract_entity");
const NoteRevision = require("./note_revision");
const TaskContext = require("../../services/task_context.js");
const optionService = require("../../services/options.js");
const noteRevisionService = require("../../services/note_revisions.js");
const LABEL = 'label';
const RELATION = 'relation';
@@ -1164,6 +1166,41 @@ class Note extends AbstractEntity {
return !(this.noteId in this.becca.notes);
}
/**
* @return {NoteRevision|null}
*/
saveNoteRevision() {
const content = this.getContent();
if (!content || (Buffer.isBuffer(content) && content.byteLength === 0)) {
return null;
}
const contentMetadata = this.getContentMetadata();
const noteRevision = new NoteRevision({
noteId: this.noteId,
// title and text should be decrypted now
title: this.title,
type: this.type,
mime: this.mime,
isProtected: false, // will be fixed in the protectNoteRevisions() call
utcDateLastEdited: this.utcDateModified > contentMetadata.utcDateModified
? this.utcDateModified
: contentMetadata.utcDateModified,
utcDateCreated: dateUtils.utcNowDateTime(),
utcDateModified: dateUtils.utcNowDateTime(),
dateLastEdited: this.dateModified > contentMetadata.dateModified
? this.dateModified
: contentMetadata.dateModified,
dateCreated: dateUtils.localNowDateTime()
}).save();
noteRevision.setContent(content);
return noteRevision;
}
beforeSaving() {
super.beforeSaving();

View File

@@ -101,6 +101,26 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
}
};
/**
* Open a note in a new split.
*
* @param {string} notePath (or noteId)
* @param {boolean} activate - set to true to activate the new split, false to stay on the current split
* @return {Promise<void>}
*/
this.openSplitWithNote = async (notePath, activate) => {
await ws.waitForMaxKnownEntityChangeId();
const subContexts = appContext.tabManager.getActiveContext().getSubContexts();
const {ntxId} = subContexts[subContexts.length - 1];
appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath});
if (activate) {
appContext.triggerEvent('focusAndSelectTitle');
}
};
/**
* @typedef {Object} ToolbarButtonOptions
* @property {string} title

View File

@@ -306,7 +306,8 @@ export default class TabManager extends Component {
const mainNoteContexts = this.getNoteContexts().filter(nc => nc.isMainContext());
if (mainNoteContexts.length === 1) {
mainNoteContexts[0].setEmpty();
await this.clearLastMainNoteContext(noteContextToRemove);
return;
}
}
@@ -317,7 +318,7 @@ export default class TabManager extends Component {
const noteContextsToRemove = noteContextToRemove.getSubContexts();
const ntxIdsToRemove = noteContextsToRemove.map(nc => nc.ntxId);
await this.triggerEvent('beforeTabRemove', { ntxIds: ntxIdsToRemove });
await this.triggerEvent('beforeNoteContextRemove', { ntxIds: ntxIdsToRemove });
if (!noteContextToRemove.isMainContext()) {
await this.activateNoteContext(noteContextToRemove.getMainContext().ntxId);
@@ -336,16 +337,39 @@ export default class TabManager extends Component {
}
}
this.children = this.children.filter(nc => !ntxIdsToRemove.includes(nc.ntxId));
this.recentlyClosedTabs.push(noteContextsToRemove);
this.triggerEvent('noteContextRemoved', {ntxIds: ntxIdsToRemove});
this.tabsUpdate.scheduleUpdate();
this.removeNoteContexts(noteContextsToRemove);
});
}
async clearLastMainNoteContext(noteContextToClear) {
noteContextToClear.setEmpty();
// activate main split
await this.activateNoteContext(noteContextToClear.ntxId);
// remove all other splits
const noteContextsToRemove = noteContextToClear.getSubContexts()
.filter(ntx => ntx.ntxId !== noteContextToClear.ntxId);
const ntxIdsToRemove = noteContextsToRemove.map(ntx => ntx.ntxId);
await this.triggerEvent('beforeNoteContextRemove', {ntxIds: ntxIdsToRemove});
this.removeNoteContexts(noteContextsToRemove);
}
removeNoteContexts(noteContextsToRemove) {
const ntxIdsToRemove = noteContextsToRemove.map(nc => nc.ntxId);
this.children = this.children.filter(nc => !ntxIdsToRemove.includes(nc.ntxId));
this.recentlyClosedTabs.push(noteContextsToRemove);
this.triggerEvent('noteContextRemoved', {ntxIds: ntxIdsToRemove});
this.tabsUpdate.scheduleUpdate();
}
tabReorderEvent({ntxIdsInOrder}) {
const order = {};

View File

@@ -219,7 +219,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
}
}
async beforeTabRemoveEvent({ntxIds}) {
async beforeNoteContextRemoveEvent({ntxIds}) {
if (this.isNoteContext(ntxIds)) {
await this.spacedUpdate.updateNowIfNecessary();
}

View File

@@ -87,7 +87,7 @@ export default class NoteTitleWidget extends NoteContextAwareWidget {
}
}
async beforeTabRemoveEvent({ntxIds}) {
async beforeNoteContextRemoveEvent({ntxIds}) {
if (this.isNoteContext(ntxIds)) {
await this.spacedUpdate.updateNowIfNecessary();
}

View File

@@ -206,7 +206,7 @@ function changeTitle(req) {
const noteTitleChanged = note.title !== title;
if (noteTitleChanged) {
noteService.saveNoteRevision(note);
noteService.saveNoteRevisionIfNeeded(note);
}
note.title = title;

View File

@@ -30,46 +30,6 @@ function protectNoteRevisions(note) {
}
}
/**
* @param {Note} note
* @return {NoteRevision|null}
*/
function createNoteRevision(note) {
if (note.hasLabel("disableVersioning")) {
return null;
}
const content = note.getContent();
if (!content || (Buffer.isBuffer(content) && content.byteLength === 0)) {
return null;
}
const contentMetadata = note.getContentMetadata();
const noteRevision = new NoteRevision({
noteId: note.noteId,
// title and text should be decrypted now
title: note.title,
type: note.type,
mime: note.mime,
isProtected: false, // will be fixed in the protectNoteRevisions() call
utcDateLastEdited: note.utcDateModified > contentMetadata.utcDateModified
? note.utcDateModified
: contentMetadata.utcDateModified,
utcDateCreated: dateUtils.utcNowDateTime(),
utcDateModified: dateUtils.utcNowDateTime(),
dateLastEdited: note.dateModified > contentMetadata.dateModified
? note.dateModified
: contentMetadata.dateModified,
dateCreated: dateUtils.localNowDateTime()
}).save();
noteRevision.setContent(content);
return noteRevision;
}
function eraseNoteRevisions(noteRevisionIdsToErase) {
if (noteRevisionIdsToErase.length === 0) {
return;
@@ -86,6 +46,5 @@ function eraseNoteRevisions(noteRevisionIdsToErase) {
module.exports = {
protectNoteRevisions,
createNoteRevision,
eraseNoteRevisions
};

View File

@@ -499,7 +499,7 @@ function saveLinks(note, content) {
return content;
}
function saveNoteRevision(note) {
function saveNoteRevisionIfNeeded(note) {
// files and images are versioned separately
if (note.type === 'file' || note.type === 'image' || note.hasLabel('disableVersioning')) {
return;
@@ -516,7 +516,7 @@ function saveNoteRevision(note) {
const msSinceDateCreated = now.getTime() - dateUtils.parseDateTime(note.utcDateCreated).getTime();
if (!existingNoteRevisionId && msSinceDateCreated >= noteRevisionSnapshotTimeInterval * 1000) {
noteRevisionService.createNoteRevision(note);
note.saveNoteRevision();
}
}
@@ -527,7 +527,7 @@ function updateNote(noteId, noteUpdates) {
throw new Error(`Note '${noteId}' is not available for change!`);
}
saveNoteRevision(note);
saveNoteRevisionIfNeeded(note);
// if protected status changed, then we need to encrypt/decrypt the content anyway
if (['file', 'image'].includes(note.type) && note.isProtected !== noteUpdates.isProtected) {
@@ -918,6 +918,6 @@ module.exports = {
triggerNoteTitleChanged,
eraseDeletedNotesNow,
eraseNotesWithDeleteId,
saveNoteRevision,
saveNoteRevisionIfNeeded,
downloadImages
};

View File

@@ -83,7 +83,7 @@ function lex(str) {
continue;
}
else if (!quotes) {
if (!fulltextEnded && currentWord === 'note' && chr === '.') {
if (!fulltextEnded && currentWord === 'note' && chr === '.' && i + 1 < str.length) {
fulltextEnded = true;
}