mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Merge remote-tracking branch 'origin/stable'
This commit is contained in:
commit
67cce5f817
@ -2,7 +2,7 @@
|
||||
"name": "trilium",
|
||||
"productName": "Trilium Notes",
|
||||
"description": "Trilium Notes",
|
||||
"version": "0.50.1",
|
||||
"version": "0.50.2",
|
||||
"license": "AGPL-3.0-only",
|
||||
"main": "electron.js",
|
||||
"bin": {
|
||||
|
@ -42,8 +42,10 @@ class EtapiToken extends AbstractEntity {
|
||||
/** @type {boolean} */
|
||||
this.isDeleted = !!row.isDeleted;
|
||||
|
||||
if (this.etapiTokenId) {
|
||||
this.becca.etapiTokens[this.etapiTokenId] = this;
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.etapiTokenId) {
|
||||
|
@ -62,12 +62,12 @@ export default class EtapiOptions {
|
||||
return;
|
||||
}
|
||||
|
||||
const {token} = await server.post('etapi-tokens', {tokenName});
|
||||
const {authToken} = await server.post('etapi-tokens', {tokenName});
|
||||
|
||||
await promptDialog.ask({
|
||||
title: "ETAPI token created",
|
||||
message: 'Copy the created token into clipboard. Trilium stores the token hashed and this is the last time you see it.',
|
||||
defaultValue: token
|
||||
defaultValue: authToken
|
||||
});
|
||||
|
||||
this.refreshTokens();
|
||||
|
@ -51,7 +51,8 @@ $dialog.on("hidden.bs.modal", () => {
|
||||
}
|
||||
});
|
||||
|
||||
$form.on('submit', () => {
|
||||
$form.on('submit', e => {
|
||||
e.preventDefault();
|
||||
resolve($answer.val());
|
||||
|
||||
$dialog.modal('hide');
|
||||
|
@ -7,11 +7,14 @@ import treeService from "./tree.js";
|
||||
import utils from "./utils.js";
|
||||
import NoteContext from "./note_context.js";
|
||||
import appContext from "./app_context.js";
|
||||
import Mutex from "../utils/mutex.js";
|
||||
|
||||
export default class TabManager extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.mutex = new Mutex();
|
||||
|
||||
this.activeNtxId = null;
|
||||
|
||||
// elements are arrays of note contexts for each tab (one main context + subcontexts [splits])
|
||||
@ -292,6 +295,9 @@ export default class TabManager extends Component {
|
||||
}
|
||||
|
||||
async removeNoteContext(ntxId) {
|
||||
// removing note context is async process which can take some time, if users presses CTRL-W quickly, two
|
||||
// close events could interleave which would then lead to attempting to activate already removed context.
|
||||
await this.mutex.runExclusively(async () => {
|
||||
const noteContextToRemove = this.getNoteContextById(ntxId);
|
||||
|
||||
if (noteContextToRemove.isMainContext()) {
|
||||
@ -337,6 +343,7 @@ export default class TabManager extends Component {
|
||||
this.triggerEvent('noteContextRemoved', {ntxIds: ntxIdsToRemove});
|
||||
|
||||
this.tabsUpdate.scheduleUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
tabReorderEvent({ntxIdsInOrder}) {
|
||||
|
@ -65,7 +65,7 @@ async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logEr
|
||||
|
||||
if (!parents.length) {
|
||||
if (logErrors) {
|
||||
ws.logError(`No parents found for ${childNoteId} (${child.title}) for path ${notePath}`);
|
||||
ws.logError(`No parents found for note ${childNoteId} (${child.title}) for path ${notePath}`);
|
||||
}
|
||||
|
||||
return;
|
||||
|
28
src/public/app/utils/mutex.js
Normal file
28
src/public/app/utils/mutex.js
Normal file
@ -0,0 +1,28 @@
|
||||
export default class Mutex {
|
||||
constructor() {
|
||||
this.current = Promise.resolve();
|
||||
}
|
||||
|
||||
/** @returns {Promise} */
|
||||
lock() {
|
||||
let resolveFun;
|
||||
const subPromise = new Promise(resolve => resolveFun = () => resolve());
|
||||
// Caller gets a promise that resolves when the current outstanding lock resolves
|
||||
const newPromise = this.current.then(() => resolveFun);
|
||||
// Don't allow the next request until the new promise is done
|
||||
this.current = subPromise;
|
||||
// Return the new promise
|
||||
return newPromise;
|
||||
};
|
||||
|
||||
async runExclusively(cb) {
|
||||
const unlock = await this.lock();
|
||||
|
||||
try {
|
||||
await cb();
|
||||
}
|
||||
finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
}
|
@ -91,6 +91,8 @@ body {
|
||||
|
||||
--ck-color-table-focused-cell-background: var(--more-accented-background-color);
|
||||
|
||||
--ck-color-labeled-field-label-background: var(--accented-background-color);
|
||||
|
||||
/* todo lists */
|
||||
|
||||
--ck-color-todo-list-checkmark-border: var(--main-border-color);
|
||||
|
@ -9,9 +9,7 @@ function getTokens() {
|
||||
}
|
||||
|
||||
function createToken(req) {
|
||||
return {
|
||||
authToken: etapiTokenService.createToken(req.body.tokenName)
|
||||
};
|
||||
return etapiTokenService.createToken(req.body.tokenName);
|
||||
}
|
||||
|
||||
function patchToken(req) {
|
||||
|
@ -1 +1 @@
|
||||
module.exports = { buildDate:"2022-02-02T21:38:21+01:00", buildRevision: "0917fc8be171253449219cf29c0e603ac29eb26e" };
|
||||
module.exports = { buildDate:"2022-02-09T22:52:36+01:00", buildRevision: "23daaa2387a0655685377f0a541d154aeec2aae8" };
|
||||
|
@ -93,8 +93,7 @@ function deleteToken(etapiTokenId) {
|
||||
return; // ok, already deleted
|
||||
}
|
||||
|
||||
etapiToken.isDeleted = true;
|
||||
etapiToken.save();
|
||||
etapiToken.markAsDeletedSimple();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -13,6 +13,7 @@ const fs = require("fs");
|
||||
const becca = require("../../becca/becca");
|
||||
const RESOURCE_DIR = require('../../services/resource_dir').RESOURCE_DIR;
|
||||
const archiver = require('archiver');
|
||||
const log = require("../log");
|
||||
|
||||
/**
|
||||
* @param {TaskContext} taskContext
|
||||
@ -254,7 +255,9 @@ ${content}
|
||||
</html>`;
|
||||
}
|
||||
|
||||
return html.prettyPrint(content, {indent_size: 2});
|
||||
return content.length < 100000
|
||||
? html.prettyPrint(content, {indent_size: 2})
|
||||
: content;
|
||||
}
|
||||
else if (noteMeta.format === 'markdown') {
|
||||
let markdownContent = mdService.toMarkdown(content);
|
||||
@ -274,6 +277,8 @@ ${content}
|
||||
const notePaths = {};
|
||||
|
||||
function saveNote(noteMeta, filePathPrefix) {
|
||||
log.info(`Exporting note ${noteMeta.noteId}`);
|
||||
|
||||
if (noteMeta.isClone) {
|
||||
const targetUrl = getTargetUrl(noteMeta.noteId, noteMeta);
|
||||
|
||||
|
@ -634,7 +634,10 @@ function undeleteBranch(branchId, deleteId, taskContext) {
|
||||
taskContext.increaseProgressCount();
|
||||
|
||||
if (note.isDeleted && note.deleteId === deleteId) {
|
||||
new Note(note).save();
|
||||
// becca entity was already created as skeleton in "new Branch()" above
|
||||
const noteEntity = becca.getNote(note.noteId);
|
||||
noteEntity.updateFromRow(note);
|
||||
noteEntity.save();
|
||||
|
||||
const attributes = sql.getRows(`
|
||||
SELECT * FROM attributes
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div id="prompt-dialog" class="modal mx-auto" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<form id="prompt-dialog-form">
|
||||
<div class="modal-header">
|
||||
|
Loading…
x
Reference in New Issue
Block a user