mirror of
https://github.com/zadam/trilium.git
synced 2025-10-29 09:16:45 +01:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b679f4218d | ||
|
|
77c6c4617b | ||
|
|
8240a208dd | ||
|
|
1c34f73f61 | ||
|
|
c102089731 | ||
|
|
7495777d97 | ||
|
|
fa2ffd7574 | ||
|
|
412c745e53 | ||
|
|
913d2c06f3 | ||
|
|
d04d356429 | ||
|
|
be59f248e8 | ||
|
|
1995b54770 | ||
|
|
f2732bcab7 | ||
|
|
0e9d76890b | ||
|
|
9df521109b | ||
|
|
75b65c396e | ||
|
|
d4d48f3834 | ||
|
|
b90ba3d1a9 |
@@ -44,7 +44,7 @@ find $DIR/node_modules -name demo -exec rm -rf {} \;
|
||||
|
||||
find $DIR/libraries -name "*.map" -type f -delete
|
||||
|
||||
rm -r $DIR/src/public/app
|
||||
rm -rf $DIR/src/public/app
|
||||
|
||||
sed -i -e 's/app\/desktop.js/app-dist\/desktop.js/g' $DIR/src/views/desktop.ejs
|
||||
sed -i -e 's/app\/mobile.js/app-dist\/mobile.js/g' $DIR/src/views/mobile.ejs
|
||||
|
||||
@@ -10,10 +10,20 @@ CREATE TABLE IF NOT EXISTS "mig_entity_changes" (
|
||||
`utcDateChanged` TEXT NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO mig_entity_changes (entityName, entityId, hash, isErased, changeId, sourceId, isSynced, utcDateChanged)
|
||||
SELECT entityName, entityId, hash, isErased, '', sourceId, isSynced, utcDateChanged FROM entity_changes;
|
||||
INSERT INTO mig_entity_changes (id, entityName, entityId, hash, isErased, changeId, sourceId, isSynced, utcDateChanged)
|
||||
SELECT id, entityName, entityId, hash, isErased, '', sourceId, isSynced, utcDateChanged FROM entity_changes;
|
||||
|
||||
DROP TABLE entity_changes;
|
||||
-- delete duplicates https://github.com/zadam/trilium/issues/2534
|
||||
DELETE FROM mig_entity_changes WHERE isErased = 0 AND id IN (
|
||||
SELECT id FROM mig_entity_changes ec
|
||||
WHERE (
|
||||
SELECT COUNT(*) FROM mig_entity_changes
|
||||
WHERE ec.entityName = mig_entity_changes.entityName
|
||||
AND ec.entityId = mig_entity_changes.entityId
|
||||
) > 1
|
||||
);
|
||||
|
||||
DROP TABLE entity_changes;
|
||||
|
||||
ALTER TABLE mig_entity_changes RENAME TO entity_changes;
|
||||
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "trilium",
|
||||
"version": "0.49.2-beta",
|
||||
"version": "0.49.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "trilium",
|
||||
"version": "0.49.2-beta",
|
||||
"version": "0.49.4",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@electron/remote": "2.0.1",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "trilium",
|
||||
"productName": "Trilium Notes",
|
||||
"description": "Trilium Notes",
|
||||
"version": "0.49.3",
|
||||
"version": "0.49.5",
|
||||
"license": "AGPL-3.0-only",
|
||||
"main": "electron.js",
|
||||
"bin": {
|
||||
|
||||
@@ -71,14 +71,7 @@ function getNoteTitle(childNoteId, parentNoteId) {
|
||||
return "[error fetching title]";
|
||||
}
|
||||
|
||||
let title;
|
||||
|
||||
if (childNote.isProtected) {
|
||||
title = protectedSessionService.isProtectedSessionAvailable() ? childNote.title : '[protected]';
|
||||
}
|
||||
else {
|
||||
title = childNote.title;
|
||||
}
|
||||
const title = childNote.getTitleOrProtected();
|
||||
|
||||
const branch = parentNote ? becca.getBranchFromChildAndParent(childNote.noteId, parentNote.noteId) : null;
|
||||
|
||||
|
||||
@@ -131,6 +131,10 @@ class Note extends AbstractEntity {
|
||||
|| protectedSessionService.isProtectedSessionAvailable()
|
||||
}
|
||||
|
||||
getTitleOrProtected() {
|
||||
return this.isContentAvailable() ? this.title : '[protected]';
|
||||
}
|
||||
|
||||
/** @returns {Branch[]} */
|
||||
getParentBranches() {
|
||||
return this.parentBranches;
|
||||
@@ -861,11 +865,13 @@ class Note extends AbstractEntity {
|
||||
this.ancestorCache = [];
|
||||
|
||||
for (const parent of this.parents) {
|
||||
if (!noteIds.has(parent.noteId)) {
|
||||
this.ancestorCache.push(parent);
|
||||
noteIds.add(parent.noteId);
|
||||
if (noteIds.has(parent.noteId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.ancestorCache.push(parent);
|
||||
noteIds.add(parent.noteId);
|
||||
|
||||
for (const ancestorNote of parent.getAncestors()) {
|
||||
if (!noteIds.has(ancestorNote.noteId)) {
|
||||
this.ancestorCache.push(ancestorNote);
|
||||
|
||||
@@ -790,7 +790,7 @@ class NoteShort {
|
||||
|
||||
const parentNote = froca.notes[parentNoteId];
|
||||
|
||||
if (!parentNote) {
|
||||
if (!parentNote || parentNote.type === 'search') {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import server from './server.js';
|
||||
import toastService from "./toast.js";
|
||||
|
||||
async function syncNow() {
|
||||
async function syncNow(ignoreNotConfigured = false) {
|
||||
const result = await server.post('sync/now');
|
||||
|
||||
if (result.success) {
|
||||
@@ -12,7 +12,9 @@ async function syncNow() {
|
||||
result.message = result.message.substr(0, 200) + "...";
|
||||
}
|
||||
|
||||
toastService.showError("Sync failed: " + result.message);
|
||||
if (!ignoreNotConfigured || result.errorCode !== 'NOT_CONFIGURED') {
|
||||
toastService.showError("Sync failed: " + result.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import ReadOnlyCodeTypeWidget from "./type_widgets/read_only_code.js";
|
||||
import NoneTypeWidget from "./type_widgets/none.js";
|
||||
import attributeService from "../services/attributes.js";
|
||||
import NoteMapTypeWidget from "./type_widgets/note_map.js";
|
||||
import attributeRenderer from "../services/attribute_renderer.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-detail">
|
||||
@@ -209,8 +210,17 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
||||
|
||||
await libraryLoader.requireLibrary(libraryLoader.PRINT_THIS);
|
||||
|
||||
let $promotedAttributes = $("");
|
||||
|
||||
if (this.note.getPromotedDefinitionAttributes().length > 0) {
|
||||
$promotedAttributes = (await attributeRenderer.renderNormalAttributes(this.note)).$renderedAttributes;
|
||||
}
|
||||
|
||||
this.$widget.find('.note-detail-printable:visible').printThis({
|
||||
header: $("<h2>").text(this.note && this.note.title).prop('outerHTML'),
|
||||
header: $("<div>")
|
||||
.append($("<h2>").text(this.note.title))
|
||||
.append($promotedAttributes)
|
||||
.prop('outerHTML'),
|
||||
footer: `
|
||||
<script src="libraries/katex/katex.min.js"></script>
|
||||
<script src="libraries/katex/mhchem.min.js"></script>
|
||||
|
||||
@@ -13,7 +13,7 @@ const TPL = `
|
||||
}
|
||||
</style>
|
||||
|
||||
<span class="share-text"></span> <a class="share-link external"></a>. For help visit <a href="https://github.com/zadam/trilium/wiki/Sharing">wiki</a>.
|
||||
<span class="shared-text"></span> <a class="shared-link external"></a>. For help visit <a href="https://github.com/zadam/trilium/wiki/Sharing">wiki</a>.
|
||||
</div>`;
|
||||
|
||||
export default class SharedInfoWidget extends NoteContextAwareWidget {
|
||||
@@ -23,8 +23,8 @@ export default class SharedInfoWidget extends NoteContextAwareWidget {
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$shareLink = this.$widget.find(".share-link");
|
||||
this.$shareText = this.$widget.find(".share-text");
|
||||
this.$sharedLink = this.$widget.find(".shared-link");
|
||||
this.$sharedText = this.$widget.find(".shared-text");
|
||||
this.contentSized();
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ export default class SharedInfoWidget extends NoteContextAwareWidget {
|
||||
|
||||
if (syncServerHost) {
|
||||
link = syncServerHost + "/share/" + shareId;
|
||||
this.$shareText.text("This note is shared publicly on");
|
||||
this.$sharedText.text("This note is shared publicly on");
|
||||
}
|
||||
else {
|
||||
link = location.protocol + '//' + location.host + location.pathname + "share/" + shareId;
|
||||
this.$shareText.text("This note is shared locally on");
|
||||
this.$sharedText.text("This note is shared locally on");
|
||||
}
|
||||
|
||||
this.$shareLink.attr("href", link).text(link);
|
||||
this.$sharedLink.attr("href", link).text(link);
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import SwitchWidget from "./switch.js";
|
||||
import branchService from "../services/branches.js";
|
||||
import server from "../services/server.js";
|
||||
import utils from "../services/utils.js";
|
||||
import syncService from "../services/sync.js";
|
||||
|
||||
export default class SharedSwitchWidget extends SwitchWidget {
|
||||
isEnabled() {
|
||||
@@ -21,8 +22,10 @@ export default class SharedSwitchWidget extends SwitchWidget {
|
||||
this.$helpButton.on('click', e => utils.openHelp(e));
|
||||
}
|
||||
|
||||
switchOn() {
|
||||
branchService.cloneNoteToNote(this.noteId, 'share');
|
||||
async switchOn() {
|
||||
await branchService.cloneNoteToNote(this.noteId, 'share');
|
||||
|
||||
syncService.syncNow(true);
|
||||
}
|
||||
|
||||
async switchOff() {
|
||||
@@ -43,6 +46,8 @@ export default class SharedSwitchWidget extends SwitchWidget {
|
||||
}
|
||||
|
||||
await server.remove(`branches/${shareBranch.branchId}?taskId=no-progress-reporting`);
|
||||
|
||||
syncService.syncNow(true);
|
||||
}
|
||||
|
||||
async refreshWithNote(note) {
|
||||
|
||||
@@ -98,7 +98,7 @@ function getLinkMap(req) {
|
||||
|
||||
return [
|
||||
note.noteId,
|
||||
note.isContentAvailable() ? note.title : '[protected]',
|
||||
note.getTitleOrProtected(),
|
||||
note.type
|
||||
];
|
||||
});
|
||||
@@ -158,7 +158,7 @@ function getTreeMap(req) {
|
||||
.concat(...mapRootNote.getParentNotes())
|
||||
.map(note => [
|
||||
note.noteId,
|
||||
note.isContentAvailable() ? note.title : '[protected]',
|
||||
note.getTitleOrProtected(),
|
||||
note.type
|
||||
]);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ function getNotesAndBranchesAndAttributes(noteIds) {
|
||||
|
||||
notes.push({
|
||||
noteId: note.noteId,
|
||||
title: note.isDecrypted ? note.title : '[protected]',
|
||||
title: note.getTitleOrProtected(),
|
||||
isProtected: note.isProtected,
|
||||
type: note.type,
|
||||
mime: note.mime
|
||||
|
||||
@@ -1 +1 @@
|
||||
module.exports = { buildDate:"2022-01-06T23:09:17+01:00", buildRevision: "590eea11830531699643b381d06a6a59dd7704bb" };
|
||||
module.exports = { buildDate:"2022-01-14T21:40:37+01:00", buildRevision: "77c6c4617b634226e12ead172482fe1fe92bc360" };
|
||||
|
||||
@@ -97,7 +97,8 @@ function exportToZip(taskContext, branch, format, res) {
|
||||
return;
|
||||
}
|
||||
|
||||
const completeTitle = branch.prefix ? (branch.prefix + ' - ' + note.title) : note.title;
|
||||
const title = note.getTitleOrProtected();
|
||||
const completeTitle = branch.prefix ? (branch.prefix + ' - ' + title) : title;
|
||||
let baseFileName = sanitize(completeTitle);
|
||||
|
||||
if (baseFileName.length > 200) { // actual limit is 256 bytes(!) but let's be conservative
|
||||
@@ -113,7 +114,7 @@ function exportToZip(taskContext, branch, format, res) {
|
||||
isClone: true,
|
||||
noteId: note.noteId,
|
||||
notePath: notePath,
|
||||
title: note.title,
|
||||
title: note.getTitleOrProtected(),
|
||||
prefix: branch.prefix,
|
||||
dataFileName: fileName,
|
||||
type: 'text', // export will have text description,
|
||||
@@ -125,7 +126,7 @@ function exportToZip(taskContext, branch, format, res) {
|
||||
isClone: false,
|
||||
noteId: note.noteId,
|
||||
notePath: notePath,
|
||||
title: note.title,
|
||||
title: note.getTitleOrProtected(),
|
||||
notePosition: branch.notePosition,
|
||||
prefix: branch.prefix,
|
||||
isExpanded: branch.isExpanded,
|
||||
@@ -445,7 +446,7 @@ ${content}
|
||||
}
|
||||
|
||||
const note = branch.getNote();
|
||||
const zipFileName = (branch.prefix ? `${branch.prefix} - ` : "") + note.title + ".zip";
|
||||
const zipFileName = (branch.prefix ? `${branch.prefix} - ` : "") + note.getTitleOrProtected() + ".zip";
|
||||
|
||||
res.setHeader('Content-Disposition', utils.getContentDisposition(zipFileName));
|
||||
res.setHeader('Content-Type', 'application/zip');
|
||||
|
||||
@@ -102,8 +102,9 @@ function createNewNote(params) {
|
||||
throw new Error(`Parent note "${params.parentNoteId}" not found.`);
|
||||
}
|
||||
|
||||
if (!params.title || params.title.trim().length === 0) {
|
||||
throw new Error(`Note title must not be empty`);
|
||||
if (params.title === null || params.title === undefined) {
|
||||
// empty title is allowed since it's possible to create such in the UI
|
||||
throw new Error(`Note title must be set`);
|
||||
}
|
||||
|
||||
return sql.transactional(() => {
|
||||
|
||||
@@ -26,7 +26,7 @@ async function sync() {
|
||||
try {
|
||||
return await syncMutexService.doExclusively(async () => {
|
||||
if (!syncOptions.isSyncSetup()) {
|
||||
return { success: false, message: 'Sync not configured' };
|
||||
return { success: false, errorCode: 'NOT_CONFIGURED', message: 'Sync not configured' };
|
||||
}
|
||||
|
||||
let continueSync = false;
|
||||
@@ -149,8 +149,8 @@ async function pullChanges(syncContext) {
|
||||
|
||||
sql.transactional(() => {
|
||||
for (const {entityChange, entity} of entityChanges) {
|
||||
const changeAppliedAlready = !entityChange.changeId
|
||||
|| !!sql.getValue("SELECT id FROM entity_changes WHERE changeId = ?", [entityChange.changeId]);
|
||||
const changeAppliedAlready = entityChange.changeId
|
||||
&& !!sql.getValue("SELECT id FROM entity_changes WHERE changeId = ?", [entityChange.changeId]);
|
||||
|
||||
if (!changeAppliedAlready && !sourceIdService.isLocalSourceId(entityChange.sourceId)) {
|
||||
if (!atLeastOnePullApplied) { // send only for first
|
||||
|
||||
@@ -41,8 +41,6 @@ function validateParentChild(parentNoteId, childNoteId, branchId = null) {
|
||||
|
||||
const existing = getExistingBranch(parentNoteId, childNoteId);
|
||||
|
||||
console.log("BBBB", existing);
|
||||
|
||||
if (existing && (branchId === null || existing.branchId !== branchId)) {
|
||||
const parentNote = becca.getNote(parentNoteId);
|
||||
const childNote = becca.getNote(childNoteId);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<div id="main">
|
||||
<% if (note.parents[0].noteId !== 'share' && note.parents.length !== 0) { %>
|
||||
<nav id="parentLink">
|
||||
parent: <a href="<%= note.parents[0].noteId %>"
|
||||
parent: <a href="<%= note.parents[0].shareId %>"
|
||||
class="type-<%= note.parents[0].type %>"><%= note.parents[0].title %></a>
|
||||
</nav>
|
||||
<% } %>
|
||||
@@ -40,10 +40,7 @@
|
||||
<div id="noteClippedFrom">This note was originally clipped from <a href="<%= note.getLabelValue("pageUrl") %>"><%= note.getLabelValue("pageUrl") %></a></div>
|
||||
<% } %>
|
||||
|
||||
<% if (note.type === 'book') { %>
|
||||
<% } else if (isEmpty) { %>
|
||||
<p>This note has no content.</p>
|
||||
<% } else { %>
|
||||
<% if (!isEmpty) { %>
|
||||
<div id="content" class="type-<%= note.type %><% if (note.type === 'text') { %> ck-content<% } %>">
|
||||
<%- content %>
|
||||
</div>
|
||||
@@ -52,20 +49,21 @@
|
||||
<% if (note.hasChildren()) { %>
|
||||
<nav id="childLinks" class="<% if (isEmpty) { %>grid<% } else { %>list<% } %>">
|
||||
<% if (!isEmpty) { %>
|
||||
<div id="noteClippedFrom">
|
||||
<hr>
|
||||
<span>Child notes: </span>
|
||||
<ul>
|
||||
<% for (const childNote of note.getChildNotes()) { %>
|
||||
<li>
|
||||
<a href="<%= childNote.shareId %>"
|
||||
class="type-<%= childNote.type %>"><%= childNote.title %></a>
|
||||
</li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<ul>
|
||||
<% for (const childNote of note.getChildNotes()) { %>
|
||||
<li>
|
||||
<a href="<%= childNote.shareId %>"
|
||||
class="type-<%= childNote.type %>"><%= childNote.title %></a>
|
||||
</li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</nav>
|
||||
<% } else if (isEmpty) { %>
|
||||
<p>This note has no content.</p>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user