mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 19:05:59 +01:00
Compare commits
15 Commits
v0.40.0-be
...
v0.40.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7651c53363 | ||
|
|
0f25c8a95f | ||
|
|
1a49894adf | ||
|
|
bd8c078fb9 | ||
|
|
6e060b87b8 | ||
|
|
2375b170ba | ||
|
|
828cce0d78 | ||
|
|
ab535bf147 | ||
|
|
1876664dfb | ||
|
|
1690248e24 | ||
|
|
cbeb8ea17e | ||
|
|
c9113ae752 | ||
|
|
0ec11d29ba | ||
|
|
a6cd25071e | ||
|
|
20fdeee048 |
3
.idea/.gitignore
generated
vendored
3
.idea/.gitignore
generated
vendored
@@ -2,4 +2,5 @@
|
|||||||
/workspace.xml
|
/workspace.xml
|
||||||
|
|
||||||
# Datasource local storage ignored files
|
# Datasource local storage ignored files
|
||||||
/dataSources.local.xml
|
/dataSources.local.xml
|
||||||
|
/dataSources/
|
||||||
|
|||||||
1
db/migrations/0157__fix_contentLength.sql
Normal file
1
db/migrations/0157__fix_contentLength.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
UPDATE notes SET contentLength = COALESCE((SELECT COALESCE(LENGTH(content), 0) FROM note_contents WHERE note_contents.noteId = notes.noteId), -1);
|
||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"version": "0.39.5",
|
"version": "0.40.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"productName": "Trilium Notes",
|
"productName": "Trilium Notes",
|
||||||
"description": "Trilium Notes",
|
"description": "Trilium Notes",
|
||||||
"version": "0.40.0-beta",
|
"version": "0.40.2",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"main": "electron.js",
|
"main": "electron.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -110,6 +110,10 @@ class Note extends Entity {
|
|||||||
async getJsonContent() {
|
async getJsonContent() {
|
||||||
const content = await this.getContent();
|
const content = await this.getContent();
|
||||||
|
|
||||||
|
if (!content || !content.trim()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return JSON.parse(content);
|
return JSON.parse(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,9 +123,11 @@ class Note extends Entity {
|
|||||||
throw new Error(`Cannot set null content to note ${this.noteId}`);
|
throw new Error(`Cannot set null content to note ${this.noteId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
content = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
||||||
|
|
||||||
// force updating note itself so that dateModified is represented correctly even for the content
|
// force updating note itself so that dateModified is represented correctly even for the content
|
||||||
this.forcedChange = true;
|
this.forcedChange = true;
|
||||||
this.contentLength = content.length;
|
this.contentLength = content.byteLength;
|
||||||
await this.save();
|
await this.save();
|
||||||
|
|
||||||
this.content = content;
|
this.content = content;
|
||||||
@@ -130,7 +136,7 @@ class Note extends Entity {
|
|||||||
noteId: this.noteId,
|
noteId: this.noteId,
|
||||||
content: content,
|
content: content,
|
||||||
utcDateModified: dateUtils.utcNowDateTime(),
|
utcDateModified: dateUtils.utcNowDateTime(),
|
||||||
hash: utils.hash(this.noteId + "|" + content)
|
hash: utils.hash(this.noteId + "|" + content.toString())
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.isProtected) {
|
if (this.isProtected) {
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ async function showTree() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
treeService.setTree($.ui.fancytree.getTree("#tree"));
|
||||||
}
|
}
|
||||||
|
|
||||||
$detail.on("click", ".note-menu-button", async e => {
|
$detail.on("click", ".note-menu-button", async e => {
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ function registerEntrypoints() {
|
|||||||
|
|
||||||
d.showDialog(selectedOrActiveNodes);
|
d.showDialog(selectedOrActiveNodes);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
keyboardActionService.setGlobalActionHandler("CreateNoteIntoDayNote", async () => {
|
keyboardActionService.setGlobalActionHandler("CreateNoteIntoDayNote", async () => {
|
||||||
const todayNote = await dateNoteService.getTodayNote();
|
const todayNote = await dateNoteService.getTodayNote();
|
||||||
|
|
||||||
@@ -288,6 +288,8 @@ function registerEntrypoints() {
|
|||||||
|
|
||||||
searchNotesService.searchInSubtree(node.data.noteId);
|
searchNotesService.searchInSubtree(node.data.noteId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
keyboardActionService.setGlobalActionHandler("CopyWithoutFormatting", utils.copySelectionToClipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import splitService from "./split.js";
|
|||||||
import optionService from "./options.js";
|
import optionService from "./options.js";
|
||||||
import server from "./server.js";
|
import server from "./server.js";
|
||||||
import noteDetailService from "./note_detail.js";
|
import noteDetailService from "./note_detail.js";
|
||||||
|
import utils from "./utils.js";
|
||||||
|
|
||||||
const $sidebar = $("#right-pane");
|
const $sidebar = $("#right-pane");
|
||||||
const $sidebarContainer = $('#sidebar-container');
|
const $sidebarContainer = $('#sidebar-container');
|
||||||
@@ -15,6 +16,10 @@ const $hideSidebarButton = $("#hide-sidebar-button");
|
|||||||
optionService.waitForOptions().then(options => toggleSidebar(options.is('rightPaneVisible')));
|
optionService.waitForOptions().then(options => toggleSidebar(options.is('rightPaneVisible')));
|
||||||
|
|
||||||
function toggleSidebar(show) {
|
function toggleSidebar(show) {
|
||||||
|
if (utils.isMobile()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$sidebar.toggle(show);
|
$sidebar.toggle(show);
|
||||||
$showSidebarButton.toggle(!show);
|
$showSidebarButton.toggle(!show);
|
||||||
$hideSidebarButton.toggle(show);
|
$hideSidebarButton.toggle(show);
|
||||||
|
|||||||
@@ -303,7 +303,11 @@ class TabContext {
|
|||||||
|
|
||||||
let type = this.note.type;
|
let type = this.note.type;
|
||||||
|
|
||||||
if (type === 'text' && !disableAutoBook && utils.isHtmlEmpty(this.note.content) && this.note.hasChildren()) {
|
if (type === 'text'
|
||||||
|
&& !disableAutoBook
|
||||||
|
&& utils.isHtmlEmpty(this.note.content)
|
||||||
|
&& this.note.hasChildren()
|
||||||
|
&& utils.isDesktop()) {
|
||||||
type = 'book';
|
type = 'book';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -913,6 +913,10 @@ function getNodeByKey(key) {
|
|||||||
return tree.getNodeByKey(key);
|
return tree.getNodeByKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setTree(treeInstance) {
|
||||||
|
tree = treeInstance;
|
||||||
|
}
|
||||||
|
|
||||||
keyboardActionService.setGlobalActionHandler('CollapseTree', () => collapseTree()); // don't use shortened form since collapseTree() accepts argument
|
keyboardActionService.setGlobalActionHandler('CollapseTree', () => collapseTree()); // don't use shortened form since collapseTree() accepts argument
|
||||||
$collapseTreeButton.on('click', () => collapseTree());
|
$collapseTreeButton.on('click', () => collapseTree());
|
||||||
|
|
||||||
@@ -949,5 +953,6 @@ export default {
|
|||||||
focusTree,
|
focusTree,
|
||||||
scrollToActiveNote,
|
scrollToActiveNote,
|
||||||
duplicateNote,
|
duplicateNote,
|
||||||
getNodeByKey
|
getNodeByKey,
|
||||||
|
setTree
|
||||||
};
|
};
|
||||||
@@ -241,6 +241,13 @@ function getUrlForDownload(url) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function copySelectionToClipboard() {
|
||||||
|
const text = window.getSelection().toString();
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
navigator.clipboard.writeText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
reloadApp,
|
reloadApp,
|
||||||
parseDate,
|
parseDate,
|
||||||
@@ -273,5 +280,6 @@ export default {
|
|||||||
isHtmlEmpty,
|
isHtmlEmpty,
|
||||||
clearBrowserCache,
|
clearBrowserCache,
|
||||||
getUrlForDownload,
|
getUrlForDownload,
|
||||||
normalizeShortcut
|
normalizeShortcut,
|
||||||
|
copySelectionToClipboard
|
||||||
};
|
};
|
||||||
@@ -41,7 +41,7 @@ class CalendarWidget extends StandardWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init($el, activeDate) {
|
init($el, activeDate) {
|
||||||
this.activeDate = new Date(Date.parse(activeDate));
|
this.activeDate = new Date(activeDate + "T12:00:00"); // attaching time fixes local timezone handling
|
||||||
this.todaysDate = new Date();
|
this.todaysDate = new Date();
|
||||||
this.date = new Date(this.activeDate.getTime());
|
this.date = new Date(this.activeDate.getTime());
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,12 @@ async function searchFromNote(req) {
|
|||||||
return [404, `Note ${req.params.noteId} has not been found.`];
|
return [404, `Note ${req.params.noteId} has not been found.`];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (note.isDeleted) {
|
||||||
|
return [400, `Note ${req.params.noteId} is deleted.`];
|
||||||
|
}
|
||||||
|
|
||||||
if (note.type !== 'search') {
|
if (note.type !== 'search') {
|
||||||
return [400, '`Note ${req.params.noteId} is not search note.`']
|
return [400, `Note ${req.params.noteId} is not search note.`]
|
||||||
}
|
}
|
||||||
|
|
||||||
const json = await note.getJsonContent();
|
const json = await note.getJsonContent();
|
||||||
@@ -41,18 +45,28 @@ async function searchFromNote(req) {
|
|||||||
|
|
||||||
let noteIds;
|
let noteIds;
|
||||||
|
|
||||||
if (json.searchString.startsWith('=')) {
|
try {
|
||||||
const relationName = json.searchString.substr(1).trim();
|
if (json.searchString.startsWith('=')) {
|
||||||
|
const relationName = json.searchString.substr(1).trim();
|
||||||
|
|
||||||
noteIds = await searchFromRelation(note, relationName);
|
noteIds = await searchFromRelation(note, relationName);
|
||||||
|
} else {
|
||||||
|
noteIds = await searchService.searchForNoteIds(json.searchString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
catch (e) {
|
||||||
noteIds = await searchService.searchForNoteIds(json.searchString);
|
log.error(`Search failed for note ${note.noteId}: ` + e.message + ": " + e.stack);
|
||||||
|
|
||||||
|
throw new Error("Search failed, see logs for details.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// we won't return search note's own noteId
|
// we won't return search note's own noteId
|
||||||
noteIds = noteIds.filter(noteId => noteId !== note.noteId);
|
noteIds = noteIds.filter(noteId => noteId !== note.noteId);
|
||||||
|
|
||||||
|
if (noteIds.length > 200) {
|
||||||
|
noteIds = noteIds.slice(0, 200);
|
||||||
|
}
|
||||||
|
|
||||||
return noteIds.map(noteCacheService.getNotePath).filter(res => !!res);
|
return noteIds.map(noteCacheService.getNotePath).filter(res => !!res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const build = require('./build');
|
|||||||
const packageJson = require('../../package');
|
const packageJson = require('../../package');
|
||||||
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
||||||
|
|
||||||
const APP_DB_VERSION = 156;
|
const APP_DB_VERSION = 157;
|
||||||
const SYNC_VERSION = 14;
|
const SYNC_VERSION = 14;
|
||||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
module.exports = { buildDate:"2020-01-11T09:54:31+01:00", buildRevision: "5e91b1b5e0fa04affbc1a5a43a874cadc382fe11" };
|
module.exports = { buildDate:"2020-02-01T10:17:51+01:00", buildRevision: "0f25c8a95f381d99b66735b9c0af3e319edb72ed" };
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const noteService = require('./notes');
|
|||||||
const repository = require('./repository');
|
const repository = require('./repository');
|
||||||
const Branch = require('../entities/branch');
|
const Branch = require('../entities/branch');
|
||||||
const TaskContext = require("./task_context.js");
|
const TaskContext = require("./task_context.js");
|
||||||
|
const utils = require('./utils');
|
||||||
|
|
||||||
async function cloneNoteToParent(noteId, parentNoteId, prefix) {
|
async function cloneNoteToParent(noteId, parentNoteId, prefix) {
|
||||||
if (await isNoteDeleted(noteId) || await isNoteDeleted(parentNoteId)) {
|
if (await isNoteDeleted(noteId) || await isNoteDeleted(parentNoteId)) {
|
||||||
@@ -54,7 +55,8 @@ async function ensureNoteIsAbsentFromParent(noteId, parentNoteId) {
|
|||||||
const branch = await repository.getEntity(`SELECT * FROM branches WHERE noteId = ? AND parentNoteId = ? AND isDeleted = 0`, [noteId, parentNoteId]);
|
const branch = await repository.getEntity(`SELECT * FROM branches WHERE noteId = ? AND parentNoteId = ? AND isDeleted = 0`, [noteId, parentNoteId]);
|
||||||
|
|
||||||
if (branch) {
|
if (branch) {
|
||||||
await noteService.deleteBranch(branch, new TaskContext());
|
const deleteId = utils.randomString(10);
|
||||||
|
await noteService.deleteBranch(branch, deleteId, new TaskContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ async function getRootCalendarNote() {
|
|||||||
parentNoteId: 'root',
|
parentNoteId: 'root',
|
||||||
title: 'Calendar',
|
title: 'Calendar',
|
||||||
target: 'into',
|
target: 'into',
|
||||||
isProtected: false
|
isProtected: false,
|
||||||
|
type: 'text',
|
||||||
|
content: ''
|
||||||
})).note;
|
})).note;
|
||||||
|
|
||||||
await attributeService.createLabel(rootNote.noteId, CALENDAR_ROOT_LABEL);
|
await attributeService.createLabel(rootNote.noteId, CALENDAR_ROOT_LABEL);
|
||||||
|
|||||||
@@ -306,6 +306,10 @@ const DEFAULT_KEYBOARD_ACTIONS = [
|
|||||||
{
|
{
|
||||||
actionName: "ZoomIn",
|
actionName: "ZoomIn",
|
||||||
defaultShortcuts: ["CommandOrControl+="]
|
defaultShortcuts: ["CommandOrControl+="]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
actionName: "CopyWithoutFormatting",
|
||||||
|
defaultShortcuts: ["CommandOrControl+Alt+C"]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -71,22 +71,36 @@ function sendMessageToAllClients(message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fillInAdditionalProperties(sync) {
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function sendPing(client) {
|
async function sendPing(client) {
|
||||||
const syncData = require('./sync_table').getEntitySyncsNewerThan(lastAcceptedSyncIds[client.id]);
|
const syncData = require('./sync_table').getEntitySyncsNewerThan(lastAcceptedSyncIds[client.id]);
|
||||||
|
|
||||||
for (const sync of syncData) {
|
for (const sync of syncData) {
|
||||||
// fill in some extra data needed by the frontend
|
try {
|
||||||
if (sync.entityName === 'attributes') {
|
await fillInAdditionalProperties(sync);
|
||||||
sync.noteId = await sql.getValue(`SELECT noteId FROM attributes WHERE attributeId = ?`, [sync.entityId]);
|
|
||||||
}
|
}
|
||||||
else if (sync.entityName === 'note_revisions') {
|
catch (e) {
|
||||||
sync.noteId = await sql.getValue(`SELECT noteId FROM note_revisions WHERE noteRevisionId = ?`, [sync.entityId]);
|
log.error("Could not fill additional properties for sync " + JSON.stringify(sync)
|
||||||
}
|
+ " because of error: " + e.message + ": " + e.stack);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user